| 
 | 
 
路线栈欢迎您!
您需要 登录 才可以下载或查看,没有帐号?立即注册 
 
 
 
x
 
前言 
 
单片机的ROM与RAM存贮空间有限,一般没有多线程可用,给复杂的单片机项目带来困扰。经过多年的单片机项目实践,借鉴windows消息机制的思想,编写了单片机多任务事件驱动C代码,应用于单片机项目,无论复杂的项目,还是简单的项目,都可以达到优化代码架构的目的。经过几轮的精简、优化,现在分享给大家。 
 
设计思路 
 
代码分为3个模块:任务列表、事件列表、定时器列表。 
 
任务列表创建一个全局列表管理任务,通过调用taskCreat()创建事件处理任务,创建成功返回任务ID,任务列表、事件列表与定时器列表通过任务ID关联。 
 
事件列表创建一个全局循环列表管理事件,调用taskEventIssue()生成一个事件,放到事件循环列表,taskEventLoop()函数放到主线程循环调用,当事件循环列表中有事件时,根据任务ID分发到具体的事件处理任务。 
 
定时器列表创建一个全局列表管理定时器,taskTimer()建立一个定时器,放到定时器列表执行,当定时时间到,会生成一个定时器事件,放到事件列表,分发到具体的事件处理任务。 
 
代码例程: 
 
- //common.h
 
 - #ifndef __COMMON_H
 
 - #define __COMMON_H
 
  
- #include "stdio.h"
 
 - #include <stdlib.h>
 
 - #include <string.h>
 
  
- typedef short int16_t;
 
 - typedef int int32_t;
 
 - typedef long long int64_t;
 
 - typedef unsigned char uint8_t;
 
 - typedef unsigned short uint16_t;
 
 - typedef unsigned int uint32_t;
 
 - typedef unsigned long long uint64_t;
 
 - typedef unsigned char bool;
 
  
- #define false 0
 
 - #define true 1
 
  
- #endif // __COMMON_H
 
  复制代码- //task.h
 
 - #ifndef _THREAD_H
 
 - #define _THREAD_H
 
  
- #define TASK_MAX 20 // 最多任务数量
 
 - #define TASK_EVENT_MAX 100 // 任务队列长度
 
 - #define TASK_TIMER_MAX 100 // 定时器最大数量
 
  
- typedef void (*CBTaskEvent)(int taskID,uint32_t eventID);
 
 - typedef struct _TASK_EVENT
 
 - {
 
 -     int taskID;
 
 -     uint32_t eventID;
 
  
- } TASK_EVENT;
 
  
- int taskCreat(CBTaskEvent task);
 
 - void taskLoop();
 
 - void taskEventIssue(int taskID,uint32_t eventID);
 
 - void taskEventLoop();
 
  
- //定时、休眠
 
  
- typedef struct _TASK_TIMER
 
 - {
 
 -     bool isValid;
 
 -     int taskID;
 
 -     uint32_t eventID;
 
 -     uint32_t timeMs;
 
 -     uint32_t start;
 
  
- } TASK_TIMER;
 
  
- void taskTicksInc();
 
 - void taskTimer(int taskID,uint32_t eventID,uint32_t time_ms);
 
 - void taskTimerLoop();
 
  
- #endif // _THREAD_H
 
  复制代码- //task.c
 
 - #include "common.h"
 
 - #include "task.h"
 
  
- CBTaskEvent g_taskList[TASK_MAX]={0};
 
  
- int taskFindEmpty()
 
 - {
 
 -     static int index = -1;
 
  
-     for(int i=0; i<TASK_MAX; i++)
 
 -     {
 
 -         index++;
 
 -         index %= TASK_MAX;
 
 -         if(g_taskList[index]==NULL)
 
 -         {
 
 -             return index;
 
 -         }
 
 -     }
 
  
-     return -1;
 
 - }
 
  
