软定时管理任务内核
源文件
#include "kern.h"
#include
// 时间片长,单位ms,中断一次周期
uint16_t TIME_SLICE = 1;
// 内核时间片计数
volatile uint32_t kern_time_slice_count = 0;
// 任务队列
static TASK_QUEUE task_queue;
void increase_kern_time(void)
{
kern_time_slice_count++;
}
uint32_t get_kern_time(void)
{
return kern_time_slice_count;
}
void kern_init(uint16_t time_slice)
{
task_queue.tick_pre = get_kern_time();
task_queue.tick_cur = task_queue.tick_pre;
task_queue.task_num = 0;
TIME_SLICE = time_slice;
}
void schedule(void)
{
uint8_t i = 0;
uint8_t run_list[TASKS_NUMBER_MAX] = {0}, run_cnt = 0;
TASK_STRUCT *task;
// 更新当前任务队列时间
task_queue.tick_cur = get_kern_time();
// 内核时间正常,没有发生溢出
if(fabs(task_queue.tick_cur-task_queue.tick_pre) > 0)
{
// 置换时间
task_queue.tick_pre = task_queue.tick_cur;
// 遍历任务队列中的每个任务
for(i = 0; i < TASKS_NUMBER_MAX; i++)
{
// 把遍历的当前任务提取出来
task = &task_queue.tasks[i];
// 当前任务没有具体的执行函数
if(task->task_done == FUNCTION_NULL)
{
continue;
}
// 有具体的执行函数
else
{
// 任务没有挂起
if(task->state != TASK_STATE_SUSPEND)
{
// 任务时间还没轮到,让任务倒计时
if((task->time > 0) && (task->state != TASK_STATE_SUSPEND))
{
task->time--;
}
// 任务到时,改变任务状态
else
{
task->state = TASK_STATE_GO;
run_list[run_cnt++] = i;
}
}
}
}
}
// 等待执行的任务有多个时
if(run_cnt > 0)
{
// 遍历在等待执行的任务
for(i = 1; i < run_cnt; i++)
{
// 把任务提取出来
task = &task_queue.tasks[run_list[i]];
// 把最高优先级的任务提到等待执行的任务队列的前面
if(task_queue.tasks[run_list[i]].prio < task_queue.tasks[run_list[0]].prio)
{
run_list[0] = run_list[i];
}
}
// 提取最高优先级的等待任务
task=&task_queue.tasks[run_list[0]];
// 最高优先级的任务状态为等待执行
if(task->state == TASK_STATE_GO)
{
// 重置任务倒计时时间
task->time = task->period / TIME_SLICE;
// 执行具体的任务函数
task->task_done(task);
// 执行完任务后把任务状态重新回到倒计时准备的状态当中
task->state = TASK_STATE_READY;
}
}
// 正在等待执行的任务为1个或者没有时
else
{
// 从头到尾遍历任务
for(i = 0; i < TASKS_NUMBER_MAX; i++)
{
// 提取遍历的任务
task = &task_queue.tasks[i];
// 任务没有执行函数的直接跳过
if(task->task_done == FUNCTION_NULL)
{
continue;
}
// 有具体的执行函数的
else
{
// 任务在可以执行的状态中
if(task->state == TASK_STATE_GO)
{
run_list[run_cnt++] = i; // 记录下当前索引
}
}
}
// 遍历在等待当中的任务
for(i = 1; i < run_cnt; i++)
{
// 把任务提取出来
task = &task_queue.tasks[run_list[i]];
// 把最高优先级的任务提取出来
if(task_queue.tasks[run_list[i]].prio < task_queue.tasks[run_list[0]].prio)
{
run_list[0] = run_list[i];
}
}
// 达到最高优先级的任务
task=&task_queue.tasks[run_list[0]];
// 有具体的任务函数,并且任务可执行
if((task->task_done != FUNCTION_NULL) && (task->state == TASK_STATE_GO))
{
// 重置任务倒计时
task->time = task->period / TIME_SLICE;
// 执行具体的任务函数
task->task_done(task);
// 切换任务的状态
task->state = TASK_STATE_READY;
}
}
}
static uint8_t find_task(uint8_t id)
{
uint8_t task_index = 0;
// 遍历任务队列中存在的任务,找到特定ID的任务
for(task_index = 0; task_index < TASKS_NUMBER_MAX; task_index++)
{
if(task_queue.tasks[task_index].id == id)
{
return task_index;
}
}
return FAIL_FIND_NULL;
}
uint8_t create_task(uint8_t id,
uint8_t prio,
uint8_t state,
uint16_t period,
void (*task_done)(void *))
{
uint8_t task_index = 0;
// 判断任务数量是否超过限制
if(task_queue.task_num >= TASKS_NUMBER_MAX)
{
return FAIL_CREATE_FULL;
}
// 寻找准备创建的任务ID,判断是否重复
task_index = find_task(id);
if(task_index < TASKS_NUMBER_MAX)
{
return FAIL_CREATE_REPEAT;
}
// 寻找空位置
task_index = find_task(0);
if(task_index >= TASKS_NUMBER_MAX) // 超出空间了
{
return FAIL_CREATE_FULL;
}
// 正常赋值
else
{
task_queue.tasks[task_index].id = id;
task_queue.tasks[task_index].prio = prio;
task_queue.tasks[task_index].state = state;
task_queue.tasks[task_index].period = period;
task_queue.tasks[task_index].time = period / TIME_SLICE;
task_queue.tasks[task_index].task_done = task_done;
// 任务队列中的任务数量加1
task_queue.task_num++;
}
return task_index;
}
uint8_t delete_task(uint8_t id)
{
uint8_t task_index = 0;
TASK_STRUCT *task;
task_index = find_task(id);
// 没找到此任务
if(task_index >= FAIL_FIND_NULL)
{
return FAIL_DELETE;
}
// 正常赋值
else
{
task = &task_queue.tasks[task_index];
task->id = 0;
task->prio = 0;
task->state = 0;
task->period = 0;
task->time = 0;
task->task_done = FUNCTION_NULL;
task_queue.task_num--;
}
return task_index;
}
uint8_t set_task_state(uint8_t id, uint8_t TASK_STATE)
{
uint8_t task_index = 0;
TASK_STRUCT *task;
task_index = find_task(id);
// 没找到此任务
if(task_index >= FAIL_FIND_NULL)
{
return FAIL_SUSPEND;
}
// 找到任务
else
{
task = &task_queue.tasks[task_index];
task->state = TASK_STATE;
}
return task_index;
}
void suspend_task(uint8_t id)
{
set_task_state(id, TASK_STATE_SUSPEND);
}
void resume_task(uint8_t id)
{
set_task_state(id, TASK_STATE_READY);
}
#if 0
// 包含必要的头文件
#include
#include "kern.h"
#include "led.h"
void KERN_TIMER_Init(uint32_t u32Freq)
{
// 用于作为内核定时器的初始化代码
}
void SYS_Init(void)
{
// 系统初始化代码
}
void TMR0_IRQHandler(void)
{
if(TIMER_GetIntFlag(TIMER0) == 1)
{
TIMER_ClearIntFlag(TIMER0);
// 调用增加内核计数函数
increase_kern_time();
}
}
// 创建任务的ID
typedef enum {
TASK1 = 1,
TASK2,
TASK3,
TASK4,
TASK5
}TASK_ID;
// 系统指示灯
void task_fun2(void *arg)
{
static uint32_t count = 0;
printf("task2 run times: %dn", ++count);
LED_RED = ~LED_RED;
}
// 闪灯
void task_fun3(void *arg)
{
static uint32_t count = 0;
printf("task3 run times: %dn", ++count);
LED_YELLOW = ~LED_YELLOW;
}
// 闪灯
void task_fun4(void *arg)
{
static uint32_t count = 0;
printf("task4 run times: %dn", ++count);
LED_GREEN = ~LED_GREEN;
}
// 关闭闪灯任务
void task_fun5(void *arg)
{
static uint32_t count = 0;
uint8_t index = 0;
printf("task5 run times: %dn", ++count);
// 运行5秒关闭点灯
if(count == 5)
{
// 删除其他点灯任务
delete_task(TASK3);
delete_task(TASK4);
}
// 运行10秒重新打开
if(count == 10)
{
create_task(TASK3, 3, TASK_STATE_READY, 200, task_fun3);
create_task(TASK4, 3, TASK_STATE_READY, 300, task_fun4);
}
// 运行15秒关闭点灯
if(count == 15)
{
// 删除其他点灯任务
delete_task(TASK3);
delete_task(TASK4);
delete_task(TASK5);
}
}
// 任务1用于创建其他任务
void task_fun1(void *arg)
{
static uint32_t count = 0;
printf("task1 run times: %dn", ++count);
if(count == 1)
{
// 创建其他任务
create_task(TASK2, 2, TASK_STATE_READY, 500, task_fun2);
create_task(TASK3, 3, TASK_STATE_READY, 200, task_fun3);
create_task(TASK4, 3, TASK_STATE_READY, 300, task_fun4);
create_task(TASK5, 5, TASK_STATE_READY, 1000, task_fun5);
}
// 删除自身任务
delete_task(TASK1);
}
int main(void)
{
// 系统初始化
SYS_Init();
// 调试串口
UART_Open(UART0, 115200);
// 内核定时器初始化
KERN_TIMER_Init(1000 / TIME_SLICE);
// 内核初始化
kern_init();
// 调试LED灯初始化
LED_Init();
// 创建第一个任务
create_task(TASK1, 1, TASK_STATE_READY, 500, task_fun1);
// 循环调用调度函数
while(1)
{
schedule();
}
}
#endif
头文件
#ifndef __KERN_H
#define __KERN_H
// 数据类型定义
#define DATA_TYPE_DEFINE 1
#if DATA_TYPE_DEFINE
typedef unsigned char uint8_t; // 无符号8位
typedef unsigned short int uint16_t; // 无符号16位
typedef unsigned int uint32_t; // 无符号32位
#endif
// 定义空指针
#define FUNCTION_NULL 0
// 任务最大数,根据u8最大值256,预留6位错误代码,任务最大数不建议超过250
#define TASKS_NUMBER_MAX 16
// 任务结构体
typedef struct{
uint8_t id; // 任务ID,唯一,自然数
uint8_t prio; // 任务优先级,自然数,越小优先级越高
uint8_t state; // 任务状态
uint16_t period; // 任务运行周期
uint16_t time; // 任务倒计时
void (*task_done)(void *); // 任务执行函数
}TASK_STRUCT;
// 任务队列
typedef struct{
uint32_t tick_pre; // 前一时刻
uint32_t tick_cur; // 现在时刻
uint8_t task_num; // 当前任务数
TASK_STRUCT tasks[TASKS_NUMBER_MAX]; // 任务数组
}TASK_QUEUE;
//------任务状态 ---@def TASK_STATE
typedef enum{
TASK_STATE_GO = 0,
TASK_STATE_READY,
TASK_STATE_SUSPEND,
}TASK_STATE;
//------错误返回值 ---@def FAIL_RETURN
typedef enum{
FAIL_FIND_NULL = (TASKS_NUMBER_MAX),
FAIL_CREATE_FULL = (TASKS_NUMBER_MAX),
FAIL_CREATE_REPEAT = (TASKS_NUMBER_MAX + 1),
FAIL_DELETE = (TASKS_NUMBER_MAX),
FAIL_SUSPEND = (TASKS_NUMBER_MAX),
}FAIL_RETURN;
void increase_kern_time(void);
uint32_t get_kern_time(void);
void schedule(void);
void kern_init(uint16_t time_slice);
uint8_t create_task(uint8_t id, uint8_t prio, uint8_t state, uint16_t period, void (*task_done)(void *));
uint8_t delete_task(uint8_t id);
uint8_t set_task_state(uint8_t id, uint8_t TASK_STATE);
void suspend_task(uint8_t id);
void resume_task(uint8_t id);
#endif