source: rtos_arduino/trunk/asp_1.9.2/kernel/task.c@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

File size: 12.4 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者
12は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * スコード中に含まれていること.
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再é…
21å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
22å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
23 * 者
24マニュアルなど)に,上記の著作権表示,この利用条件および下記
25 * の無保証規定を掲載すること.
26 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27 * 用できない形で再é…
28å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
29 * と.
30 * (a) 再é…
31å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
32マニュアルなど)に,上記の著
33 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
34 * (b) 再é…
35å¸ƒã®å½¢æ…
36‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
37 * 報告すること.
38 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
39 * 害からも,上記著作権者
40およびTOPPERSプロジェクトをå…
41è²¬ã™ã‚‹ã“と.
42 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
43 * 由に基づく請求からも,上記著作権者
44およびTOPPERSプロジェクトを
45 * å…
46è²¬ã™ã‚‹ã“と.
47 *
48 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
49お
50 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
51 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
52 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
53 * の責任を負わない.
54 *
55 * $Id: task.c 2248 2011-08-30 01:05:11Z ertl-hiro $
56 */
57
58/*
59 * タスク管理モジュール
60 */
61
62#include "kernel_impl.h"
63#include "wait.h"
64#include "task.h"
65
66/*
67 * トレースログマクロのデフォルト定義
68 */
69#ifndef LOG_TEX_ENTER
70#define LOG_TEX_ENTER(p_tcb, texptn)
71#endif /* LOG_TEX_ENTER */
72
73#ifndef LOG_TEX_LEAVE
74#define LOG_TEX_LEAVE(p_tcb)
75#endif /* LOG_TEX_LEAVE */
76
77#ifdef TOPPERS_tskini
78
79/*
80 * 実行状æ…
81‹ã®ã‚¿ã‚¹ã‚¯
82 */
83TCB *p_runtsk;
84
85/*
86 * 最高優å…
87ˆé †ä½ã®ã‚¿ã‚¹ã‚¯
88 */
89TCB *p_schedtsk;
90
91/*
92 * タスクディスパッチ/タスク例外処理ルーチン起動要求フラグ
93 */
94bool_t reqflg;
95
96/*
97 * 割込み優å…
98ˆåº¦ãƒžã‚¹ã‚¯å…
99¨è§£é™¤çŠ¶æ…
100‹
101 */
102bool_t ipmflg;
103
104/*
105 * ディスパッチ禁止状æ…
106‹
107 */
108bool_t disdsp;
109
110/*
111 * タスクディスパッチ可能状æ…
112‹
113 */
114bool_t dspflg;
115
116/*
117 * レディキュー
118 */
119QUEUE ready_queue[TNUM_TPRI];
120
121/*
122 * レディキューサーチのためのビットマップ
123 */
124uint16_t ready_primap;
125
126/*
127 * タスク管理モジュールの初期化
128 */
129void
130initialize_task(void)
131{
132 uint_t i, j;
133 TCB *p_tcb;
134
135 p_runtsk = NULL;
136 p_schedtsk = NULL;
137 reqflg = false;
138 ipmflg = true;
139 disdsp = false;
140 dspflg = true;
141
142 for (i = 0; i < TNUM_TPRI; i++) {
143 queue_initialize(&(ready_queue[i]));
144 }
145 ready_primap = 0U;
146
147 for (i = 0; i < tnum_tsk; i++) {
148 j = INDEX_TSK(torder_table[i]);
149 p_tcb = &(tcb_table[j]);
150 p_tcb->p_tinib = &(tinib_table[j]);
151 p_tcb->actque = false;
152 make_dormant(p_tcb);
153 if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
154 (void) make_active(p_tcb);
155 }
156 }
157}
158
159#endif /* TOPPERS_tskini */
160
161/*
162 * ビットマップサーチ関数
163 *
164 * bitmap内
165の1のビットの内
166,最も下位(右)のものをサーチし,そのビッ
167 * ト番号を返す.ビット番号は,最下位ビットを0とする.bitmapに0を指定
168 * してはならない.この関数では,bitmapが16ビットであることを仮定し,
169 * uint16_t型としている.
170 *
171 * ビットサーチ命令を持つプロセッサでは,ビットサーチ命令を使うように
172 * 書き直した方が効率が良い場合がある.このような場合には,ターゲット
173 * 依存部でビットサーチ命令を使ったbitmap_searchを定義し,
174 * OMIT_BITMAP_SEARCHをマクロ定義すればよい.また,ビットサーチ命令の
175 * サーチ方向が逆などの理由で優å…
176ˆåº¦ã¨ãƒ“ットとの対応を変更したい場合に
177 * は,PRIMAP_BITをマクロ定義すればよい.
178 *
179 * また,ライブラリにffsがあるなら,次のように定義してライブラリ関数を
180 * 使った方が効率が良い可能性もある.
181 * #define bitmap_search(bitmap) (ffs(bitmap) - 1)
182 */
183#ifndef PRIMAP_BIT
184#define PRIMAP_BIT(pri) (1U << (pri))
185#endif /* PRIMAP_BIT */
186
187#ifndef OMIT_BITMAP_SEARCH
188
189static const unsigned char bitmap_search_table[] = { 0, 1, 0, 2, 0, 1, 0,
190 3, 0, 1, 0, 2, 0, 1, 0 };
191
192Inline uint_t
193bitmap_search(uint16_t bitmap)
194{
195 uint_t n = 0U;
196
197 assert(bitmap != 0U);
198 if ((bitmap & 0x00ffU) == 0U) {
199 bitmap >>= 8;
200 n += 8;
201 }
202 if ((bitmap & 0x0fU) == 0U) {
203 bitmap >>= 4;
204 n += 4;
205 }
206 return(n + bitmap_search_table[(bitmap & 0x0fU) - 1]);
207}
208
209#endif /* OMIT_BITMAP_SEARCH */
210
211/*
212 * 優å…
213ˆåº¦ãƒ“ットマップが空かのチェック
214 */
215Inline bool_t
216primap_empty(void)
217{
218 return(ready_primap == 0U);
219}
220
221/*
222 * 優å…
223ˆåº¦ãƒ“ットマップのサーチ
224 */
225Inline uint_t
226primap_search(void)
227{
228 return(bitmap_search(ready_primap));
229}
230
231/*
232 * 優å…
233ˆåº¦ãƒ“ットマップのセット
234 */
235Inline void
236primap_set(uint_t pri)
237{
238 ready_primap |= PRIMAP_BIT(pri);
239}
240
241/*
242 * 優å…
243ˆåº¦ãƒ“ットマップのクリア
244 */
245Inline void
246primap_clear(uint_t pri)
247{
248 ready_primap &= ~PRIMAP_BIT(pri);
249}
250
251/*
252 * 最高優å…
253ˆé †ä½ã‚¿ã‚¹ã‚¯ã®ã‚µãƒ¼ãƒ
254 */
255#ifdef TOPPERS_tsksched
256
257TCB *
258search_schedtsk(void)
259{
260 uint_t schedpri;
261
262 schedpri = primap_search();
263 return((TCB *)(ready_queue[schedpri].p_next));
264}
265
266#endif /* TOPPERS_tsksched */
267
268/*
269 * 実行できる状æ…
270‹ã¸ã®é·ç§»
271 *
272 * 最高優å…
273ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã‚’更新するのは,実行できるタスクがなかった場合
274 * と,p_tcbの優å…
275ˆåº¦ãŒæœ€é«˜å„ªå…
276ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã®å„ªå…
277ˆåº¦ã‚ˆã‚Šã‚‚高い場合であ
278 * る.
279 */
280#ifdef TOPPERS_tskrun
281
282bool_t
283make_runnable(TCB *p_tcb)
284{
285 uint_t pri = p_tcb->priority;
286
287 queue_insert_prev(&(ready_queue[pri]), &(p_tcb->task_queue));
288 primap_set(pri);
289
290 if (p_schedtsk == (TCB *) NULL || pri < p_schedtsk->priority) {
291 p_schedtsk = p_tcb;
292 return(dspflg);
293 }
294 return(false);
295}
296
297#endif /* TOPPERS_tskrun */
298
299/*
300 * 実行できる状æ…
301‹ã‹ã‚‰ä»–の状æ…
302‹ã¸ã®é·ç§»
303 *
304 * 最高優å…
305ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã‚’更新するのは,p_tcbが最高優å…
306ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã§
307 * あった場合である.p_tcbと同じ優å…
308ˆåº¦ã®ã‚¿ã‚¹ã‚¯ãŒä»–にある場合は,p_tcb
309 * の次のタスクが最高優å…
310ˆé †ä½ã«ãªã‚‹ï¼Žãã†ã§ãªã„場合は,レディキューを
311 * サーチする必
312要がある.
313 */
314#ifdef TOPPERS_tsknrun
315
316bool_t
317make_non_runnable(TCB *p_tcb)
318{
319 uint_t pri = p_tcb->priority;
320 QUEUE *p_queue = &(ready_queue[pri]);
321
322 queue_delete(&(p_tcb->task_queue));
323 if (queue_empty(p_queue)) {
324 primap_clear(pri);
325 if (p_schedtsk == p_tcb) {
326 p_schedtsk = primap_empty() ? (TCB *) NULL : search_schedtsk();
327 return(dspflg);
328 }
329 }
330 else {
331 if (p_schedtsk == p_tcb) {
332 p_schedtsk = (TCB *)(p_queue->p_next);
333 return(dspflg);
334 }
335 }
336 return(false);
337}
338
339#endif /* TOPPERS_tsknrun */
340
341/*
342 * 休止状æ…
343‹ã¸ã®é·ç§»
344 */
345#ifdef TOPPERS_tskdmt
346
347void
348make_dormant(TCB *p_tcb)
349{
350 p_tcb->tstat = TS_DORMANT;
351 p_tcb->priority = p_tcb->p_tinib->ipriority;
352 p_tcb->wupque = false;
353 p_tcb->enatex = false;
354 p_tcb->texptn = 0U;
355 LOG_TSKSTAT(p_tcb);
356}
357
358#endif /* TOPPERS_tskdmt */
359
360/*
361 * 休止状æ…
362‹ã‹ã‚‰å®Ÿè¡Œã§ãã‚‹çŠ¶æ…
363‹ã¸ã®é·ç§»
364 */
365#ifdef TOPPERS_tskact
366
367bool_t
368make_active(TCB *p_tcb)
369{
370 activate_context(p_tcb);
371 p_tcb->tstat = TS_RUNNABLE;
372 LOG_TSKSTAT(p_tcb);
373 return(make_runnable(p_tcb));
374}
375
376#endif /* TOPPERS_tskact */
377
378/*
379 * タスクの優å…
380ˆåº¦ã®å¤‰æ›´
381 *
382 * タスクが実行できる状æ…
383‹ã®å ´åˆã«ã¯ï¼Œãƒ¬ãƒ‡ã‚£ã‚­ãƒ¥ãƒ¼ã®ä¸­ã§ã®ä½ç½®ã‚’変更す
384 * る.オブジェクトの待
385ちキューの中で待
386ち状æ…
387‹ã«ãªã£ã¦ã„る場合には,待
388
389 * ちキューの中での位置を変更する.
390 *
391 * 最高優å…
392ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã‚’更新するのは,(1) p_tcbが最高優å…
393ˆé †ä½ã®ã‚¿ã‚¹
394 * クであって,その優å…
395ˆåº¦ã‚’下げた場合,(2) p_tcbが最高優å…
396ˆé †ä½ã®ã‚¿ã‚¹
397 * クではなく,変更後の優å…
398ˆåº¦ãŒæœ€é«˜å„ªå…
399ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã®å„ªå…
400ˆåº¦ã‚ˆã‚Šã‚‚高い
401 * 場合である.(1)の場合には,レディキューをサーチする必
402要がある.
403 */
404#ifdef TOPPERS_tskpri
405
406bool_t
407change_priority(TCB *p_tcb, uint_t newpri)
408{
409 uint_t oldpri;
410
411 oldpri = p_tcb->priority;
412 p_tcb->priority = newpri;
413
414 if (TSTAT_RUNNABLE(p_tcb->tstat)) {
415 /*
416 * タスクが実行できる状æ…
417‹ã®å ´åˆ
418 */
419 queue_delete(&(p_tcb->task_queue));
420 if (queue_empty(&(ready_queue[oldpri]))) {
421 primap_clear(oldpri);
422 }
423 queue_insert_prev(&(ready_queue[newpri]), &(p_tcb->task_queue));
424 primap_set(newpri);
425
426 if (p_schedtsk == p_tcb) {
427 if (newpri >= oldpri) {
428 p_schedtsk = search_schedtsk();
429 return(p_schedtsk != p_tcb && dspflg);
430 }
431 }
432 else {
433 if (newpri < p_schedtsk->priority) {
434 p_schedtsk = p_tcb;
435 return(dspflg);
436 }
437 }
438 }
439 else {
440 if (TSTAT_WAIT_WOBJCB(p_tcb->tstat)) {
441 /*
442 * タスクが,同期・通信オブジェクトの管理ブロックのå…
443±é€šéƒ¨
444 * 分(WOBJCB)の待
445ちキューにつながれている場合
446 */
447 wobj_change_priority(((WINFO_WOBJ *)(p_tcb->p_winfo))->p_wobjcb,
448 p_tcb);
449 }
450 }
451 return(false);
452}
453
454#endif /* TOPPERS_tskpri */
455
456/*
457 * レディキューの回転
458 *
459 * 最高優å…
460ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ã‚’更新するのは,最高優å…
461ˆé †ä½ã®ã‚¿ã‚¹ã‚¯ãŒã‚¿ã‚¹ã‚¯ã‚­
462 * ューの末尾に移動した場合である.
463 */
464#ifdef TOPPERS_tskrot
465
466bool_t
467rotate_ready_queue(uint_t pri)
468{
469 QUEUE *p_queue = &(ready_queue[pri]);
470 QUEUE *p_entry;
471
472 if (!queue_empty(p_queue) && p_queue->p_next->p_next != p_queue) {
473 p_entry = queue_delete_next(p_queue);
474 queue_insert_prev(p_queue, p_entry);
475 if (p_schedtsk == (TCB *) p_entry) {
476 p_schedtsk = (TCB *)(p_queue->p_next);
477 return(dspflg);
478 }
479 }
480 return(false);
481}
482
483#endif /* TOPPERS_tskrot */
484
485/*
486 * タスク例外処理ルーチンの呼出し
487 *
488 * ASPカーネルでは,タスク例外処理ルーチン内
489でCPUロック状æ…
490‹ã«é·ç§»ã—,
491 * å…
492ƒã®çŠ¶æ…
493‹ã«æˆ»ã•ãšã«ãƒªã‚¿ãƒ¼ãƒ³ã—た場合,カーネルがå…
494ƒã®çŠ¶æ…
495‹ã«æˆ»ã™ï¼Ž
496 */
497#ifdef TOPPERS_tsktex
498
499void
500call_texrtn(void)
501{
502 TEXPTN texptn;
503 bool_t saved_disdsp;
504
505 saved_disdsp = disdsp;
506 p_runtsk->enatex = false;
507 do {
508 texptn = p_runtsk->texptn;
509 p_runtsk->texptn = 0U;
510
511 t_unlock_cpu();
512 LOG_TEX_ENTER(p_runtsk, texptn);
513 (*((TEXRTN)(p_runtsk->p_tinib->texrtn)))(texptn,
514 p_runtsk->p_tinib->exinf);
515 LOG_TEX_LEAVE(p_runtsk);
516 if (!t_sense_lock()) {
517 t_lock_cpu();
518 }
519 if (!ipmflg) {
520 t_set_ipm(TIPM_ENAALL);
521 ipmflg = true;
522 }
523 disdsp = saved_disdsp;
524 dspflg = !disdsp;
525 p_runtsk->enatex = false;
526 if (p_runtsk != p_schedtsk && dspflg) {
527 /*
528 * ここでdispatchを呼び出す処理は,相互再帰呼出しになって
529 * いるが,dispatchを呼ぶ前にp_runtsk->enatexをfalseにして
530 * おけば支障がない.その理由については,「TOPPERS/ASP カー
531 * ネル 設計メモ」を参ç…
532§ã®ã“と.
533 */
534 dispatch();
535 }
536 } while (p_runtsk->texptn != 0U);
537 p_runtsk->enatex = true;
538}
539
540/*
541 * タスク例外処理ルーチンの起動
542 */
543#ifndef OMIT_CALLTEX
544
545void
546calltex(void)
547{
548 if (p_runtsk->enatex && p_runtsk->texptn != 0U && ipmflg) {
549 call_texrtn();
550 }
551}
552
553#endif /* OMIT_CALLTEX */
554#endif /* TOPPERS_tsktex */
Note: See TracBrowser for help on using the repository browser.