《嵌入式操作系统内核原理和开发(实时调度)》由会员分享,可在线阅读,更多相关《嵌入式操作系统内核原理和开发(实时调度)(8页珍藏版)》请在金锄头文库上搜索。
1、本文由长春白癜风专科医院 http:/ 收集,转载请注明出处 本文由吉林白癜风医院 http:/ 收集,转载请注明出处 嵌入式操作系统内核原理和开发(实时调度)嵌入式操作系统内核原理和开发(实时调度) 和很多通用的操作系统相比, 实时操作系统有自己的一个特点,那就是实时调度。通用操作系统的线程优先级一般是可以变化的, 而实时系统的线程优先级却是不变的。 之所以这么设计,是为了保证高优先级的任务在第一时间获得调度,这样才能保证调度的实时性。因为实时系统是严格按照优先级搞定调度的, 所以不管什么时候, 我们只要寻找到最高优先级的任务即可。 rawos 系统可以支持 256 个优先级,对任务的创建个
2、数也没有限制,所以就会出现多个任务共享一个优先级的情况。 因此系统本身对同优先级的任务分配了定额的时间片, 一旦该任务时间片用完,就会被放到优先级的末尾,直到获得下一次的调度机会,下面的代码就说明了这一情况,它是在时钟中断的时候被调度的, cpp view plaincopy 1. void caculate_time_slice() 2. 3. RAW_TASK_OBJ *task_ptr; 4. LIST *head; 5. 6. RAW_SR_ALLOC(); 7. 8. task_ptr = raw_task_active; 9. head = 10. 11. RAW_CRITICAL
3、_ENTER(); 12. 13. if (is_list_empty(head) 14. 15. RAW_CRITICAL_EXIT(); 16. return; 17. 18. 19. /*there is only one task on this ready list, so do not need to caculate time slice*/ 20. if (head-next-next = head) 21. 22. RAW_CRITICAL_EXIT(); 23. return; 24. 25. 26. 27. if (task_ptr-time_slice) 本文由长春白癜
4、风专科医院 http:/ 收集,转载请注明出处 本文由吉林白癜风医院 http:/ 收集,转载请注明出处 28. task_ptr-time_slice-; 29. 30. 31. /*if current active task has time_slice, just return*/ 32. if (task_ptr-time_slice) 33. RAW_CRITICAL_EXIT(); 34. return; 35. 36. 37. /*Move current active task to the end of ready list for the same priority*/
5、38. move_to_ready_list_end( 39. 40. /*restore the task time slice*/ 41. task_ptr-time_slice = task_ptr-time_total; 42. 43. RAW_CRITICAL_EXIT(); 44. 45. 上面说的是一个优先级下面有多个任务的情况,如果优先级本身只有一个任务,那么就很抱歉了,下面还得继续运行这个任务。另外,我们在 windows 上面编程的时候喜欢暂时 释放线程的运行权利,调用 sleep(0)即可,那么这在 rawos 上是怎么实现的呢, cpp view plaincopy 1
6、. RAW_U16 raw_sleep(RAW_U32 dly) 2. 3. RAW_U16 error_status; 4. 5. RAW_SR_ALLOC(); 6. 7. #if (RAW_TASK_FUNCTION_CHECK 0) 8. 9. if (raw_int_nesting) 10. 11. return RAW_NOT_CALLED_BY_ISR; 12. 13. #endif 14. 15. RAW_CRITICAL_ENTER(); 16. 17. if (dly) 18. 19. /*system is locked so task can not sleep jus
7、t return immediately*/ 本文由长春白癜风专科医院 http:/ 收集,转载请注明出处 本文由吉林白癜风医院 http:/ 收集,转载请注明出处 20. if (raw_sched_lock) 21. RAW_CRITICAL_EXIT(); 22. return RAW_SCHED_DISABLE; 23. 24. 25. raw_task_active-task_state = RAW_DLY; 26. 27. tick_list_insert(raw_task_active, dly); 28. 29. remove_ready_list( 30. 31. 32. e
8、lse 33. /*make current task to the end of ready list*/ 34. move_to_ready_list_end( 35. 36. 37. RAW_CRITICAL_EXIT(); 38. 39. raw_sched(); 40. 41. if (dly) 42. /*task is timeout after sleep*/ 43. error_status = block_state_post_process(raw_task_active, 0); 44. 45. 46. else 47. 48. error_status = RAW_S
9、UCCESS; 49. 50. 51. 52. return error_status; 53. 54. 通过的上面的代码,我们可以看到其实系统啥也没干,只是把任务方法放到优先级的链 表末尾了。因为我们的系统需要实时调度,所以即使把使用权出让出来,也不可能让低优先 的任务运行,只能让同优先级的其他任务运行了。当然,同优先级没有其他任务的时候,只好它自己继续玩了。说了这么多,我们看看系统是怎么调度的, cpp view plaincopy 1. void raw_sched() 2. 本文由长春白癜风专科医院 http:/ 收集,转载请注明出处 本文由吉林白癜风医院 http:/ 收集,转载请注
10、明出处 3. RAW_SR_ALLOC(); 4. 5. /*if it is in interrupt or system is locked, just return*/ 6. if (raw_int_nesting | raw_sched_lock) 7. return; 8. 9. 10. RAW_CRITICAL_ENTER(); 11. 12. 13. get_ready_task( 14. 15. /*if highest task is currently task, then no need to do switch and just return*/ 16. if (hig
11、h_ready_obj = raw_task_active) 17. RAW_CRITICAL_EXIT(); 18. return; 19. 20. 21. CONTEXT_SWITCH(); 22. RAW_CRITICAL_EXIT(); 23. 24. 25. 这个函数看上去很长,其实最重要的部分就是 get_ready_task 这个函数,它的目的就是 寻找到当前最高优先级下面的任务,大家看看代码就明白了, cpp view plaincopy 1. void get_ready_task(RAW_RUN_QUEUE *rq) 2. 3. LIST *node ; 4. RAW_S3
12、2 highest_pri = rq-highest_priority; 5. /*Highest task must be the first element on the list*/ 6. node = rq-task_ready_listhighest_pri.next; 7. 8. high_ready_obj = list_entry(node, RAW_TASK_OBJ, task_list); 9. 10. 所以,实时系统的核心就是寻找到那个最高优先级就可以了。在实时系统上面,我们一 般用 bitmap 表示优先级,如果对应的优先级存在,那么该位置 1,反之置 0。那么什么情况下,会发生优先级的改变呢?其实就两种情况,一种是需要把任务加入调度队列的时候, 还有一种就是把任务清除出调度队列的时候。 cpp view plaincopy 本文由长春白癜风专科医院 http:/