标题:
闲着无聊写了个简便的裸机调度器 附单片机程序
[打印本页]
作者:
jizhongbiao
时间:
2020-11-8 00:47
标题:
闲着无聊写了个简便的裸机调度器 附单片机程序
废话不说,直接上单片机程序。
=========================================================================================
/*
说明:精简调度器实现
作者:jizhongbiao
微信:mcu6666
*/
#ifndef CORE_H
#define CORE_H
/* 基本类型转义(与平台相关注意修改) */
typedef (unsigned char) u8;
typedef (char) i8;
typedef (unsigned short) u16;
typedef (short) i16;
#define USE_LOW_POWER_MODE 0 /* 需要低功耗则打开这个宏 */
enum {
/* 依次在此处添加任务枚举作为唯一ID */
MAX_TASK_NUM
};
typedef enum {
DEL_INDEX,
DEL_ID,
MAX_DEL_TYPE,
}DeleteType;
typedef enum {
DEL_PARAERR,
DEL_SUCCESS,
DEL_FAIL,
MAX_DEL,
} DeleteResult;
typedef enum {
ADD_PARAERR,
ADD_SUCCESS,
ADD_FAIL,
MAX_ADD,
}AddResult;
/* 任务数据结构定义 */
typedef struct {
void (*TaskPtr)(void); /* 待运行的任务函数指针 */
u16 actionDelay; /* 运行延迟,以时标为单位,为0代表立即执行 */
u16 actionPeriod; /* 运行间隔为0代表单次运行 */
u8 readyFlg; /* 就绪标志 */
u8 taskId; /* 任务标识 非优先级 */
}TaskStruct;
void Scheduling(void);
DeleteResult TaskDelete(const u8 para, const DeleteType type);
void UpdataHandle(void);
AddResult AddTask( void (*TaskPtr)(), const u16 delay, const u16 period, const u8 id);
#endif
==========================================================================================
/*
说明:精简合作式调度器实现
作者:jizhongbiao
微信:mcu6666(项目承接)
版本:tt001.0
备注:1,需要硬件提供一个定时中断
2,当前版本不支持抢占式调度
*/
#include "core.h"
/* 任务队列 */
volatile static TaskStruct g_task[MAX_TASK_NUM];
/* 任务删除,支持两种方式(id及index) */
DeleteResult TaskDelete(const u8 para, const DeleteType type)
{
u8 i;
u8 temp = para;
DeleteResult ret;
/* 参数不合法 */
if ((type >= MAX_DEL_TYPE) || (para >= MAX_TASK_NUM)) {
return DEL_PARAERR;
}
if (type == DEL_INDEX) {
if(g_task[para].TaskPtr == 0) {
return DEL_FAIL;
}
} else {
for(i = 0; i < MAX_TASK_NUM, i++) {
if (g_task[i].TaskPtr) {
temp = i;
break;
}
}
if(i == MAX_TASK_NUM) {
return DEL_FAIL;
}
}
/* 真正的删除动作,注意不可以使用memset(id不准清0) */
g_task[temp].actionDelay = 0;
g_task[temp].actionPeriod = 0;
g_task[temp].readyFlg = 0;
g_task[temp].TaskPtr = 0;
return DEL_SUCCESS;
}
/* 任务创建 */
AddResult AddTask( void (*TaskPtr)(), const u16 delay, const u16 period, const u8 id)
{
u8 i = 0;
/* 判空 指向0地址会发生不可预测错误*/
if(TaskPtr == 0) {
return ADD_PARAERR;
}
while ((i < MAX_TASK_NUM) && g_task[i].TaskPtr) {
i++;
}
if (i == MAX_TASK_NUM) {
return ADD_FAIL;
}
/* 向表中空隙插入任务块信息 */
if(delay == 0) {
/* 在调度函数中会立即执行,不需要等待时标响应 */
g_task[i].readyFlg = 1;
} else {
g_task[i].readyFlg = 0;
}
g_task[i].actionDelay = delay;
g_task[i].actionPeriod = period;
g_task[i].taskId = id;
g_task[i].TaskPtr = TaskPtr;
return ADD_SUCCESS;
}
/* 定时刷新任务状态函数,本函数应在定时器中断函数中调用 */
void UpdataHandle(void)
{
u8 i;
for (i = 0; i < MAX_TASK_NUM; i++) {
if(g_task[i].TaskPtr) {
if(g_task[i].actionDelay) {
g_task[i].actionDelay--;
} else {
/* 本分支为延迟时间已经为0 */
g_task[i].readyFlg = 1;
/* 周期性任务重新设置延迟时标 单次任务删除在调度函数中完成*/
if(g_task[i].actionPeriod) {
g_task[i].actionDelay = g_task[i].actionPeriod;
}
}
}
}
}
/*调度器初始化*/
void ScheduInit(void)
{
u8 i;
for(i = 0; i < MAX_TASK_NUM; i++) {
(void)TaskDelete(i, DEL_INDEX);
}
}
/* 调度执行函数 */
void Scheduling(void)
{
u8 index;
for(index = 0; index < MAX_TASK_NUM; index++) {
if (g_task[index].readyFlg) {
(g_task[index].TaskPtr)(); /* 执行已就绪的任务 */
g_task[index].readyFlg = 0;
/* 如果单次运行则删除该任务 */
if(g_task[index].actionPeriod == 0) {
TaskDelte(index);
}
}
}
#if (USE_LOW_POWER_MODE == 1)
McuEnterStandby(); /* 需要根据不同芯片及硬件适配低功耗函数 */
#endif
}
复制代码
作者:
TTQ001
时间:
2020-11-8 08:23
感谢您分享您的代码。 应该会很有帮助!
作者:
51hei团团
时间:
2020-11-8 14:56
好东东啊,能应用在哪些地方呢?
作者:
jizhongbiao
时间:
2020-11-22 12:38
核心还是时间触发,不适合需要快速响应的场合。因为不支持抢占式调度,就我的经验来说绝大多数单片机的应用合作式调度足够了。
作者:
zhanghl55
时间:
2020-11-30 15:20
牛人呀!这是自定义多任务系统的最佳启蒙资料了。受教了!
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1