对于简单的嵌入式应用多数裸奔就能解决,但写出来的裸奔代码质量也由好坏之分。
在网上看到了这样一篇文字:
上面说到了裸奔环境下的多任务模型 - stateMachine + timerTick + Queue,也提到具体怎么做。
伪代码实现
//消息类型
enum MessageType {
MSG_USART1,
MSG_USART3,
MSG_20MS = 20,
MSG_100MS = 100,
};
typedef enum MessgeType enMsgType
stMsgQueue g_AppMsgQueue;
void AppMsgHandle(enMsgType msg)
{
switch (msg)
{
case MSG_USART1:
{
Usart1MsgHandle();
break;
}
case MSG_USART3:
{
Usart3MsgHandle();
break;
}
case MSG_20MSG: //定时20MS处理的任务
{
...
break;
}
case MSG_100MS: //定时100ms处理的任务
{
...
break;
}
}
}
int main(void)
{
Hardware_Init();
enMsgType msg;
while(1)
{
if (MQ_GetMsg(&g_AppMsgQueue, &msg))
AppMsgHandle(msg);
}
}
void USART1_IRQHandler(void)
{
if (USART_GetTIFlag(USART1, TI_IDLE) == SET)
{
MQ_PublishMsg(&g_AppMsgQueue, MSG_USART1); //接收完一帧数据发送MSG_USART1消息给消息队列
}
}
void USART3_IRQHandler(void)
{
if (USART_GetTIFlag(USART3, TI_IDLE) == SET)
{
MQ_PublishMsg(&g_AppMsgQueue, MSG_USART3);
}
}
//1ms中断 timerTick
void TIM_IRQHandler(void)
{
static uint16_t msCount = 0;
if (TIM_GetTIFlag(TIM2, TI_UPDATE) == SET)
{
msCount++;
if (msCount % MSG_20MS == 0)
MQ_PublishMsg(&g_AppMsgQueue, MSG_20MS);
if (msCount % MSG_100MS == 0)
MQ_PublishMsg(&g_AppMsgQueue, MSG_100MS);
}
}
由于使用的消息队列处理的任务,消息队列可以缓存事件,即使其中一个任务处理事件过长,其他任务事件也不会丢失。
对于紧急处理的任务可以将消息插入队头:
MQ_PublishArgentMsg(&g_AppMsgQueue, MSG_USART1);
stateMachine + timerTick + Queue已经应用到实际项目中,确实好用。
仔细想想,其实很多系统啥的事件都是使用的消息队列处理的事件。