混合式调度器C51源代码

/*==============================================================
1ms时标 混合式调度器(一个抢占式任务,多个合作式任务)
作者:shadow.hu
===============================================================*/
#include
#define uchar unsigned char
#define ushort unsigned short
#define sch_max_tasks 9
#define error_sch_too_many_tasks 9
#define error_sch_canot_delete_task 0
#define return_error 0
#define return_normal 1
#define interrpt_timer_2_overflow 5
#define sch_report_errors
#ifdef sch_report_errors
#define error_port p1
#endif
typedef data struct
{
void (code *ptask)(void);
ushort delay;
ushort period;
ushort runme;
uchar co_op;//如果任务是合作式的,设置为1,如果任务是抢占式的,设置为0
}stask;
stask sch_tasks_g[sch_max_tasks];
void sch_init_t2(void);
uchar sch_add_task(void (code * pfunction)(),const ushort delay, ushort period);
// 函数名指针 延时的时标数 执行任务的时间间隔
// 为0则立即执行 如果为0,表示单次任务
void sch_dispatch_tasks(void);
void sch_start(void);
bit sch_delete_task(const ushort task_index);
void sch_go_to_sleep(void);
void sch_report_status(void);//报告系统状况
void led_flash_init(void);
void led_flash_update_a(void);
void led_flash_update_b(void);
void led_flash_update_c(void);
void led_flash_update_d(void);
void led_flash_update_e(void);
void led_flash_update_f(void);
void led_flash_update_g(void);
void led_flash_update_h(void);
uchar error_code_g = 0;//
static ushort error_tick_count_g;//记住自从上一次纪录错误以来的时间
static uchar last_error_code_g;//上次的错误代码(在1分钟之后复位)
uchar led_state_g_a = 0;
uchar led_state_g_b = 0;
uchar led_state_g_c = 0;
uchar led_state_g_d = 0;
uchar led_state_g_e = 0;
uchar led_state_g_f = 0;
uchar led_state_g_g = 0;
uchar led_state_g_h = 0;
sbit led_pin_a = p1^0;
sbit led_pin_b = p1^1;
sbit led_pin_c = p1^2;
sbit led_pin_d = p1^3;
sbit led_pin_e = p1^4;
sbit led_pin_f = p1^5;
sbit led_pin_g = p1^6;
sbit led_pin_h = p1^7;
//error_code_g = error_sch_too_many_tasks;
//error_code_g = error_sch_waiting_for_slave_to_ack;
//error_code_g = error_sch_waiting_for_start_comand_from_master;
//error_code_g = error_sch_one_or_more_slaves_did_not_start;
//error_code_g = error_sch_lost_slave;
//error_code_g = error_sch_can_bus_error;
//error_code_g = error_i2c_write_byte_at24c64;
void main(void)
{
sch_init_t2();
led_flash_init();
sch_add_task(led_flash_update_a,0,1000);//添加一个任务
sch_add_task(led_flash_update_b,0,2000);//添加一个任务
sch_add_task(led_flash_update_c,0,3000);//添加一个任务
sch_add_task(led_flash_update_d,0,4000);//添加一个任务
sch_add_task(led_flash_update_e,0,5000);//添加一个任务
sch_add_task(led_flash_update_f,0,6000);//添加一个任务
sch_add_task(led_flash_update_g,0,7000);//添加一个任务
sch_add_task(led_flash_update_h,0,8000);//添加一个任务
sch_start();//开全局中断
while(1)
{
sch_dispatch_tasks();
}
}
/*------------------------------------------------------------
这是调度器的中断服务程序,初始化函数中的定时器设置决定了它
的调度频率,这个版本的调度器由定时器2触发中断,定时器自动重装。
-------------------------------------------------------------*/
void sch_update(void) interrupt interrpt_timer_2_overflow
{
//刷新任务队列
uchar index;
tf2 = 0;//必须手工清除
//注意:计算单位为时标(不是毫秒)
for(index = 0;index < sch_max_tasks;index++)
{ //检测这里是否有任务
if(sch_tasks_g[index].ptask)
{
if(sch_tasks_g[index].delay == 0)
{
//任务需要运行,间隔的时间已经到了
if(sch_tasks_g[index].co_op)
{
//如果是合作式任务,runme标志加1
sch_tasks_g[index].runme += 1;//要执行任务的标志加1
}
else//如果它是抢占式任务,立即运行它
{
(*sch_tasks_g[index].ptask)();//运行任务
sch_tasks_g[index].runme -= 1;
//周期性的任务将自动再次运行,单次任务就删除
if(sch_tasks_g[index].period == 0)
{
sch_tasks_g[index].ptask = 0;
}
}
if(sch_tasks_g[index].period)//时标间隔不等于0
{
//调度周期性的任务再次运行,每隔这个固定的时标长度执行一次任务
sch_tasks_g[index].delay = sch_tasks_g[index].period;
}
}
else //任务有延迟执行要求,还没到达延迟的时间
{
//还没有准备好运行,延迟减1
sch_tasks_g[index].delay -= 1;
}
}
}
}
void sch_init_t2(void)
{
uchar i;
for(i=0;i{
sch_delete_task(i);
}
error_code_g = 0;
t2con = 0x04;
tmod = 0x00;
th2 = 0xfc;
rcap2h = 0xfc;
tl2 = 0x18;
rcap2l = 0x18;
et2 = 1;
tr2 = 1;
}
/*----------------------------------------------------------------------------
任务函数每隔一定时间间隔或在用户定义的延迟之后运行
pfunction -- 将被调用的函数名称。注意:被调函数必须是“void void”型
delay -- 在任务第一次被执行之前的间隔
period -- 如果它为0,则只调用该函数一次,由delay确定其调用的时间
如果非0,那么它就是被重复调用的时间间隔
co_op -- 如果是合作式任务则设置为1,如果是抢占式任务则设置为0.
注意:如果以后要删除任务,将需要返回值
例子:
task_id = sch_add_task(do_x,1000,0,0);
使函数do_x()在1000个调度器时标之后运行一次(抢占式任务)
task_id = sch_add_task(do_x,0,1000,1);
使函数do_x()每隔1000个调度器时标运行一次(合作式任务)
task_id = sch_add_task(do_x,300,1000,0);
使函数do_x()每隔1000个调度器时标运行一次,任务首先在t=300个时标时被执行
然后是1300个时标.........(抢占式任务)
-----------------------------------------------------------------------------*/
uchar sch_add_task(void (code * pfunction)(),const ushort delay, ushort period,bit co_op)
{
uchar index = 0;
//首先在队列中找到一个空隙(如果有的话,否则就不添加新任务)
while((sch_tasks_g[index].ptask != 0)&&(index < sch_max_tasks))
{
index++;//当一个新任务被添加,且没有超过任务上限
}
//是否达到任务队列的结尾?
if(index == sch_max_tasks)//任务数量达到上限
{
error_code_g = error_sch_too_many_tasks;
return sch_max_tasks;//直接返回,不添加这个新任务
}
//如果能运行到这里,说明任务队列中有空隙,添加任务。
sch_tasks_g[index].ptask = pfunction;
sch_tasks_g[index].delay = delay;
sch_tasks_g[index].period = period;
sch_tasks_g[index].co_op = co_op;
sch_tasks_g[index].runme = 0;
return index;//返回任务的位置(以便以后删除)
}
void sch_dispatch_tasks(void)
{
uchar index;
//调度(运行)下一个任务(如果有任务就绪)
for(index = 0;index 0)&&(sch_tasks_g[index].co_op))
{
(*sch_tasks_g[index].ptask)();//执行任务
sch_tasks_g[index].runme -= 1;//清除任务需要执行的标志
}
//如果这是个“单次”任务,将它从队列中删除
if(sch_tasks_g[index].period == 0)
{
sch_tasks_g[index].ptask = 0;// 比通过调用来删除任务更快sch_delete_task(index);
}
}
sch_report_status();//报告系统状况
sch_go_to_sleep();
}
void sch_start(void)
{
ea = 1;
}
bit sch_delete_task(const ushort task_index)
{
bit return_code;
if(sch_tasks_g[task_index].ptask == 0)
{
//这里没有任务。。。设置全局错误变量
error_code_g = error_sch_canot_delete_task;
return_code = return_error;//返回错误代码
}
else
{
return_code = return_normal;
}
//删除任务
sch_tasks_g[task_index].ptask = 0x0000;
sch_tasks_g[task_index].delay = 0;
sch_tasks_g[task_index].period = 0;
sch_tasks_g[task_index].runme = 0;
return return_code;
}
void sch_go_to_sleep()
{
pcon |= 0x01;//进入休眠模式
}
void sch_report_status(void)
{
/* #ifdef sch_report_errors
if(error_code_g != last_error_code_g)
{
error_port = 255 - error_code_g;
last_error_code_g = error_code_g;
if(error_code_g != 0)
{
error_tick_count_g = 60000;
}
else
{
error_tick_count_g = 0;
}
}
else
{
if(error_tick_count_g != 0)
{
if(--error_count_g == 0)
{
error_code_g = 0;
}
}
}
#endif */
}
void led_flash_update_a(void)
{
if(led_state_g_a == 1)
{
led_state_g_a = 0;
led_pin_a = 0;
}
else
{
led_state_g_a = 1;
led_pin_a = 1;
}
}
void led_flash_update_b(void)
{
if(led_state_g_b == 1)
{
led_state_g_b = 0;
led_pin_b = 0;
}
else
{
led_state_g_b = 1;
led_pin_b = 1;
}
}
void led_flash_update_c(void)
{
if(led_state_g_c == 1)
{
led_state_g_c = 0;
led_pin_c = 0;
}
else
{
led_state_g_c = 1;
led_pin_c = 1;
}
}
void led_flash_update_d(void)
{
if(led_state_g_d == 1)
{
led_state_g_d = 0;
led_pin_d = 0;
}
else
{
led_state_g_d = 1;
led_pin_d = 1;
}
}
void led_flash_update_e(void)
{
if(led_state_g_e == 1)
{
led_state_g_e = 0;
led_pin_e = 0;
}
else
{
led_state_g_e = 1;
led_pin_e = 1;
}
}
void led_flash_update_f(void)
{
if(led_state_g_f == 1)
{
led_state_g_f = 0;
led_pin_f = 0;
}
else
{
led_state_g_f = 1;
led_pin_f = 1;
}
}
void led_flash_update_g(void)
{
if(led_state_g_g == 1)
{
led_state_g_g = 0;
led_pin_g = 0;
}
else
{
led_state_g_g = 1;
led_pin_g = 1;
}
}
void led_flash_update_h(void)
{
if(led_state_g_h == 1)
{
led_state_g_h = 0;
led_pin_h = 0;
}
else
{
led_state_g_h = 1;
led_pin_h = 1;
}
}
void led_flash_init(void)
{
led_state_g_a= 0;//初始化led状态
led_state_g_b= 0;//初始化led状态
led_state_g_c= 0;//初始化led状态
}

大数据与人工智能的区别以及二者之间的联系
目前37家运营商已经推出了符合3GPP标准的5G FWA或家庭宽带服务
具备服务全球能力的北斗三号有哪些优势呢?
支付宝刷脸支付打响了“攻城掠地”的第一枪,安全性如何保证?
weblogic修改数据源需要重启吗
混合式调度器C51源代码
怎样防止电线短路?防止电气线路短路的几点措施
适应多种时序的DMA控制器设计
谷歌宣布针对Chrome扩展程序的重大隐私政策更新 1月正式上线
英国开发出太阳能HAPS无人机
光电传感器和光纤传感器的区别是什么
智能巡检机器人提高了轨道系统运行的安全与稳定性
家电行业4家巨头占据半壁江山,盈利超10%
从PC中试验MAX6950和MAX6951 LED显示驱动器
CEVA-XM4图像和视觉 DSP 获得Linley Group评为“2015年最佳处理器IP”
从工具到“外脑”,手机进入真AI时代是否能够崛起?
倪光南院士:建议存储设备的政府采购、招标优先支持SSD而非机械硬盘
红外取暖器电路原理图
华为“1+8+N”全场景业务高速增长,TWS耳机实现了50%的同比增长
FFT和示波器:实用指南