source: atk2-sc3-1.4.0-ntisr/kernel/task.c

Last change on this file was 172, checked in by ertl-ishikawa, 8 years ago

ATK2-SC3 1.4.0 RH850依存部 非信頼C2ISR対応を追加

  • Property svn:executable set to *
File size: 16.2 KB
Line 
1/*
2 * TOPPERS ATK2
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 * Automotive Kernel Version 2
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2004-2015 by Center for Embedded Computing Systems
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 * Copyright (C) 2011-2015 by FUJI SOFT INCORPORATED, JAPAN
11 * Copyright (C) 2011-2013 by Spansion LLC, USA
12 * Copyright (C) 2011-2015 by NEC Communication Systems, Ltd., JAPAN
13 * Copyright (C) 2011-2015 by Panasonic Advanced Technology Development Co., Ltd., JAPAN
14 * Copyright (C) 2011-2014 by Renesas Electronics Corporation, JAPAN
15 * Copyright (C) 2011-2015 by Sunny Giken Inc., JAPAN
16 * Copyright (C) 2011-2015 by TOSHIBA CORPORATION, JAPAN
17 * Copyright (C) 2004-2015 by Witz Corporation
18 * Copyright (C) 2014-2015 by AISIN COMCRUISE Co., Ltd., JAPAN
19 * Copyright (C) 2014-2015 by eSOL Co.,Ltd., JAPAN
20 * Copyright (C) 2014-2015 by SCSK Corporation, JAPAN
21 * Copyright (C) 2015 by SUZUKI MOTOR CORPORATION
22 *
23 * 上記著作権者
24は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
25 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
26 * 変・再é…
27å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
28 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
29 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
30 * スコード中に含まれていること.
31 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
32 * 用できる形で再é…
33å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
34å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
35 * 者
36マニュアルなど)に,上記の著作権表示,この利用条件および下記
37 * の無保証規定を掲載すること.
38 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
39 * 用できない形で再é…
40å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
41 * と.
42 * (a) 再é…
43å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
44マニュアルなど)に,上記の著
45 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
46 * (b) 再é…
47å¸ƒã®å½¢æ…
48‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
49 * 報告すること.
50 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
51 * 害からも,上記著作権者
52およびTOPPERSプロジェクトをå…
53è²¬ã™ã‚‹ã“と.
54 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
55 * 由に基づく請求からも,上記著作権者
56およびTOPPERSプロジェクトを
57 * å…
58è²¬ã™ã‚‹ã“と.
59 *
60 * 本ソフトウェアは,AUTOSAR(AUTomotive Open System ARchitecture)仕
61 * 様に基づいている.上記の許諾は,AUTOSARの知的財産権を許諾するもので
62 * はない.AUTOSARは,AUTOSAR仕様に基づいたソフトウェアを商用目的で利
63 * 用する者
64に対して,AUTOSARパートナーになることを求めている.
65 *
66 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
67お
68 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
69 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
70 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
71 * の責任を負わない.
72 *
73 * $Id: task.c 425 2015-12-07 08:06:19Z witz-itoyo $
74 */
75
76/*
77 * タスク制御モジュール
78 */
79
80#include "kernel_impl.h"
81#include "check.h"
82#include "task.h"
83#include "interrupt.h"
84
85/*
86 * トレースログマクロのデフォルト定義
87 */
88#ifndef LOG_TSKSTAT
89#define LOG_TSKSTAT(p_tcb)
90#endif /* LOG_TSKSTAT */
91
92/* 内
93部関数のプロトタイプ宣言 */
94LOCAL_INLINE uint16 bitmap_search(uint16 bitmap);
95LOCAL_INLINE boolean primap_empty(void);
96LOCAL_INLINE PriorityType primap_search(void);
97LOCAL_INLINE void primap_set(PriorityType pri);
98LOCAL_INLINE void primap_clear(PriorityType pri);
99
100#ifdef TOPPERS_task_initialize
101
102/*
103 * 実行状æ…
104‹ã®ã‚¿ã‚¹ã‚¯
105 */
106TCB *p_runtsk;
107
108/*
109 * 最高優å…
110ˆé †ä½ã‚¿ã‚¹ã‚¯
111 */
112TCB *p_schedtsk;
113
114/*
115 * レディキュー中の最高優å…
116ˆåº¦
117 */
118PriorityType nextpri;
119
120/*
121 * レディキュー
122 */
123QUEUE ready_queue[TNUM_TPRI];
124
125/*
126 * レディキューサーチのためのビットマップ
127 */
128uint16 ready_primap;
129
130/*
131 * タスク管理モジュールの初期化
132 */
133void
134task_initialize(void)
135{
136 TaskType i;
137 TCB *p_tcb;
138
139 p_runtsk = NULL;
140 p_schedtsk = NULL;
141
142 for (i = 0U; i < TNUM_TPRI; i++) {
143 queue_initialize(&(ready_queue[i]));
144 }
145 nextpri = TPRI_MINTASK;
146 ready_primap = 0U;
147
148 for (i = 0U; i < tnum_task; i++) {
149 p_tcb = &(tcb_table[i]);
150 p_tcb->p_tinib = &(tinib_table[i]);
151 p_tcb->actcnt = 0U;
152 p_tcb->tstat = SUSPENDED;
153#ifdef CFG_USE_PROTECTIONHOOK
154 p_tcb->calltfn = FALSE;
155#endif /* CFG_USE_PROTECTIONHOOK */
156 if ((p_tcb->p_tinib->autoact & ((AppModeType) 1 << appmodeid)) != APPMODE_NONE) {
157 (void) make_active(p_tcb);
158 }
159 }
160}
161
162#endif /* TOPPERS_task_initialize */
163
164/*
165 * ビットマップサーチ関数
166 *
167 * bitmap内
168の1のビットの内
169,最も下位(右)のものをサーチし,そのビッ
170 * ト番号を返す
171 * ビット番号は,最下位ビットを0とする.bitmapに0を指定
172 * してはならない.この関数では,bitmapが16ビットであることを仮定し,
173 * uint16型としている
174 *
175 * ビットサーチ命令を持つプロセッサでは,ビットサーチ命令を使うように
176 * 書き直した方が効率が良い場合がある
177 * このような場合には,ターゲット依存部でビットサーチ命令を使った
178 * bitmap_searchを定義し,OMIT_BITMAP_SEARCHをマクロ定義すればよい
179 * また,ビットサーチ命令のサーチ方向が逆などの理由で優å…
180ˆåº¦ã¨ãƒ“ット
181 * との対応を変更したい場合には,PRIMAP_BITをマクロ定義すればよい
182 *
183 * また,標準ライブラリにffsがあるなら,次のように定義して標準ライブ
184 * ラリを使った方が効率が良い可能性もある
185 * #define bitmap_search(bitmap) (ffs(bitmap) - 1)
186 */
187#ifndef PRIMAP_BIT
188#define PRIMAP_BIT(pri) ((uint16) ((uint16) 1U << (pri)))
189#endif /* PRIMAP_BIT */
190
191#ifndef OMIT_BITMAP_SEARCH
192
193LOCAL_INLINE uint16
194bitmap_search(uint16 bitmap)
195{
196 /*
197 * ビットマップサーチ関数用テーブル
198 */
199 const uint8 bitmap_search_table[BITMAP_NUM] = {
200 0U, 1U, 0U, 2U, 0U, 1U, 0U,
201 3U, 0U, 1U, 0U, 2U, 0U, 1U, 0U
202 };
203
204 uint16 n = 0U;
205
206 ASSERT(bitmap != 0U);
207 if ((bitmap & 0x00ffU) == 0U) {
208 bitmap >>= 8U;
209 n += 8U;
210 }
211 if ((bitmap & 0x0fU) == 0U) {
212 bitmap >>= 4U;
213 n += 4U;
214 }
215 return(n + bitmap_search_table[(bitmap & 0x000fU) - 1U]);
216}
217
218#endif /* OMIT_BITMAP_SEARCH */
219
220/*
221 * 優å…
222ˆåº¦ãƒ“ットマップが空かのチェック
223 */
224LOCAL_INLINE boolean
225primap_empty(void)
226{
227 return(ready_primap == 0U);
228}
229
230/*
231 * 優å…
232ˆåº¦ãƒ“ットマップのサーチ
233 */
234LOCAL_INLINE PriorityType
235primap_search(void)
236{
237 return((PriorityType) bitmap_search(ready_primap));
238}
239
240/*
241 * 優å…
242ˆåº¦ãƒ“ットマップのセット
243 */
244LOCAL_INLINE void
245primap_set(PriorityType pri)
246{
247 ready_primap |= PRIMAP_BIT(pri);
248}
249
250/*
251 * 優å…
252ˆåº¦ãƒ“ットマップのクリア
253 */
254LOCAL_INLINE void
255primap_clear(PriorityType pri)
256{
257 ready_primap &= (uint16) ~PRIMAP_BIT(pri);
258}
259
260/*
261 * 最高優å…
262ˆé †ä½ã‚¿ã‚¹ã‚¯ã®ã‚µãƒ¼ãƒ
263 */
264#ifdef TOPPERS_search_schedtsk
265
266void
267search_schedtsk(void)
268{
269 if (primap_empty() != FALSE) {
270 p_schedtsk = NULL;
271 }
272 else {
273 p_schedtsk = (TCB *) (queue_delete_next(&(ready_queue[nextpri])));
274 if (queue_empty(&(ready_queue[nextpri])) != FALSE) {
275 primap_clear(nextpri);
276 nextpri = (primap_empty() != FALSE) ?
277 TPRI_MINTASK : primap_search();
278 }
279 }
280}
281
282#endif /* TOPPERS_search_schedtsk */
283
284/*
285 * 実行できる状æ…
286‹ã¸ã®ç§»è¡Œ
287 */
288#ifdef TOPPERS_make_runnable
289
290boolean
291make_runnable(TCB *p_tcb)
292{
293 PriorityType pri, schedpri;
294 boolean is_next_schedtsk = TRUE;
295
296 p_tcb->tstat = READY;
297 LOG_TSKSTAT(p_tcb);
298 if (p_schedtsk != NULL) {
299 pri = p_tcb->curpri;
300 schedpri = p_schedtsk->curpri;
301 if (pri >= schedpri) {
302 /*
303 * schedtsk の方が優å…
304ˆåº¦ãŒé«˜ã„場合,p_tcb をレ
305 * ディキューの最後にå…
306¥ã‚Œã‚‹
307 */
308 queue_insert_prev(&(ready_queue[pri]), &(p_tcb->task_queue));
309 primap_set(pri);
310 if (pri < nextpri) {
311 nextpri = pri;
312 }
313 is_next_schedtsk = FALSE;
314 }
315 else {
316 /*
317 * p_tcb の方が優å…
318ˆåº¦ãŒé«˜ã„場合,schedtsk をレディキュー
319 * のå…
320ˆé ­ã«å…
321¥ã‚Œï¼Œp_tcb を新しい schedtsk とする
322 */
323 queue_insert_next(&(ready_queue[schedpri]), &(p_schedtsk->task_queue));
324 primap_set(schedpri);
325 nextpri = schedpri;
326 }
327 }
328
329 if (is_next_schedtsk != FALSE) {
330 p_schedtsk = p_tcb;
331 }
332 return(is_next_schedtsk);
333}
334
335#endif /* TOPPERS_make_runnable */
336
337/*
338 * 実行できる状æ…
339‹ã‹ã‚‰ä»–の状æ…
340‹ã¸ã®é·ç§»
341 *
342 * SC1-MCでmake_non_runnableが実装
343されるため
344 * SC1にもmake_non_runableを実装
345し,SC1もSC1-MCの関数構成に合せる
346 * (SC1-MCでは,p_runtskとp_schedtskが一致していることを確認する処理をå…
347¥ã‚Œã‚‹å¿…
348要があるが,
349 * SC1では,search_schedtskのみ呼び出す処理とする)
350 */
351#ifdef TOPPERS_make_non_runnable
352
353void
354make_non_runnable(void)
355{
356 search_schedtsk();
357}
358
359#endif /* TOPPERS_make_non_runnable */
360
361/*
362 * タスクの起動
363 *
364 * TerminateTask や ChainTask の中で,自タスクに対して make_active を
365 * 呼ぶ場合があるので注意する
366 */
367#ifdef TOPPERS_make_active
368
369boolean
370make_active(TCB *p_tcb)
371{
372 p_tcb->curpri = p_tcb->p_tinib->inipri;
373 if (TSKID(p_tcb) < tnum_exttask) {
374 p_tcb->curevt = EVTMASK_NONE;
375 p_tcb->waievt = EVTMASK_NONE;
376 }
377 p_tcb->p_lastrescb = NULL;
378 p_tcb->p_lastcntcb = NULL;
379
380 activate_context(p_tcb);
381 return(make_runnable(p_tcb));
382}
383
384#endif /* TOPPERS_make_active */
385
386/*
387 * タスクのプリエンプト
388 */
389#ifdef TOPPERS_preempt
390
391void
392preempt(void)
393{
394 PriorityType pri;
395
396 ASSERT(p_runtsk == p_schedtsk);
397 pri = p_runtsk->curpri;
398 queue_insert_next(&(ready_queue[pri]), &(p_runtsk->task_queue));
399 primap_set(pri);
400 search_schedtsk();
401}
402
403#endif /* TOPPERS_preempt */
404
405/*
406 * 実行中のタスクをSUSPENDED状æ…
407‹ã«ã™ã‚‹
408 * リソース解放した状æ…
409‹ã§å‘¼å‡ºã™å¿…
410要がある
411 */
412#ifdef TOPPERS_suspend
413
414void
415suspend(void)
416{
417 p_runtsk->tstat = SUSPENDED;
418 LOG_TSKSTAT(p_runtsk);
419 make_non_runnable();
420 if (p_runtsk->actcnt > 0U) {
421 p_runtsk->actcnt -= 1U;
422 (void) make_active(p_runtsk);
423 }
424}
425
426#endif /* TOPPERS_suspend */
427
428/*
429 * タスクのå…
430¨ãƒªã‚½ãƒ¼ã‚¹è¿”却
431 */
432#ifdef TOPPERS_release_taskresources
433
434void
435release_taskresources(TCB *p_tcb)
436{
437 if (p_tcb->p_lastrescb != NULL) {
438 if (p_tcb->curpri <= TPRI_MINISR) {
439 /* リソースをå…
440¨éƒ¨è§£æ”¾ã™ã‚Œã°å‰²è¾¼ã¿è¨±å¯ã«ãªã‚‹ */
441 x_set_ipm((PriorityType) TIPM_ENAALL);
442 }
443 /* リソースをå…
444¨éƒ¨è§£æ”¾ã™ã‚Œã°å®Ÿè¡Œä¸­å„ªå…
445ˆåº¦ã«æˆ»ã‚‹ */
446 p_tcb->curpri = p_tcb->p_tinib->exepri;
447
448 /* OS割込み禁止状æ…
449‹ä»¥ä¸Šã§æ¥ã‚‹ p_tcb->p_lastrescb != NULL */
450 do {
451 p_tcb->p_lastrescb->lockflg = FALSE;
452 p_tcb->p_lastrescb = p_tcb->p_lastrescb->p_prevrescb;
453 } while (p_tcb->p_lastrescb != NULL);
454 }
455}
456
457#endif /* TOPPERS_release_taskresources */
458
459/*
460 * タスクのカウンタの状æ…
461‹ã‚’すべてCS_NULLに戻す
462 */
463#ifdef TOPPERS_cancel_taskcounters
464
465void
466cancel_taskcounters(TCB *p_tcb)
467{
468 if (p_tcb->p_lastcntcb != NULL) {
469
470 /* OS割込み禁止状æ…
471‹ä»¥ä¸Šã§æ¥ã‚‹ */
472 do {
473 p_tcb->p_lastcntcb->cstat = CS_NULL;
474 p_tcb->p_lastcntcb = p_tcb->p_lastcntcb->p_prevcntcb;
475 } while (p_tcb->p_lastcntcb != NULL);
476 }
477}
478#endif /* TOPPERS_cancel_taskcounters */
479
480/*
481 * タスクの不正終了時の保護
482 * TerminateTask(),ChainTask()なしでの自タスクの終了
483 * (タスクの関数からリターン)した場合の処理
484 */
485#ifdef TOPPERS_exit_task
486
487void
488exit_task(void)
489{
490 x_nested_lock_os_int();
491
492 /* 割込み禁止状æ…
493‹ã®å ´åˆã¯å‰²è¾¼ã¿ç¦æ­¢ã‚’解除する */
494 release_interrupts(OSServiceId_Invalid);
495
496 /* リソース確保したままの場合はリソースを解放する */
497 release_taskresources(p_runtsk);
498
499#ifdef CFG_USE_ERRORHOOK
500 /* エラーフックを呼ぶ */
501 call_errorhook(E_OS_MISSINGEND, OSServiceId_TaskMissingEnd);
502#endif /* CFG_USE_ERRORHOOK */
503
504 suspend();
505
506 /* ポストタスクフックが有効な場合はポストタスクフックが呼ばれる */
507 exit_and_dispatch();
508}
509
510#endif /* TOPPERS_exit_task */
511
512#ifdef TOPPERS_remove_task_from_queue
513
514/*
515 * レディキューからタスクを削除する
516 */
517void
518remove_task_from_queue(TCB *p_tcb, PriorityType remove_task_pri)
519{
520 queue_delete(&(p_tcb->task_queue));
521 if (queue_empty(&(ready_queue[remove_task_pri])) != FALSE) {
522 primap_clear(remove_task_pri);
523 nextpri = (primap_empty() != FALSE) ? TPRI_MINTASK : primap_search();
524 }
525}
526
527#endif /* TOPPERS_remove_task_from_queue */
528
529/*
530 * 自タスクの強制終了
531 * ProtectionHookからのみ呼出される
532 * リソースの解放,割込み禁止の解除を行った後
533 * TerminateTask相当の処理を行う
534 * 強制タスク終了の場合は,PostTaskHookを呼出さないのでTerminateTask
535 * とは異なる処理となる
536 * 本関数はOS割込み禁止状æ…
537‹ã§å‘¼å‡ºã•ã‚Œã‚‹ã“とを前提とする
538 */
539#ifdef TOPPERS_force_terminate_task
540
541void
542force_terminate_task(TCB *p_tcb)
543{
544 /*
545 * 割込み禁止を解除する
546 * エラーフックを呼ばないため,引数にOSServiceId_Invalidをする
547 */
548 release_interrupts(OSServiceId_Invalid);
549
550 /* リソース確保したままの場合,リソース解放 */
551 release_taskresources(p_tcb);
552 /* カウンタの状æ…
553‹ã‚’初期化する */
554 cancel_taskcounters(p_tcb);
555
556 suspend();
557
558 exit_and_dispatch_nohook();
559}
560
561#endif /* TOPPERS_force_terminate_task */
562
563/*
564 * OSAP所属するタスクの強制終了
565 */
566#ifdef TOPPERS_force_term_osap_task
567
568void
569force_term_osap_task(OSAPCB *p_osapcb)
570{
571 /* OSAPに所属するタスクを強制終了 */
572 TaskType i;
573 TCB *p_tcb;
574 PriorityType remove_task_pri;
575
576 for (i = 0U; i < tnum_task; i++) {
577 p_tcb = &tcb_table[i];
578 if ((tinib_table[i].p_osapcb == p_osapcb) &&
579 (p_tcb != p_runtsk)) {
580 /*
581 * OSAP終了/再起動よりタスクの強制終了
582 */
583 p_tcb->actcnt = 0U;
584#ifdef CFG_USE_PROTECTIONHOOK
585 p_tcb->calltfn = FALSE;
586#endif /* CFG_USE_PROTECTIONHOOK */
587
588 if (p_tcb->tstat == READY) {
589 /* curpriとinipriが異なる値でレディキューに繋がれている場合への対応 */
590 remove_task_pri = p_tcb->curpri;
591
592 /* リソース確保したままの場合,リソース解放 */
593 release_taskresources(p_tcb);
594
595 /* カウンタの状æ…
596‹ã‚’初期化する */
597 cancel_taskcounters(p_tcb);
598
599 /* 対象タスクをSUSPEND状æ…
600‹ã¨ã—,レディキューから削除する */
601 p_tcb->tstat = SUSPENDED;
602 remove_task_from_queue(p_tcb, remove_task_pri);
603 }
604 else {
605 p_tcb->tstat = SUSPENDED;
606 }
607
608 /*
609 * ここでC2ISRを受け付ける.
610 * フックの中からここに来た場合はnested_lock_os_int_cntが2以上なので,
611 * 割込み禁止解除されない.
612 * SusOS状æ…
613‹ã§ã‚‚,割込み優å…
614ˆåº¦ãƒžã‚¹ã‚¯ã¯ä¿æŒã•ã‚ŒãŸã¾ã¾ãªã®ã§ï¼Œ
615 * C2ISRは発生しない.
616 */
617 x_nested_unlock_os_int();
618
619 /* ここで割込み禁止とする */
620 x_nested_lock_os_int();
621 }
622 }
623
624 p_tcb = p_runtsk;
625 /* OSAPを強制終了するためのリスタートタスクからコールされるため */
626 /* リソース解放やカウンタの状æ…
627‹ã‚’初期化する必
628要はなし */
629 /* 対象タスクをSUSPEND状æ…
630‹ã¨ã™ã‚‹ */
631 /* p_schedtskの更新はforce_term_osap_mainに戻ってから実施する */
632 p_tcb->tstat = SUSPENDED;
633}
634
635#endif /* TOPPERS_force_term_osap_task */
636
637/*
638 * p_schedtskをレディキューのå…
639ˆé ­ã«é€€é¿
640 */
641#ifdef TOPPERS_move_schedtsk
642
643void
644move_schedtsk(void)
645{
646 queue_insert_next(&(ready_queue[p_schedtsk->curpri]), &(p_schedtsk->task_queue));
647 primap_set(p_schedtsk->curpri);
648 nextpri = p_schedtsk->curpri;
649}
650
651#endif /* TOPPERS_move_schedtsk */
Note: See TracBrowser for help on using the repository browser.