- int taskCreat(CBTaskEvent task)
 
 - {
 
 -     int taskID;
 
  
-     taskID=taskFindEmpty();
 
 -     if(taskID == -1)
 
 -     {
 
 -         printf("error:task list is full!\n");
 
 -         return -1;
 
 -     }
 
  
-     g_taskList[taskID] = task;
 
  
-     printf("creat task<%d>\n",taskID);
 
  
-     return taskID;
 
 - }
 
  
- void taskDestroy(int taskID)
 
 - {
 
 -     printf("Destroy task<%d>\n",taskID);
 
  
-     g_taskList[taskID] = NULL;
 
 - }
 
  
- void taskLoop()
 
 - {
 
 -     taskEventLoop();
 
 -     taskTimerLoop();
 
 - }
 
  
- TASK_EVENT g_taskEventList[TASK_EVENT_MAX];
 
 - int g_TKEventWrite=0;
 
 - int g_TKEventRead=0;
 
  
- int tkEventGetSize()
 
 - {
 
 -     return (g_TKEventWrite + TASK_EVENT_MAX - g_TKEventRead)% TASK_EVENT_MAX;
 
 - }
 
  
- void taskEventIssue(int taskID,uint32_t eventID)
 
 - {
 
 -     int writePos;
 
  
-     if(taskID >= TASK_EVENT_MAX || taskID < 0)
 
 -     {
 
 -         printf("taskEventIssue() error:taskID\n");
 
 -         return;
 
 -     }
 
  
-     writePos = (g_TKEventWrite + 1)% TASK_EVENT_MAX;
 
  
-     if(writePos == g_TKEventRead)
 
 -     {
 
 -         printf("taskEventIssue() error:task<%d> event list is full!\n",taskID);
 
 -         return;
 
 -     }
 
  
-     g_taskEventList[g_TKEventWrite].taskID=taskID;
 
 -     g_taskEventList[g_TKEventWrite].eventID=eventID;
 
 -     g_TKEventWrite=writePos;
 
  
-     //printf("add event:%x\n",eventID);
 
 - }
 
  
- void taskEventLoop()
 
 - {
 
 -     TASK_EVENT event;
 
 -     CBTaskEvent task;
 
 -     int size;
 
  
-     size=tkEventGetSize();
 
 -     while(size-- >0)
 
 -     {
 
 -         event=g_taskEventList[g_TKEventRead];
 
 -         g_TKEventRead = (g_TKEventRead + 1)% TASK_EVENT_MAX;
 
  
-         task = g_taskList[event.taskID];
 
 -         if(!task)
 
 -         {
 
 -             printf("taskEventLoop() error:task is NULL\n");
 
 -             continue;
 
 -         }
 
  
-         task(event.taskID,event.eventID);
 
 -     }
 
 - }
 
  
- // 定时、休眠
 
  
- uint32_t g_taskTicks=0;
 
  
- uint32_t getTaskTicks()
 
 - {
 
 -     return g_taskTicks;
 
 - }
 
  
- void taskTicksInc() // 1ms时间基准
 
 - {
 
 -     g_taskTicks++;
 
 - }
 
  
- uint32_t taskTickDiff(uint32_t now,uint32_t last)
 
 - {
 
 -     uint64_t diff;
 
 -     diff = now + 0x100000000 - last;
 
  
-     return (diff & 0xffffffff);
 
 - }
 
  
- TASK_TIMER g_taskTimerList[TASK_TIMER_MAX]={0};
 
  
- int taskTimerFindEmpty()
 
 - {
 
 -     for(int i=0; i<TASK_TIMER_MAX; i++)
 
 -     {
 
 -         if(!g_taskTimerList[i].isValid)
 
 -         {
 
 -             return i;
 
 -         }
 
 -     }
 
  
-     return -1;
 
 - }
 
  
