本帖最后由 summarize 于 2013-5-19 14:47 编辑
废话少说,先上stm8s103 IAR库工程代码压缩包。
Schedule-IAR-STM8S103.rar
(416.35 KB, 下载次数: 538)
2013-5-19 14:15 上传
点击文件名下载附件
工程是在stm8s103f3单片机上调度通过,已经用消息实现了 UART1_TX模块的共享,即UART1_RX接收到的数据+0x11后再通过UART_TX模块发送回去,同时ADC1 通道3的转换结果也通过UART1_TX模块发送出去.见下图
1.ADC1转换结果每1秒上传一次到PC。测试式给ADC1通道3供的是5V电,所以结果是0x03ff.即1023.
共享时接收到的数据.png (61.3 KB, 下载次数: 0)
下载附件
2013-5-19 14:16 上传
3.支持非抢占式优先级调度,优先级顺序就是创建任务时的顺序,由高到底。其实现思想是,每一个任务运行结束后,都重新回到第一个创建的任务处按顺序查找某个任务是否满足运行条件,所以先创建的任务会先被“发现”其满足运行条件并运行之,核心代码如下
a.任务控制块数据结构
- struct SchTcb
- {
- #if SCH_CFG_Q_EN > 0u
- void *pData; //消息指针
- SCH_UINT8 Size; //消息大小
- #endif
- SCH_DLY_TYPE TimeCounter; //定时计数器,时基为 "SCH_SYS_TICKS_MS"
- void (*pTask)(); //任务指针
- struct SchTcb *pNextTCB; //下一个任务控制块指针
- };
复制代码b.调度核心
- void SCHTaskSchedStart(void)
- {
- SCHED_SART:
-
- pCurTCB = pFirstTCB; //指向第一个创建的任务,之后按创建时的顺序执行下去
- while (1)
- {
- SCHTimeTick(); //如果任务Tick满足条件,则将其置于可执行状态
- if (SCH_TASK_RUN == pCurTCB->TimeCounter) //任务处于可执行状态
- {
- pCurTCB->TimeCounter = SCH_TASK_PEND; //设置为挂起状态,保证任务只执行一次
- pCurTCB->pTask(); //执行当前任务控制块指向的任务
- goto SCHED_SART; //每执行完一个任务,都重新查找一次可执行最高优先级任务
- }
- pCurTCB = pCurTCB->pNextTCB; //指向下一个任务控制块,查找下个任务是否可执行
- }
- }
复制代码“schedule.c”和"schedule.h"已经设置为只读属性,无特殊情况不建议修改,"sch_cfg.h"则为开放给用户的接口,可定义数据类型、调度器节拍和配置是否使用消息。
本人水平有限,欢迎大家测试、指正不足。
这里补充说明一下为什么要做支持优先级的调度:
之前手里有一个项目有多个任务,main函数简述如下
void main(void)
{
SystemInit();
whiile(1)
{
Task1();////经测试执行最长时间约0.8ms
Task2();//经测试执行最长时间约1.2ms
Task3();//经测试执行最长时间约0.9ms
Task4();//经测试执行最长时间约1.5ms
}
}
如Task1为通信数据处理任务(数据在中断中接收并放到缓冲区等待处理),要求最慢响应时间是2ms,那么如果是按照常规的顺序执行,则其它三个任务的最大执行时间(1.2+0.9+1.5)>2ms,则数据会丢失.
当时的临时解决办法是,在Task2(),Task3()后面都多调用一次Task1(),即变成下面这样:
void main(void)
{
SystemInit();
whiile(1)
{
Task1();////经测试执行最长时间约0.8ms
Task2();//经测试执行最长时间约1.2ms
Task1();////经测试执行最长时间约0.8ms
Task3();//经测试执行最长时间约0.9ms
Task1();////经测试执行最长时间约0.8ms
Task4();//经测试执行最长时间约1.5ms
}
}
显然,问题得到解决,但是main函数的简洁性被破坏,显示得有点杂乱了.而且只有Task1()取得了最高优先级,其它任务还是按原来那样顺序执行;所以后来就有了做一个支持优先级的非抢占式调度器,可以支持配置所有任务的优先级.
一周热门 更多>