嵌入式操作系统内核原理和开发(实时调度)_第1页
嵌入式操作系统内核原理和开发(实时调度)_第2页
嵌入式操作系统内核原理和开发(实时调度)_第3页
嵌入式操作系统内核原理和开发(实时调度)_第4页
嵌入式操作系统内核原理和开发(实时调度)_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、嵌入式操作系统内核原理和开发(实时调度) 和很多通用的操作系统相比, 实时操作系统有自己的一个特点,那就是实时调度。通用操作系统的线程优先级一般是可以变化的,而实时系统的线程优先级却是不变的。之所以这么设计,是为了保证高优先级的任务在第一时间获得调度,这样才能保证调度的实时性。因为实时系统是严格按照优先级搞定调度的,所以不管什么时候,我们只要寻找到最高优先级的任务即可。 rawos系统可以支持256个优先级,对任务的创建个数也没有限制,所以就会出现多个任务共享一个优先级的情况。因此系统本身对同优先级的任务分配了定额的时间片,一旦该任务时间片用完,就会被放到优先级的末尾,直到获得下一次的调度机会

2、,下面的代码就说明了这一情况,它是在时钟中断的时候被调度的,cpp view plaincopy1 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 = &raw_ready_queue.task_ready_listtask_ptr-priority; 10 11 RAW_CRITICAL_ENTER(); 12 13 if (is_list_empty(head) 14 15 RAW_C

3、RITICAL_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) 28 task_ptr-time_slice-; 29 30 31 /*if current active task has time_slice,

4、 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*/ 38 move_to_ready_list_end(&raw_ready_queue, task_ptr); 39 40 /*restore the task time slice*/ 41 task_ptr-time_slice = task_ptr-time_total

5、; 42 43 RAW_CRITICAL_EXIT(); 44 45 上面说的是一个优先级下面有多个任务的情况,如果优先级本身只有一个任务,那么就很抱歉了,下面还得继续运行这个任务。另外,我们在windows上面编程的时候喜欢暂时释放线程的运行权利,调用sleep(0)即可,那么这在rawos上是怎么实现的呢,cpp view plaincopy46 RAW_U16 raw_sleep(RAW_U32 dly) 47 48 RAW_U16 error_status; 49 50 RAW_SR_ALLOC(); 51 52 #if (RAW_TASK_FUNCTION_CHECK 0) 53 5

6、4 if (raw_int_nesting) 55 56 return RAW_NOT_CALLED_BY_ISR; 57 58 #endif 59 60 RAW_CRITICAL_ENTER(); 61 62 if (dly) 63 64 /*system is locked so task can not sleep just return immediately*/ 65 if (raw_sched_lock) 66 RAW_CRITICAL_EXIT(); 67 return RAW_SCHED_DISABLE; 68 69 70 raw_task_active-task_state

7、= RAW_DLY; 71 72 tick_list_insert(raw_task_active, dly); 73 74 remove_ready_list(&raw_ready_queue, raw_task_active); 75 76 77 else 78 /*make current task to the end of ready list*/ 79 move_to_ready_list_end(&raw_ready_queue, raw_task_active); 80 81 82 RAW_CRITICAL_EXIT(); 83 84 raw_sched(); 85 86 if

8、 (dly) 87 /*task is timeout after sleep*/ 88 error_status = block_state_post_process(raw_task_active, 0); 89 90 91 else 92 93 error_status = RAW_SUCCESS; 94 95 96 97 return error_status; 98 99 通过的上面的代码,我们可以看到其实系统啥也没干,只是把任务方法放到优先级的链表末尾了。因为我们的系统需要实时调度,所以即使把使用权出让出来,也不可能让低优先的任务运行,只能让同优先级的其他任务运行了。当然,同优先级

9、没有其他任务的时候,只好它自己继续玩了。说了这么多,我们看看系统是怎么调度的,cpp view plaincopy100 void raw_sched() 101 102 RAW_SR_ALLOC(); 103 104 /*if it is in interrupt or system is locked, just return*/ 105 if (raw_int_nesting | raw_sched_lock) 106 return; 107 108 109 RAW_CRITICAL_ENTER(); 110 111 112 get_ready_task(&raw_ready_queue

10、); 113 114 /*if highest task is currently task, then no need to do switch and just return*/ 115 if (high_ready_obj = raw_task_active) 116 RAW_CRITICAL_EXIT(); 117 return; 118 119 120 CONTEXT_SWITCH(); 121 RAW_CRITICAL_EXIT(); 122 123 124 这个函数看上去很长,其实最重要的部分就是get_ready_task这个函数,它的目的就是寻找到当前最高优先级下面的任务,大

11、家看看代码就明白了,cpp view plaincopy125 void get_ready_task(RAW_RUN_QUEUE *rq) 126 127 LIST *node ; 128 RAW_S32 highest_pri = rq-highest_priority; 129 /*Highest task must be the first element on the list*/ 130 node = rq-task_ready_listhighest_pri.next; 131 132 high_ready_obj = list_entry(node, RAW_TASK_OBJ,

12、 task_list); 133 134 所以,实时系统的核心就是寻找到那个最高优先级就可以了。在实时系统上面,我们一般用bitmap表示优先级,如果对应的优先级存在,那么该位置1,反之置0。那么什么情况下,会发生优先级的改变呢?其实就两种情况,一种是需要把任务加入调度队列的时候,还有一种就是把任务清除出调度队列的时候。cpp view plaincopy135 void add_ready_list(RAW_RUN_QUEUE *rq, RAW_TASK_OBJ *task_ptr) 136 137 /*if task priority is equal current task prior

13、ity then add to the end*/ 138 if (task_ptr-priority = raw_task_active-priority) 139 add_ready_list_end(rq, task_ptr); 140 141 /*if not add to the list front*/ 142 else 143 add_ready_list_head(rq, task_ptr); 144 145 146 147 148 149 void remove_ready_list(RAW_RUN_QUEUE *rq, RAW_TASK_OBJ *task_ptr) 150

14、 151 152 RAW_S32 i; 153 RAW_S32 priority = task_ptr-priority; 154 155 list_delete(&task_ptr-task_list); 156 157 /*if the ready list is not empty, we do not need to update the highest priority*/ 158 if (!is_list_empty(&rq-task_ready_listpriority) ) 159 return; 160 161 162 bit_clear(rq-task_bit_map, p

15、riority); 163 164 /*If task priority not equal to the highest priority, then we do not need to update the highest priority*/ 165 if (priority != rq-highest_priority) 166 return; 167 168 169 i = bit_search_first_one(rq-task_bit_map, priority, CONFIG_RAW_PRIO_MAX - priority); 170 /*Update the next hig

16、hest priority task*/ 171 if (i = 0) 172 rq-highest_priority = priority + i; 173 174 175 else 176 177 #if (CONFIG_RAW_ASSERT 0) 178 RAW_ASSERT(0); 179 #endif 180 181 182 183 184 加入调度队列的情况考虑的比较少,我们只需要判断当前的最高优先级和加入任务优先级之间的关系即可。如果新加入的任务优先级高,那么优先级发生了改变;反之什么也不需要做。反之删除任务则比较复杂一些,我们需要判断移除的任务是不是最高优先级,不是还好处理,如

17、果清除出去的任务正好是最高优先级,我们就需要从bitmap中寻找下一个最高优先级了,这个函数就是bit_search_first_one。函数第一个参数是bitmap数组,第二个参数是当前最高优先级,第三个参数是剩下的优先级总数,返回值为次优先级距离当前最高优先级的偏移值。cpp view plaincopy185 /*For 32 bit cpu*/ 186 RAW_S32 bit_search_first_one(RAW_U32 *base, RAW_S32 offset, RAW_S32 width) 187 188 register RAW_U32 *cp, v; 189 regist

18、er RAW_S32 position; 190 191 cp = base; 192 cp += offset 5; 193 194 if (offset & 31) 195 #if (CONFIG_RAW_LITTLE_ENDIAN 0) 196 v = *cp & (RAW_U32)1 (offset & 31) - 1); 197 #else 198 v = *cp & (RAW_U32)1 (32 - (offset & 31) - 1); 199 #endif 200 201 202 else 203 v = *cp; 204 205 206 position = 0; 207 w

19、hile (position search bit of 1 */ 209 if (!position) position -= (offset & 31); 210 211 #if (CONFIG_RAW_LITTLE_ENDIAN 0) 212 213 if (!(v & 0xffff) 214 v = 16; 215 position += 16; 216 217 if (!(v & 0xff) 218 v = 8; 219 position += 8; 220 221 if (!(v & 0xf) 222 v = 4; 223 position += 4; 224 225 if (!(v & 0x3) 226 v = 2; 227 position += 2; 228 229 if (!(v & 0x1) 230 +position; 231 232 233 #else 234 235 if (!(v & 0xffff0000) 236 v = 16; 237 position +=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论