检查osKernalSysTick()的环绕需要吗?

时间:2016-11-02 09:58:32

标签: c arm embedded keil

我正在关注Keil的CMSIS-RTOS Tutorial。它提供了以下方法来放置亚毫秒延迟:

  

部分:亚毫秒延迟

int32_t tick,delayPeriod;
tick = osKernelSysTick(); // get start value of the Kernel system tick
// Then we can scale a period in microseconds to a SysTick count value
delayPeriod = osKernelTickMicroSec(100));
// This then allows us to create a delay for the the required period.
do { // Delay for 100 microseconds 
} while ((osKernelSysTick() - tick) < delayPeriod); 

osKernelSysTick()返回滚动32位计数器的值;此实现不适合该值的环绕。

如果发生环绕,则无法实现预期的延迟。这是官方Keil文档中的错误还是我遗漏了什么?

1 个答案:

答案 0 :(得分:3)

由于算术运算的方式,您显示的实现不能满足环绕性。

do { // Delay for 100 microseconds 
} while ((osKernelSysTick() - tick) < delayPeriod); 

当计时器换行时,这会导致算术溢出。

如果您使用unsigned变量并计算之前的缩短时间将其与所需的时间进行比较,您将避免这种情况。 C标准保证无符号变量可以包装。

uint32_t tick, delayPeriod, elapsed;            // unsigned
tick = osKernelSysTick();
delayPeriod = osKernelTickMicroSec(100));

do {
    elapsed = osKernelSysTick() - tick;         // separate arithmetic wraps cleanly
} while (elapsed < delayPeriod); 

请注意,该函数无论如何都定义为uint32_t osKernelSysTick,因此使用签名类型时原始示例不正确。