单核嵌入式设备上的经典问题:
void blink() {
set_main_diode(HIGH);
delay(200);
set_main_diode(LOW);
delay(200);
}这将占用CPU,从而占用设备的其他实时组件(如USB等)。在执行此操作之前,不会勾选。当然,我们有一个实时操作系统,但我不想使用实时操作系统。处理状态的最佳方式是什么?我喜欢这个State Machine Design in C,尽管我希望看到任何其他设计的状态机或如何处理状态的方法。
发布于 2021-01-21 17:56:29
如果嵌入式设备只是在闪烁LED,那么浪费CPU资源是没有问题的。即使你有一个基于中断的代码,你也会在某些时候浪费CPU周期:
interrupt function Timer100ms ()
{
// state machine implementation
// to toggle the LEDs
}
void main ()
{
InitializeLED();
InitializeTimers();
while (true)
{
// do nothing, waiting for the LED to flash
}
}发布于 2021-01-21 18:29:52
实现裸机实时系统的经典方法是使用类似于您所链接的状态机的代码,基于函数指针。但它实际上并不是一个状态机,而是一个要执行的任务列表。一种“穷人的RTOS”的方式,它实际上包含了RTOS为上下文切换和单独的进程堆栈而保存的所有内容。它可能看起来像这样:
typedef err_t task_t (void);
static task_t* const TASK [TASK_N] =
{
display,
uart,
leds,
...
};
void main (void)
{
/* misc init code here */
err_t result;
size_t task_count = 0;
for(;;)
{
kick_wdog();
result = TASK[task_count]();
if(result != OK)
{
error_handler(result, task_count);
}
task_count++;
if(task_count == TASK_N)
{
task_count=0;
}
}
}这里,假设TASK列表中的每个函数都是非阻塞的。例如,如果它轮询各种标志,它应该优先使用if(REG & FLAG)而不是while((REG & FLAG)==0)。并且每个模块/驱动程序保持跟踪其内部状态。这意味着CPU的最大利用率。
看门狗应该被配置为,如果一个单独的任务需要太长时间才能完成,它就会终止程序。此外,您可以在执行每个任务之前启动硬件计时器。然后,您可以检查它需要多长时间才能完成。
在实时系统中,你通常有一个循环时间,所有任务都应该在这个循环时间内完成,例如10ms。这意味着您将首先等待10ms的周期,然后再将任务计数器设置为零。在此期间,您可以选择将MCU置于休眠模式,以节省电流。
这也是您经常设计高完整性系统的方式,其中看门狗使用“窗口模式”,这意味着它必须在一定的时间间隔内输入才能不重置。
发布于 2021-01-21 17:58:46
我想说最简单的方法是使用计时器。您可以将LED设置为高电平,并启动计时器。在中断处理例程中,您可以关闭LED并禁用定时器。如果你想持续闪烁,你可以简单地设置一个定时器,在ISR中,你只需切换LED即可。我不会为了一些LED闪烁而去寻找实时操作系统,在我看来这将是一个相当大的开销。
https://stackoverflow.com/questions/65824815
复制相似问题