【问题标题】:Sharing global variables with multiple Interrupt Service Routines in C在 C 中与多个中断服务例程共享全局变量
【发布时间】:2016-03-29 14:08:39
【问题描述】:

我正在用 C 语言为 PIC32 uC 编写一个程序,它有一个全局变量(uint32_t 类型),可以从多个中断服务程序和主程序中读取/修改。
我知道那不安全,所以我想知道如何使它安全?有没有一个例子说明如何使它安全?

编辑1:

中断可以互相打断吗?是的
ISR 是否更新变量?是的 main 是否更新变量?是的 对变量的写入和读取是原子的,你怎么知道?不确定
是否存在 RTOS?没有

【问题讨论】:

  • 最安全的方法是:不要那样做!顺便说一句,我希望您将该 var 定义为 volatile
  • 嗯,听起来您使用的是独立环境,因此 C 的要求并不高,但如果您想编写可移植代码,您可以查看 C11 草案标准 n1570:5.1.2.3 程序执行 5 当抽象机的处理因接收到信号而中断时,既不是无锁原子对象也不是 volatile sig_atomic_t 类型的对象的值是未指定的[...]。当处理程序退出时,处理程序修改的任何对象(既不是无锁原子对象也不是 volatile sig_atomic_t 类型)的值变得不确定[...]
  • 如果您设置为在服务中断时禁用中断,那么您需要做的就是在您读取或修改 main 中的全局的任何位置禁用中断。
  • 您必须声明变量 volatile 否则编译器可以将它们优化到寄存器或优化内存访问。或者以其他方式确保编译的代码不会优化访问。 Globals 或任何其他解决方案你仍然会有这个要求。
  • 但是 PIC32 应该在单个指令中读取/修改小于 32 位的变量,所以它应该是安全的,对吗?

标签: c embedded global-variables pic32


【解决方案1】:

如果你确实需要保留在服务多个可以互相中断的中断期间修改的全局变量,我建议你按照以下方式去做:

  1. 通过在之前禁用所有中断,然后重新启用所有中断,使对这些变量的所有操作序列(读取和/或写入)“原子”。在 PIC32 上,您可以通过写入全局中断标志 GIE 来做到这一点。
  2. 将这些变量声明为 volatile 以避免编译器的任何意外优化。
  3. 使用特定前缀重命名这些变量以清楚地识别它们,如 Shared_XXXX,但这取决于您使用的命名约定。
  4. 将这些变量的所有动作序列放在以特定前缀命名的函数中,以便清楚地识别它们,如 Atomic_XXXX()。要实现第 1 点:要么这些函数都必须从禁用所有中断开始并通过重新启用所有中断结束,或者您可以系统地将原子函数作为回调参数传递给将禁用所有中断的函数,调用回调函数并重新启用所有中断打断。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    相关资源
    最近更新 更多