C 在执行后续代码之前执行内存写入
我正在编写触发DMA的代码。一旦DMA完成其操作,它将调用C 在执行后续代码之前执行内存写入,c,memory,arm,embedded,race-condition,C,Memory,Arm,Embedded,Race Condition,我正在编写触发DMA的代码。一旦DMA完成其操作,它将调用ISR\u例程。问题是,我想确保在DMA运行之前,refreshComplete设置为0。如果DMA在refreshComplete设置为0之前先运行,则可以先调用ISR_例程,使refreshComplete成为0,即使DMA已成功运行。这意味着ready()函数将始终返回0,阻止进一步使用DMA 我现在编写代码的方式是refreshComplete变量是volatile,我忙着等待,直到读回变量是0,DMA才会这样运行: volati
ISR\u例程
。问题是,我想确保在DMA运行之前,refreshComplete
设置为0
。如果DMA在refreshComplete
设置为0
之前先运行,则可以先调用ISR_例程
,使refreshComplete
成为0
,即使DMA已成功运行。这意味着ready()
函数将始终返回0,阻止进一步使用DMA
我现在编写代码的方式是refreshComplete
变量是volatile
,我忙着等待,直到读回变量是0
,DMA才会这样运行:
volatile uint8 refreshComplete = 0u;
void trigger(void)
{
/* Write 0 and then busy wait */
refreshComplete = 0;
while (refreshComplete != 0);
/* Code to start the DMA */
...
}
/* ISR called once the DMA has completed its operation */
void ISR_Routine(void)
{
refreshComplete = 1u;
}
/* Function to check the status of the DMA */
uint8 ready(void)
{
return refreshComplete;
}
是否有一种方法可以保证设置刷新完成的代码总是在设置和运行DMA的代码之前运行?这是您应该查看处理器架构信息和指令集的地方
您将发现
DMB
、DSB
和ISB
,根据处理器的先进程度,可能还有其他一些。这些与强制执行数据传输的顺序以及指令相对于oter指令的顺序有关(因此,DMB,ISB
是一个常见的顺序)。当然,如果您在“C”中使用这些,您也需要担心语言的顺序保证。尽管对屏障说明的引用可能是相关的,但在这种情况下,我认为它们不需要。当代码正忙着等待时,无需保证写入ISR\u例程()
将在下一次读入ready()
之前完成。它会在下一次尝试时恢复volatile
在这里做所有必要的事情。我认为这取决于你是在回答最终目标,还是“规则在哪里”。我认为这两种方法都对OP有用。我假设他的代码最终会有更多的异常。同意,你的答案是有用的和准确的。但是我认为OP应该知道,没有必要将特定于体系结构的东西分散在代码中,这样在用portable C编写时就可以很好地工作。谢谢你的回答。在查阅了您的建议后,我找到了答案,其中显示了这些说明的用法。就代码可移植性而言,代码是为PSoC设备编写的,因此代码不需要是可移植的。