【问题标题】:Is it legal to use `volatile uint8_t` instead of `volatile sig_atomic_t`?使用 `volatile uint8_t` 而不是 `volatile sig_atomic_t` 是否合法?
【发布时间】:2023-02-07 18:27:25
【问题描述】:

以下代码使用 volatile uint8_t 而不是 volatile sig_atomic_t 作为 C 标准要求,因为在 avr 平台上类型 sig_atomic_t 不可用。

这还是合法的代码吗? 使用__SIG_ATOMIC_TYPE__ 合法吗?

是否需要包含cli() / sei() 宏?

#include <stdint.h>
#include <signal.h>
#include <avr/interrupt.h>

volatile uint8_t flag;  
//volatile sig_atomic_t flag; // not available in avr-gcc
//volatile __SIG_ATOMIC_TYPE__ flag; // ok?

void isr() __asm__("__vector_5") __attribute__ ((__signal__, __used__, __externally_visible__)); 
void isr() {
    flag = 1;
}

void func(void) {
  for (uint8_t i=0; i<20; i++) {
      flag = !flag;
  }
}

【问题讨论】:

    标签: c language-lawyer interrupt-handling signal-handling


    【解决方案1】:

    是的,代码仍然是合法的,但是使用 volatile uint8_t 而不是 volatile sig_atomic_t 不符合 C 标准,因为 sig_atomic_t 被指定为用于中断服务例程和主程序之间通信的类型。

    使用易失性SIG_ATOMIC_TYPE很好,因为它是由编译器定义的预处理器宏,指的是用于中断服务例程和主程序之间通信的类型。

    如果您想控制状态寄存器 (SREG) 中全局中断启用 (I) 标志的状态,则必须包含 cli() / sei() 宏,这决定了微控制器是否在有或没有中断的情况下执行。 cli() 禁用中断,而 sei() 启用它们。这对于确保代码的关键部分以原子方式执行而不被中断可能很重要。

    【讨论】:

      猜你喜欢
      • 2012-01-19
      • 1970-01-01
      • 2019-03-09
      • 1970-01-01
      • 2014-12-07
      • 2016-06-18
      • 1970-01-01
      • 2020-10-11
      • 1970-01-01
      相关资源
      最近更新 更多