栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

嵌入式软定时任务管理内核,C语言通用

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

嵌入式软定时任务管理内核,C语言通用

软定时管理任务内核 源文件

#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


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1021880.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号