source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/kernel/cyclic.c@ 337

Last change on this file since 337 was 337, checked in by coas-nagasima, 6 years ago

ASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 10.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-2016 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 * スコード中に含まれていること.
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23 * と.
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27 * 報告すること.
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32 * 免責すること.
33 *
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38 * の責任を負わない.
39 *
40 * $Id$
41 */
42
43/*
44 * 周期通知機能
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "cyclic.h"
50
51/*
52 * トレースログマクロのデフォルト定義
53 */
54#ifndef LOG_CYC_ENTER
55#define LOG_CYC_ENTER(p_cyccb)
56#endif /* LOG_CYC_ENTER */
57
58#ifndef LOG_CYC_LEAVE
59#define LOG_CYC_LEAVE(p_cyccb)
60#endif /* LOG_CYC_LEAVE */
61
62#ifndef LOG_ACRE_CYC_ENTER
63#define LOG_ACRE_CYC_ENTER(pk_ccyc)
64#endif /* LOG_ACRE_CYC_ENTER */
65
66#ifndef LOG_ACRE_CYC_LEAVE
67#define LOG_ACRE_CYC_LEAVE(ercd)
68#endif /* LOG_ACRE_CYC_LEAVE */
69
70#ifndef LOG_DEL_CYC_ENTER
71#define LOG_DEL_CYC_ENTER(cycid)
72#endif /* LOG_DEL_CYC_ENTER */
73
74#ifndef LOG_DEL_CYC_LEAVE
75#define LOG_DEL_CYC_LEAVE(ercd)
76#endif /* LOG_DEL_CYC_LEAVE */
77
78#ifndef LOG_STA_CYC_ENTER
79#define LOG_STA_CYC_ENTER(cycid)
80#endif /* LOG_STA_CYC_ENTER */
81
82#ifndef LOG_STA_CYC_LEAVE
83#define LOG_STA_CYC_LEAVE(ercd)
84#endif /* LOG_STA_CYC_LEAVE */
85
86#ifndef LOG_STP_CYC_ENTER
87#define LOG_STP_CYC_ENTER(cycid)
88#endif /* LOG_STP_CYC_ENTER */
89
90#ifndef LOG_STP_CYC_LEAVE
91#define LOG_STP_CYC_LEAVE(ercd)
92#endif /* LOG_STP_CYC_LEAVE */
93
94#ifndef LOG_REF_CYC_ENTER
95#define LOG_REF_CYC_ENTER(cycid, pk_rcyc)
96#endif /* LOG_REF_CYC_ENTER */
97
98#ifndef LOG_REF_CYC_LEAVE
99#define LOG_REF_CYC_LEAVE(ercd, pk_rcyc)
100#endif /* LOG_REF_CYC_LEAVE */
101
102/*
103 * 周期通知の数
104 */
105#define tnum_cyc ((uint_t)(tmax_cycid - TMIN_CYCID + 1))
106#define tnum_scyc ((uint_t)(tmax_scycid - TMIN_CYCID + 1))
107
108/*
109 * 周期通知IDから周期通知管理ブロックを取り出すためのマクロ
110 */
111#define INDEX_CYC(cycid) ((uint_t)((cycid) - TMIN_CYCID))
112#define get_cyccb(cycid) (&(cyccb_table[INDEX_CYC(cycid)]))
113
114#ifdef TOPPERS_cycini
115
116/*
117 * 使用していない周期通知管理ブロックのリスト
118 *
119 * 周期通知管理ブロックの先頭にはキューにつなぐための領域がないため,
120 * タイムイベントブロック(tmevtb)の領域を用いる.
121 */
122QUEUE free_cyccb;
123
124/*
125 * 周期通知機能の初期化
126 */
127void
128initialize_cyclic(void)
129{
130 uint_t i, j;
131 CYCCB *p_cyccb;
132 CYCINIB *p_cycinib;
133
134 for (i = 0; i < tnum_scyc; i++) {
135 p_cyccb = &(cyccb_table[i]);
136 p_cyccb->p_cycinib = &(cycinib_table[i]);
137 p_cyccb->tmevtb.callback = (CBACK) call_cyclic;
138 p_cyccb->tmevtb.arg = (void *) p_cyccb;
139 if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
140 /*
141 * 初回の起動のためのタイムイベントを登録する[ASPD1035]
142 * [ASPD1062].
143 */
144 p_cyccb->cycsta = true;
145 p_cyccb->tmevtb.evttim = (EVTTIM)(p_cyccb->p_cycinib->cycphs);
146 tmevtb_register(&(p_cyccb->tmevtb));
147 }
148 else {
149 p_cyccb->cycsta = false;
150 }
151 }
152 queue_initialize(&free_cyccb);
153 for (j = 0; i < tnum_cyc; i++, j++) {
154 p_cyccb = &(cyccb_table[i]);
155 p_cycinib = &(acycinib_table[j]);
156 p_cycinib->cycatr = TA_NOEXS;
157 p_cyccb->p_cycinib = ((const CYCINIB *) p_cycinib);
158 p_cyccb->tmevtb.callback = (CBACK) call_cyclic;
159 p_cyccb->tmevtb.arg = (void *) p_cyccb;
160 queue_insert_prev(&free_cyccb, ((QUEUE *) &(p_cyccb->tmevtb)));
161 }
162}
163
164#endif /* TOPPERS_cycini */
165
166/*
167 * 周期通知の生成
168 */
169#ifdef TOPPERS_acre_cyc
170
171ER_UINT
172acre_cyc(const T_CCYC *pk_ccyc)
173{
174 CYCCB *p_cyccb;
175 CYCINIB *p_cycinib;
176 ATR cycatr;
177 T_NFYINFO nfyinfo, *p_nfyinfo;
178 RELTIM cyctim;
179 RELTIM cycphs;
180 ER ercd, rercd;
181
182 LOG_ACRE_CYC_ENTER(pk_ccyc);
183 CHECK_TSKCTX_UNL();
184
185 cycatr = pk_ccyc->cycatr;
186 nfyinfo = pk_ccyc->nfyinfo;
187 cyctim = pk_ccyc->cyctim;
188 cycphs = pk_ccyc->cycphs;
189
190 CHECK_RSATR(cycatr, TA_STA);
191 rercd = check_nfyinfo(&nfyinfo);
192 if (rercd != E_OK) {
193 ercd = rercd;
194 goto error_exit;
195 }
196 CHECK_PAR(0 < cyctim && cyctim <= TMAX_RELTIM);
197 CHECK_PAR(0 <= cycphs && cycphs <= TMAX_RELTIM);
198
199 lock_cpu();
200 if (tnum_cyc == 0 || queue_empty(&free_cyccb)) {
201 ercd = E_NOID;
202 }
203 else {
204 p_cyccb = ((CYCCB *)(((char *) queue_delete_next(&free_cyccb))
205 - offsetof(CYCCB, tmevtb)));
206 p_cycinib = (CYCINIB *)(p_cyccb->p_cycinib);
207 p_cycinib->cycatr = cycatr;
208 if (nfyinfo.nfymode == TNFY_HANDLER) {
209 p_cycinib->exinf = nfyinfo.nfy.handler.exinf;
210 p_cycinib->nfyhdr = (NFYHDR)(nfyinfo.nfy.handler.tmehdr);
211 }
212 else {
213 p_nfyinfo = &acyc_nfyinfo_table[p_cycinib - acycinib_table];
214 *p_nfyinfo = nfyinfo;
215 p_cycinib->exinf = (intptr_t) p_nfyinfo;
216 p_cycinib->nfyhdr = notify_handler;
217 }
218 p_cycinib->cyctim = cyctim;
219 p_cycinib->cycphs = cycphs;
220
221 if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
222 p_cyccb->cycsta = true;
223 tmevtb_enqueue(&(p_cyccb->tmevtb), p_cyccb->p_cycinib->cycphs);
224 }
225 else {
226 p_cyccb->cycsta = false;
227 }
228 ercd = CYCID(p_cyccb);
229 }
230 unlock_cpu();
231
232 error_exit:
233 LOG_ACRE_CYC_LEAVE(ercd);
234 return(ercd);
235}
236
237#endif /* TOPPERS_acre_cyc */
238
239/*
240 * 周期通知の削除
241 */
242#ifdef TOPPERS_del_cyc
243
244ER
245del_cyc(ID cycid)
246{
247 CYCCB *p_cyccb;
248 CYCINIB *p_cycinib;
249 ER ercd;
250
251 LOG_DEL_CYC_ENTER(cycid);
252 CHECK_TSKCTX_UNL();
253 CHECK_ID(VALID_CYCID(cycid));
254 p_cyccb = get_cyccb(cycid);
255
256 lock_cpu();
257 if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
258 ercd = E_NOEXS;
259 }
260 else if (cycid <= tmax_scycid) {
261 ercd = E_OBJ;
262 }
263 else {
264 if (p_cyccb->cycsta) {
265 p_cyccb->cycsta = false;
266 tmevtb_dequeue(&(p_cyccb->tmevtb));
267 }
268
269 p_cycinib = (CYCINIB *)(p_cyccb->p_cycinib);
270 p_cycinib->cycatr = TA_NOEXS;
271 queue_insert_prev(&free_cyccb, ((QUEUE *) &(p_cyccb->tmevtb)));
272 ercd = E_OK;
273 }
274 unlock_cpu();
275
276 error_exit:
277 LOG_DEL_CYC_LEAVE(ercd);
278 return(ercd);
279}
280
281#endif /* TOPPERS_del_cyc */
282
283/*
284 * 周期通知の動作開始
285 */
286#ifdef TOPPERS_sta_cyc
287
288ER
289sta_cyc(ID cycid)
290{
291 CYCCB *p_cyccb;
292 ER ercd;
293
294 LOG_STA_CYC_ENTER(cycid);
295 CHECK_TSKCTX_UNL();
296 CHECK_ID(VALID_CYCID(cycid));
297 p_cyccb = get_cyccb(cycid);
298
299 lock_cpu();
300 if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
301 ercd = E_NOEXS;
302 }
303 else {
304 if (p_cyccb->cycsta) {
305 tmevtb_dequeue(&(p_cyccb->tmevtb));
306 }
307 else {
308 p_cyccb->cycsta = true;
309 }
310 /*
311 * 初回の起動のためのタイムイベントを登録する[ASPD1036].
312 */
313 tmevtb_enqueue(&(p_cyccb->tmevtb), p_cyccb->p_cycinib->cycphs);
314 ercd = E_OK;
315 }
316 unlock_cpu();
317
318 error_exit:
319 LOG_STA_CYC_LEAVE(ercd);
320 return(ercd);
321}
322
323#endif /* TOPPERS_sta_cyc */
324
325/*
326 * 周期通知の動作停止
327 */
328#ifdef TOPPERS_stp_cyc
329
330ER
331stp_cyc(ID cycid)
332{
333 CYCCB *p_cyccb;
334 ER ercd;
335
336 LOG_STP_CYC_ENTER(cycid);
337 CHECK_TSKCTX_UNL();
338 CHECK_ID(VALID_CYCID(cycid));
339 p_cyccb = get_cyccb(cycid);
340
341 lock_cpu();
342 if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
343 ercd = E_NOEXS;
344 }
345 else {
346 if (p_cyccb->cycsta) {
347 p_cyccb->cycsta = false;
348 tmevtb_dequeue(&(p_cyccb->tmevtb));
349 }
350 ercd = E_OK;
351 }
352 unlock_cpu();
353
354 error_exit:
355 LOG_STP_CYC_LEAVE(ercd);
356 return(ercd);
357}
358
359#endif /* TOPPERS_stp_cyc */
360
361/*
362 * 周期通知の状態参照
363 */
364#ifdef TOPPERS_ref_cyc
365
366ER
367ref_cyc(ID cycid, T_RCYC *pk_rcyc)
368{
369 CYCCB *p_cyccb;
370 ER ercd;
371
372 LOG_REF_CYC_ENTER(cycid, pk_rcyc);
373 CHECK_TSKCTX_UNL();
374 CHECK_ID(VALID_CYCID(cycid));
375 p_cyccb = get_cyccb(cycid);
376
377 lock_cpu();
378 if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
379 ercd = E_NOEXS;
380 }
381 else {
382 if (p_cyccb->cycsta) {
383 pk_rcyc->cycstat = TCYC_STA;
384 pk_rcyc->lefttim = tmevt_lefttim(&(p_cyccb->tmevtb));
385 }
386 else {
387 pk_rcyc->cycstat = TCYC_STP;
388 }
389 ercd = E_OK;
390 }
391 unlock_cpu();
392
393 error_exit:
394 LOG_REF_CYC_LEAVE(ercd, pk_rcyc);
395 return(ercd);
396}
397
398#endif /* TOPPERS_ref_cyc */
399
400/*
401 * 周期通知起動ルーチン
402 */
403#ifdef TOPPERS_cyccal
404
405void
406call_cyclic(CYCCB *p_cyccb)
407{
408 /*
409 * 次回の起動のためのタイムイベントを登録する[ASPD1037].
410 */
411 p_cyccb->tmevtb.evttim += p_cyccb->p_cycinib->cyctim; /*[ASPD1038]*/
412 tmevtb_register(&(p_cyccb->tmevtb));
413
414 /*
415 * 通知ハンドラを,CPUロック解除状態で呼び出す.
416 */
417 unlock_cpu();
418
419 LOG_CYC_ENTER(p_cyccb);
420 (*(p_cyccb->p_cycinib->nfyhdr))(p_cyccb->p_cycinib->exinf);
421 LOG_CYC_LEAVE(p_cyccb);
422
423 if (!sense_lock()) {
424 lock_cpu();
425 }
426}
427
428#endif /* TOPPERS_cyccal */
Note: See TracBrowser for help on using the repository browser.