- void taskTimer(int taskID,uint32_t eventID,uint32_t time_ms)
 
 - {
 
 -     int index;
 
  
-     index=taskTimerFindEmpty();
 
 -     if(index==-1)
 
 -     {
 
 -         printf("taskTimer() error:timer list is full\n");
 
 -         return;
 
 -     }
 
  
-     g_taskTimerList[index].taskID=taskID;
 
 -     g_taskTimerList[index].eventID=eventID;
 
 -     g_taskTimerList[index].timeMs=time_ms;
 
 -     g_taskTimerList[index].start=getTaskTicks();
 
 -     g_taskTimerList[index].isValid=true;
 
  
-     printf("add timer:<%d,%x> %ums\n",taskID,eventID,time_ms);
 
  
- }
 
  
- void taskTimerLoop()
 
 - {
 
 -     static uint32_t start=0;
 
 -     if(taskTickDiff(getTaskTicks(),start)<3)
 
 -     {
 
 -         return;
 
 -     }
 
  
-     start=getTaskTicks();
 
  
-     for(int i=0; i<TASK_TIMER_MAX; i++)
 
 -     {
 
 -         if(g_taskTimerList[i].isValid)
 
 -         {
 
 -             if(taskTickDiff(start,g_taskTimerList[i].start)>=g_taskTimerList[i].timeMs)
 
 -             {
 
 -                 taskEventIssue(g_taskTimerList[i].taskID,g_taskTimerList[i].eventID);
 
 -                 g_taskTimerList[i].isValid=false;
 
 -             }
 
 -         }
 
 -     }
 
 - }
 
  复制代码- //test_task.h
 
 - #ifndef _TEST_THREAD_H
 
 - #define _TEST_THREAD_H
 
  
- void testInit();
 
 - void testLoop();
 
  
- #endif // 
 
  复制代码- //test_task.c
 
 - #include "common.h"
 
 - #include "task.h"
 
  
- #define CTRL_EVENT1 0x01
 
 - #define CTRL_EVENT2 0x02
 
 - #define CTRL_EVENT3 0x04
 
  
- void eventProcess(int taskID,uint32_t event)
 
 - {
 
 -     switch(event)
 
 -     {
 
 -         case CTRL_EVENT1:
 
 -             printf("task[%d] CTRL_EVENT1\n",taskID);
 
 -             //taskEventIssue(taskID,CTRL_EVENT2);
 
 -             taskTimer(taskID,CTRL_EVENT2,1000);
 
 -             break;
 
  
-         case CTRL_EVENT2:
 
 -             printf("task[%d] CTRL_EVENT2\n",taskID);
 
 -             //taskEventIssue(taskID,CTRL_EVENT3);
 
 -             taskTimer(taskID,CTRL_EVENT3,2000);
 
 -             break;
 
  
-         case CTRL_EVENT3:
 
 -             printf("task[%d] CTRL_EVENT3\n",taskID);
 
 -             taskTimer(taskID,CTRL_EVENT1,4000);
 
 -             break;
 
  
-         default:
 
 -             break;
 
 -     }
 
 - }
 
  
- void testLoop()
 
 - {
 
 -     taskLoop();
 
 - }
 
  
- void testInit()
 
 - {
 
 -     int taskID1,taskID2;
 
  
-     printf("testInit()\n");
 
  
-     taskID1 = taskCreat((CBTaskEvent)&eventProcess);
 
  
-     taskTimer(taskID1,CTRL_EVENT1,5000);
 
  
-     taskID2 = taskCreat((CBTaskEvent)&eventProcess);
 
 -     taskEventIssue(taskID2,CTRL_EVENT2);
 
 -     taskDestroy(taskID1);
 
 -     taskDestroy(taskID2);
 
 -     //taskEventIssue(taskID1,CTRL_EVENT1);
 
 -     taskID1 = taskCreat((CBTaskEvent)&eventProcess);
 
 -     taskEventIssue(taskID1,CTRL_EVENT1);
 
 - }
 
  复制代码 
 
 |   
 
 
 
 |