起因
本身有一段c代码,代码逻辑如下:
填充片上SRAM数据;
启动DMA搬移;
确认搬移效果;
可实际上行为并非如想象中这样,而是先配置了寄存器, 然后CPU才填充数据:
问题原因
其实这个问题原因很简单,首先寄存器使用的全局结构体指针已经声明为volatile类型,那么首先检查for循环调用的write函数是否是用的volatile; 很快就发现坑在这里,并没有使用volatile:
何为volatile?
在 C 语言中,volatile 是一个类型限定符,用于声明变量为"易失"(volatile)变量。volatile 告诉编译器不要对该变量进行优化,以确保对变量的读写操作不会被优化掉或重新排序。
当一个变量被声明为 volatile,编译器将不会对该变量进行优化,因为该变量的值可能会在程序的控制之外发生变化。这样可以确保对该变量的读写操作与程序的执行顺序一致,避免出现意外的行为。
volatile 变量通常用于以下情况:
并发访问:当多个线程或中断服务子程序(ISR)同时访问一个变量时,可以将该变量声明为 volatile,以确保每个访问都是直接从内存中读取或写入的,而不是从寄存器或缓存中获取。
外部硬件访问:当变量表示与外部硬件设备的状态或寄存器值相关时,例如在嵌入式系统中,可以将该变量声明为 volatile,以确保对变量的读写操作与外部设备的交互保持同步。
防止编译器优化:某些情况下,变量的值可能会在程序控制之外发生变化,但编译器无法感知到。通过将变量声明为 volatile,可以告诉编译器不要对该变量进行优化,以确保读写操作的准确性。
需要注意的是,volatile 不能用于多线程同步或替代锁机制。它只能确保对变量的读写操作不会被优化,但不能提供原子性或顺序性保证。在多线程环境中,为了实现正确的同步,仍然需要使用适当的同步机制(如互斥锁、原子操作等)来保护对共享变量的访问。
————————————————
版权声明:本文为CSDN博主「hemlok」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hemlok/article/details/132615182
|