嵌入式软件开发的基础知识(5)结构体问题
在开发过程中,经常会需要很多的标志位。标志位的状态大多数都仅仅占用一两个bit。所以为了节省内存占用,方便管理标志位,使用结构体和联合体的方式。
如下所示定义结构体,联合体,以及初始化联合体。其中定义部分可以放到 .h 文件中。初始化可以放到 .c 文件中。并且该变量可以在 .h 文件中 extern 出去,在外部使用。
注意事项:
因为我是做伺服研发的,所以程序需要内外环不同时序调度。
主循环1K调度 (1ms调度一次)
位置环4K调度 (250us中断调度一次)
速度环和电流环16K调度(62.5us中断调度一次,中断优先级最高)
因为16K和4K的程序都是中断函数。所以16K可以打断4K和1K调度的程序。4K也可以打断1K的主循环。
如果存在不同环路对同一个Union操作,则位域赋值操作过程中可能会被中断打断,造成数据丢失。例如1K对Union的任意bit赋值时,被16K程序打断,且在16K程序中执行了对Union任意bit的写操作。在16K程序执行完成后,1K程序从堆栈恢复现场,就会导致16K中的赋值操作无效。
如果有学过多线程,应该很熟悉这个问题。但是很遗憾,裸机开发没有锁和临界区这种东西。所以不同时序对同一个数据进行写操作一定存在风险。要避免不同调度中对一个变量进行赋值。如果某个Union不同调度中有写操作,那就老老实实的用Uint8变量来表示标志。 如果是变量存在不同调度的写入操作,那这就没办法了。(Union的所有的bit赋值都存在风险。但是使用的Uint8数据只会和自己冲突。)