在有嵌入式操作系统的情况下,可以利用多任务和信号量,事件等设计嵌入式软件。但是在没有操作系统的裸机中,更需要有好的架构。例如利用事件和状态机模拟实现多任务,或者利用定时器和消息队列,信号量等模拟实现多任务,有了多任务就能灵活的设计软件架构。
借住定时器和任务队列实现的一种模拟多任务:
#include <stdio.h>#include "timTask.h"#include "disp.h"/*====================================================== 变量定义=====================================================*///任务队列typedef struct{char flagState; //运行方式 0: 无任务// 1: 运行char flagRun; //完成状态 0: 正在计数// 1: 计数完成char flagType; //处理方式 0: 主任务处理// 1: 中断处理ulong cntRun; //运行计数器ulong numCircle; //循环计数器void (*pTaskFunc)(void); //任务}TypeTimTask;TypeTimTask timTaskTab[TIM_TASK_NUMBER];/************************************************************************** 函数原型:* 功能描述:* 入口参数:* 出口参数:* 返 回 值:*************************************************************************/void TimTaskInit(void){int i;for (i=0; i<TIM_TASK_NUMBER; i++){timTaskTab[i].pTaskFunc = 0;timTaskTab[i].cntRun = 0;timTaskTab[i].numCircle = 0;timTaskTab[i].flagRun = 0;timTaskTab[i].flagState = 0;}SPT_register_call_back(TimTaskUpdate);SPT_set(TIM_TASK_PERIOD *64 / 1000);}/************************************************************************** 函数原型:* 功能描述:* 入口参数:* 出口参数:* 返 回 值:*************************************************************************/short TimTaskAdd(ulong fsttim, ulong cirtim, void (*pTaskFunc)(void), uchar type){int i;int pos = -1;//查找位置for (i=0; i<TIM_TASK_NUMBER; i++){if (timTaskTab[i].pTaskFunc == pTaskFunc){pos = i;break;}if ((pos == -1) && (timTaskTab[i].flagState == 0)){pos = i;}}//任务已满if (pos == -1){return -1;}//timTaskTab[pos].pTaskFunc = pTaskFunc;timTaskTab[pos].cntRun = fsttim / TIM_TASK_PERIOD;timTaskTab[pos].numCircle = cirtim / TIM_TASK_PERIOD;timTaskTab[pos].flagRun = 0;timTaskTab[pos].flagType = type;timTaskTab[pos].flagState = 1;return 0;}/************************************************************************** 函数原型:* 功能描述:* 入口参数:* 出口参数:* 返 回 值:*************************************************************************/void TimTaskDel(void (*pTaskFunc)(void)){int i;for (i=0; i<TIM_TASK_NUMBER; i++){if (timTaskTab[i].pTaskFunc == pTaskFunc){timTaskTab[i].flagState = 0;timTaskTab[i].flagRun = 0;return;}}}/************************************************************************** 函数原型:* 功能描述:* 入口参数:* 出口参数:* 返 回 值:*************************************************************************/void TimTaskUpdate(void){int i;SPT_set(TIM_TASK_PERIOD *64 / 1000);for (i=0; i<TIM_TASK_NUMBER; i++){if (timTaskTab[i].flagState != 0){if (timTaskTab[i].cntRun != 0){timTaskTab[i].cntRun--;}else{//判断处理位置if (timTaskTab[i].flagType != 0)(*timTaskTab[i].pTaskFunc)();elsetimTaskTab[i].flagRun = 1;//判断重载if (timTaskTab[i].numCircle)timTaskTab[i].cntRun = timTaskTab[i].numCircle;elsetimTaskTab[i].flagState = 0;}}}}/************************************************************************** 函数原型:* 功能描述:* 入口参数:* 出口参数:* 返 回 值:*************************************************************************/void TimTaskProc(void){int i;for (i=0; i<TIM_TASK_NUMBER; i++){if (timTaskTab[i].flagRun != 0){timTaskTab[i].flagRun = 0;(*timTaskTab[i].pTaskFunc)();}}}
可以借住函数指针实现一种灵活的菜单和按键实时处理结构。类似于windows下win32的消息驱动机制,
通过中断等方式把实时事件封装成消息。以下为定义界面刷新显示和响应按键处理的结构:
