嵌入式软件常用的几种代码架构

本文介绍了在嵌入式系统中,如何使用时间片轮询方法来设计程序架构,包括任务函数的执行策略、定时器的运用以及如何确定任务周期。讨论了无指针和含函数指针两种实现方式,并提及了ucos、freertos和rt-thread等操作系统在任务管理中的应用。

嵌入式软件常用两种代码架构

时间片轮询法

介于前后台顺序执行和操作系统之间的一种程序架构设计方案。适用于比较复杂的嵌入式系统中;

任务函数⽆需时刻执⾏,存在间隔时间(⽐如按键,⼀般情况下,都需要软件防抖,初学者的做法通常是延时10ms左右再去判断,但10ms极⼤浪费了CPU的资源,在这段时间内CPU完全可以处理很多其他事情)实时性有⼀定的要求。该设计⽅案需要使⽤⼀个定时器,⼀般情况下定时1ms即可(定时时间可随意定,但中断过于频繁效率就低,中断太⻓,实时性差),因此需要考虑到每个任务函数的执⾏时间,建议不能超过1ms(能通过程序优化缩短执⾏时间则最好优化,如果不能优化的,则必须保证该任务的执⾏周期必须远⼤于任务所执⾏的耗时时间),同时要求主循环或任务函数中不能存在毫秒级别的延时。

如何确定函数任务周期? 根据任务耗时和效果决定,例如按键扫描任务周期为10ms,指示灯控制周期为100ms,lcd显示周期为100ms,所以任务周期必须远大于耗时,同时满足刷屏需求。

通过两种变成方式,实现时间片轮询法(指针与非指针方式)

1.无指针的设计方式

// 设计主函数
int mian(void)
{
    System_Init();
    while(1)
    {
        if(Timer_1msFlag)
        {
            Uart_CommTask();
            Timer_1msFlag = 0;
        }
        if(Timer_10msFlag)
        {
            Key_ScanTask();
            Timer_10msFlag = 0;
        }
        if(Timer_50msFlag)
        {
            Logic_HandleTask();
            Timer_50msFlag = 0;
        }
    }
}
//以此向下进行分类完成各自任务

// 设计中断服务函数
void Timer_IRQHandler(void)
{
    if(Timer_GetITStatus(TIM,TIM_IT_Update) == SET)//溢出中断
    {
        sgsTic++;
        sgsTic % 1  == 0 ? Timer_1msFlag  = 1 : 0 ;
        sgsTic % 10 == 0 ? Timer_10msFlag = 1 : 0 ;
        sgsTic % 50 == 0 ? Timer_50msFlag = 1 : 0 ;
    }
    Timer_CleaerITPendingBit(TIM,TIM_IT_Update); // 清除中断标志位
}

2.含函数指针的设计方式

// 设计任务函数的相关结构体
typedef struct
{
    uint8 m_runFlag;				//程序标记运行 0不运行 1运行
    uint16 m_timer;					//计时器
    uint16 m_itvTime;				//任务运行间隔
    void(*m_pTaskCallBack)(void);	//任务运行函数
} Task_InfoType;

#define TASKS_MAX 3 				//定义任务数目

//任务的相关信息
static Task_InfoType st_TaskInfo[TASKS_MAX] =
{
    {0,	1,	1,	Uart_CommTask},
    {0,	10,	10,	Key_ScanTask},
    {0,	50,	50,	Logic_HandleTask},
};

//任务函数运行的相关标志处理,此函数在1ms定时器中运行
void Task_Remarks(void)
{
    uint 8 i;
    for(i=0,i<TAKS_MAX; i++)
    {
        if(st_TaskInfo[i].m_timer)
        {
            st_TaskInfo[i].m_timer--;
             if(0 == st_TaskInfo[i].m_timer)
             {
                 st_TaskInfo[i].m_timer = st_TaskInfo[i].m_itvTime;
                 st_TaskInfo[i].m_runFlag = 1;
             }
        }
    }
}

// 任务函数运行处理
void Task_Process(void)
{
    uint8 i;
    for(i = 0; i< TASKS_MAX; i++)
    {
        if(st_TaskInfo[i].m_runFlag)
        {
            st_TaskInfo[i].m_pTaskCallBack)();
            st_TaskInfo[i].m_runFlag = 0;
        }
    }
}

//主函数
int main(void)
{
   System_Init();
   while(1)
   {
       Task_Process();
   }
}

// 设计中断服务函数
void Timer_IRQHandler(void)
{
    if(Timer_GetITStatus(TIM,TIM_IT_Update) == SET)//溢出中断
    {
        Task_Remarks();
    }
    Timer_CleaerITPendingBit(TIM,TIM_IT_Update); // 清除中断标志位
}

操作系统

嵌⼊式操作系统EOS(Embedded Operating System)是⼀种⽤途⼴泛的系统软件,过去它主要应⽤于⼯业控制和国防系统领域。对于单⽚机来说,⽐较常⽤的有UCOS、FreeRTOS 等多种抢占式操作系统(其他如Linux等操作系统不适⽤于单⽚机)操作系统和“时间⽚轮询法”,在任务执⾏⽅⾯来说,操作系统对每个任务的耗时没有过多的要求,需要通过设置每个任务的优先级,在⾼优先级的任务就绪时,会抢占低优先级的任务。

uCOS:⽹上资料丰富,⾮常适合学习,但是在产品上使⽤则需要收费。

FreeRTOS:使⽤免费,因此很多产品都在⽤。

RT-Thread:国产物联⽹操作系统,有着⼗分丰富的组件,也免费,资料:RTThread⽂档中⼼。

RTX:为ARM和Cortex-M设备设计的免版税,确定性的实时操作系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值