[原创] HELPER2416学习笔记7——RAW-OS之任务创建、调度、挂起及恢复

fjjjnk1234   2014-8-10 19:44 楼主
HELPER2416学习笔记7——RAW-OS之任务创建、调度、挂起及恢复
参与HELPER2416开发板助学计划
RAW-OS是国内一个优秀的嵌入式硬实时操作系统,吸取了世界多个操作系统的优秀特性,并且具有许多创新特性,已经完成了在多个CPU平台上的移植,在官网上都能找到移植的例子,关于RAW-OS的介绍,大家可看这个帖子https://bbs.eeworld.com.cn/thread-418007-1-2.html
RAW-OS属于硬实时操作系统,硬实时和软实时操作系统的区别在于对处理过程超时以及由于超时带来的后果的容忍度。对于硬实时系统,在超过了允许的时间之后,即使还能得到正确的结果,也是不能容忍的。接着通过一个简单的例子分享RAW-OS操作系统任务的创建、调度、挂起及恢复。
(1) 在调用任何其它RAW-OS的服务函数之前,必须先调用raw_os_init()进行RAW-OS的初始化。
(2) 接着通过raw_task_create()函数创建一个LED灯亮的任务。
  1. 任务创建函数:
  2. RAW_U16 raw_task_create(RAW_TASK_OBJ *task_obj, RAW_U8 *task_name, RAW_VOID *task_arg,
  3. RAW_U8 task_prio, RAW_U32 time_slice, PORT_STACK *task_stack_base,
  4. RAW_U32 stack_size, RAW_TASK_ENTRY task_entry, RAW_U8 auto_start)
raw_task_create()一共有9个参数:
task_obj为任务控制块的地址。(任务控制块是内核使用的一种数据结构,用来维护任务相关的信息)
task_name为任务的名字(随便取)
task_arg为任务要传递的参数
task_prio为任务的优先级( 数值越小,优先级越高,优先级0以及空闲任务的优先级只允许有一个。)
time_slice为分配给任务的时间片(通过时间片轮转调度可以使两个或多个拥有相同的优先级的任务,一个运行一段指定的时间(即时间片),然后轮到下一个任务运行,如此循环)
task_stack_base为任务的栈底地址(任务堆栈的声明方式:PORT_STACK MY_TASK_STK[TASK_STK_SIZE];)
stack_size为栈空间大小。
task_entry为任务的入口函数。(任务的函数名)
auto_start为任务是否创建后就进入就绪状态。(非0为是,0为否)
在主函数中创建的2个任务:LED灯亮和LED灯灭
  1. raw_task_create(&LED_ON_OBJ,
  2. (RAW_U8 *)"LED_ON",
  3. 0,
  4. LED_ON_TASK_PRIO ,
  5. 0,
  6. LED_ON_TASK_STK,
  7. LED_ON_STK_SIZE,
  8. led_on_task,
  9. 1);
  10. raw_task_create(&LED_OFF_OBJ,
  11. (RAW_U8 *)"LED_OFF",
  12. 0,
  13. LED_OFF_TASK_PRIO ,
  14. 0,
  15. LED_OFF_TASK_STK,
  16. LED_OFF_STK_SIZE,
  17. led_off_task,
  18. 1);
接着调用raw_os_start();启动RAW-OS多任务管理系统,RAW-OS默认配置为多任务的抢占型内核,系统中永远运行最高优先级的就绪任务(通过raw_disable_sche()函数可以关掉系统抢占,不过关了就不能保证系统的实时性了),由于LED灯亮的任务优先级高于LED灯灭任务的优先级,两个任务均在就绪状态,所以执行LED灯亮的任务。LED灯亮任务函数:
  1. void led_on_task(void *arg)
  2. {
  3. while(1)
  4. {
  5. GPBDAT_REG = 0x00000000;
  6. delay(0x1000000);
  7. raw_task_suspend(&LED_ON_OBJ);
  8. }
  9. }
即点亮LED灯,延长一段时间后,之后通过raw_task_suspend()函数将LED灯亮的任务挂起(函数参数就是任务控制块的地址,任务挂起只是将被挂起任务的就绪标志删除)。此时LED灯灭的任务处于就绪状态,执行LED灯灭任务。LED灯灭任务函数:
  1. void led_off_task(void *arg)
  2. {
  3. while(1)
  4. {
  5. GPBDAT_REG = 0x00000002;
  6. delay(0x1000000);
  7. raw_task_resume(&LED_ON_OBJ);
  8. }
  9. }
在LED灯灭的任务函数中,先让LED灯灭,延时一段时间,接着恢复LED灯亮任务(即重新使LED灯亮任务就绪),由于LED灯亮的任务优先级高于LED灯灭任务的优先级,此时执行LED灯亮的任务,如此循环。这样LED灯亮和LED灯灭两个任务不断调度,LED灯亮任务不断挂起及恢复,实现LED灯的闪烁。连接J-Link——Debug——全速运行,就能看的LED灯闪烁的现象。
test.rar (1.97 MB)
(下载次数: 15, 2014-8-10 19:48 上传)
论坛ID:fjjjnk1234
提交时间:2014.08.10
本帖最后由 fjjjnk1234 于 2014-8-10 20:22 编辑
相由心生,境随心转,一切法从心想生。

回复评论 (4)

严重支持,希望楼主以后会继续这样的实验。
点赞  2014-8-10 20:10
写得很好。赞
点赞  2014-8-12 09:48
对于硬实时系统,在超过了允许的时间之后,即使还能得到正确的结果,也是不能容忍的
中空板|防静电中空板www.cheng-sen.com
点赞  2014-8-13 09:06
这么好的帖子没加精?
点赞  2014-8-18 15:13
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复