- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
假设我有function 1
和一个isr routine
,两者共享和更新相同的标志,它们之间没有任何锁定。 系统是单线程的。
while 将是一个 3 臂汇编指令,这意味着它不是原子操作,是否可以在非 isr 和 isr 函数之间共享一个全局变量而没有任何锁定或保护?
功能一:
while (flag == false);
flag = false;
isr 例程:
do something
flag=true
我不记得有一个 linux 内核机制可以在可 sleep 和不可 sleep 上下文之间进行锁定,例如irq
和内核线程
。
感谢@artless 的回答,这里有一些我不确定的问题:
有没有办法让我完全不会错过中断?
内存屏障是怎么解决的,单cpu运行有效果吗?
在不同上下文之间使用屏障时的预期行为是什么?
while loop
中的 sleep 能否解决同步问题?
最佳答案
使用 volatile
通常被引用为一种解决方案,但事实并非如此。它通常会掩盖一个问题,因为 volatile
总是会使代码变慢。如果您的唯一用途如图所示,那么 volatile
可能会起作用。
单个读取器和单个写入可能更好地使用memory barriers .这将是您的代码,
主线:
volatile int *p = &flag;
while (*p == false); /* You must use volatile if you poll */
flag = false;
asm volatile ("" : : : "memory"); /* gcc barrier */
是:
/* do something */
flag=true
asm volatile ("" : : : "memory"); /* gcc barrier */
此处,barrier 只是强制编译器在该点执行 ARM str
指令。优化器不会在之前或之后移动任何代码。您还可以使用 swp
或 ldrex
和 strex
,具体取决于您的 ARM CPU。同样,环形缓冲区通常与 ISR 和 mainlines 一起使用,因为它们不需要任何特殊的 CPU 支持;只有编译器内存障碍。
参见 lock-free并专门搜索 lock-free and arm .
编辑:对于添加,
Is there a way I won't miss interrupt at all ?
这取决于中断源。如果它是一个计时器并且您知道计时器源永远不会比XX 指令快并且系统中没有其他中断处于事件状态,那么您当前的代码将工作。但是,如果中断来自外部源,例如 以太网 Controller 、非去抖动键盘等。多个中断可能会很快到来。有时新的中断甚至发生在中断处理程序期间。根据 ISR 源,有不同的解决方案。 环形缓冲区 通常用于将来自 ISR 的工作项目排队到主线。对于 UART,环可能包含实际字符数据。它可以是指针列表等。当通信变得更加复杂时,很难从主线同步ISR;所以我相信答案取决于中断源。这就是为什么每个 OS 都有如此多的原语和基础结构来解决这个问题。
How the memory barriers solve the issue, does it have effect when the code runs on single cpu ?
内存屏障并不能完全解决错过的中断问题;就像 volatile
没有。它们只是使窗口小得多。它们强制编译器安排更早的加载或存储。比如主线循环,
1: ldr r0, [r1]
cmp r0, #0 ; xxx
bne 1b ; xxx
mov r0,#1 ; xxx
str r0, [r1]
如果第 2 次中断发生在 xxx 行期间,那么您的 flag
应该设置两次并且您错过了一次中断。 障碍 只是确保编译器将 ldr
和 str
放在一起。
What is the expected behavior when using barriers between different contexts?
我展示的编译器内存屏障只是让编译器做事更快。它在上下文之间没有影响。有不同的障碍;但它们主要用于多 CPU 设计。
Can a sleep in the while loop can solve problems of syncs?
不是真的,这只是一种更高效的使用方式。 ARM WFI
指令可以暂时停止 CPU,这样可以节省电量。这通常是 sleep() 在 ARM 上执行的操作。如果这是一个问题,我认为您需要更改 ISR 和 mainline 之间的通信。这取决于 ISR 来源。
关于c - 如何保护 isr 和常规函数共享的全局变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18088873/
我有一段用于 PIC 设备的 C 代码,它按照预定义的模式驱动 4 个独立的继电器,每个继电器通过计数次数和发生频率来单独设置。这种模式会无限延续,但发现标准delay_ms 上的计时不够准确。我希望
我对这种宏尝试有疑问: #define ISR(x) #pragma isr=x 无法编译,因为它试图用不存在的参数替换 #pragma。有什么办法可以实现我想要做的事情吗?我想将 ISR(VEC1)
我现在使用的是嵌入式产品,即 PIC32 Microchip CPU。 我熟悉几个实时内核:AVIX , FreeRTOS , TNKernel ,并且在所有这些函数中,几乎所有函数都有 2 个版本:
我正在调试 arm-family cpu (Cortex M3) 上的固件。 调试器显示 CPU 寄存器,包括一个称为“xPSR”的寄存器,其中包含一个称为“ISR”的子字段。 CPU寄存器中的模式是
我有以下设置经纪人:3 - 全部启动并运行 min.insync.replicas=3。 我创建了一个topic,配置如下 bin\windows\kafka-topics --zookeeper 1
我有以下设置经纪人:3 - 全部启动并运行 min.insync.replicas=3。 我创建了一个topic,配置如下 bin\windows\kafka-topics --zookeeper 1
我有一个带有3个kafka节点和3个zk节点的kakfa集群。 生产者在AWS机器上尝试将数据推送到我的Intranet服务器上运行的kafka集群上。 使用以下命令从控制台创建主题(JOB_AWS_
在mspgcc中声明中断处理程序的首选方法是什么? 最佳答案 请澄清一下,因为这是Google的早期结果。 __attribute__((__interrupt__(TIMER0_A0_VECTOR)
在 ISR 内设置断点是否合法/可能?或者这是特定于硬件的? 最佳答案 是的,这是完全合法的,但是由于其他 ISR 没有及时触发,例如 USB,可能会出现一些小问题。 关于embedded - ISR
我正在使用 Hi-Tech-PICC v9.65PL1 进行 C 语言编程,对 PIC16F876 进行编程。 对于中断,我使用以下结构: void interrupt isr() { if
被零除错误未调用 ISR0。 我的内核主要从 boot.s 调用 void kernel_main() { gdt_install(); idt_install(); isrs_
我用8051的硬件中断0编写了一个简单的led闪烁代码。当按钮被按下时,它进入中断服务程序(ISR)。执行后它应该返回到主函数中,但它没有出现。这是我的c代码。任何积极的答复将不胜感激。 sbit L
在特定的 ISR 之后是否有任何(脏)方法来触发上下文切换到特定的进程? 在正常情况下,在 ISR 之后,被中断的进程会继续运行,我必须等待调度程序选择那个特定的进程。我想在 ISR 之后立即切换到具
我有一个非常简单的程序让我很头疼。 一些背景:我正在 atmelstudio 6 中对 arduino Uno“Atmega328P”进行编程。我在 debugwire 模式下使用 JTAGICE m
有没有一种方法可以从定时器 ISR 中操纵堆栈?所以我可以通过强制退出长时间运行的函数来丢弃堆栈的最高帧吗? (我知道在这种情况下会丢失堆分配的内存) 目标可能是 ARM CPU。 最好的问候 最佳答
我正在研究操作系统,我遇到了 ISR 和中断处理程序这两个术语。他们是同一个机制的两个词吗?如果不是,有什么区别? 最佳答案 中断处理程序和 ISR 没有区别。 Wiki说: In computer
是否可以使用类方法作为中断服务程序? 我有一个 ISR 编写并使用一个函数在 C 中工作: static void interrupt far ISR(...) {} 我尝试在 C++ 中创建
我正在尝试实现该功能 unsigned int (*poll) (struct file *filp, poll_table *wait); 在我的驱动程序中。我已经使用 将设备的文件描述符添加到等待
使用 RTOS(前 FreeRTOS)时,我们为每个线程提供单独的堆栈空间。那么ISR(中断服务程序)呢,它们在内存中是否有单独的堆栈?或者这是可配置的? 如果他们没有一个堆栈来存储 ISR 中声明的
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 6 年前。 Improve
我是一名优秀的程序员,十分优秀!