source: UsbWattMeter/trunk/asp_dcre/kernel/cyclic.c@ 167

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

MIMEにSJISを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=SHIFT_JIS
File size: 9.1 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-2014 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: cyclic.c 167 2016-03-08 11:37:45Z coas-nagasima $
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/*
115 * 周期ハンドラ起動のためのタイムイベントブロックの登録
116 */
117Inline void
118tmevtb_enqueue_cyc(CYCCB *p_cyccb, EVTTIM evttim)
119{
120 tmevtb_enqueue_evttim(&(p_cyccb->tmevtb), evttim,
121 (CBACK) call_cychdr, (void *) p_cyccb);
122 p_cyccb->evttim = evttim;
123}
124
125#ifdef TOPPERS_cycini
126
127/*
128 * 使用していない周期ハンドラ管理ブロックのリスト
129 *
130 * 周期ハンドラ管理ブロックの先頭にはキューにつなぐための領域がないた
131 * め,タイムイベントブロック(tmevtb)の領域を用いる.
132 */
133QUEUE free_cyccb;
134
135/*
136 * 周期ハンドラ機能の初期化
137 */
138void
139initialize_cyclic(void)
140{
141 uint_t i, j;
142 CYCCB *p_cyccb;
143 CYCINIB *p_cycinib;
144
145 for (i = 0; i < tnum_scyc; i++) {
146 p_cyccb = &(cyccb_table[i]);
147 p_cyccb->p_cycinib = &(cycinib_table[i]);
148 if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
149 p_cyccb->cycsta = true;
150 tmevtb_enqueue_cyc(p_cyccb, (EVTTIM)(p_cyccb->p_cycinib->cycphs));
151 }
152 else {
153 p_cyccb->cycsta = false;
154 }
155 }
156 queue_initialize(&free_cyccb);
157 for (j = 0; i < tnum_cyc; i++, j++) {
158 p_cyccb = &(cyccb_table[i]);
159 p_cycinib = &(acycinib_table[j]);
160 p_cycinib->cycatr = TA_NOEXS;
161 p_cyccb->p_cycinib = ((const CYCINIB *) p_cycinib);
162 queue_insert_prev(&free_cyccb, ((QUEUE *) &(p_cyccb->tmevtb)));
163 }
164}
165
166#endif /* TOPPERS_cycini */
167
168/*
169 * 周期ハンドラの生成
170 */
171#ifdef TOPPERS_acre_cyc
172
173ER_UINT
174acre_cyc(const T_CCYC *pk_ccyc)
175{
176 CYCCB *p_cyccb;
177 CYCINIB *p_cycinib;
178 ER ercd;
179
180 LOG_ACRE_CYC_ENTER(pk_ccyc);
181 CHECK_TSKCTX_UNL();
182 CHECK_RSATR(pk_ccyc->cycatr, TA_STA);
183 CHECK_ALIGN_FUNC(pk_ccyc->cychdr);
184 CHECK_NONNULL_FUNC(pk_ccyc->cychdr);
185 CHECK_PAR(0 < pk_ccyc->cyctim && pk_ccyc->cyctim <= TMAX_RELTIM);
186 CHECK_PAR(0 <= pk_ccyc->cycphs && pk_ccyc->cycphs <= TMAX_RELTIM);
187
188 t_lock_cpu();
189 if (tnum_cyc == 0 || queue_empty(&free_cyccb)) {
190 ercd = E_NOID;
191 }
192 else {
193 p_cyccb = ((CYCCB *)(((char *) queue_delete_next(&free_cyccb))
194 - offsetof(CYCCB, tmevtb)));
195 p_cycinib = (CYCINIB *)(p_cyccb->p_cycinib);
196 p_cycinib->cycatr = pk_ccyc->cycatr;
197 p_cycinib->exinf = pk_ccyc->exinf;
198 p_cycinib->cychdr = pk_ccyc->cychdr;
199 p_cycinib->cyctim = pk_ccyc->cyctim;
200 p_cycinib->cycphs = pk_ccyc->cycphs;
201
202 if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
203 p_cyccb->cycsta = true;
204 tmevtb_enqueue_cyc(p_cyccb,
205 base_time + p_cyccb->p_cycinib->cycphs);
206 }
207 else {
208 p_cyccb->cycsta = false;
209 }
210 ercd = CYCID(p_cyccb);
211 }
212 t_unlock_cpu();
213
214 error_exit:
215 LOG_ACRE_CYC_LEAVE(ercd);
216 return(ercd);
217}
218
219#endif /* TOPPERS_acre_cyc */
220
221/*
222 * 周期ハンドラの削除
223 */
224#ifdef TOPPERS_del_cyc
225
226ER
227del_cyc(ID cycid)
228{
229 CYCCB *p_cyccb;
230 CYCINIB *p_cycinib;
231 ER ercd;
232
233 LOG_DEL_CYC_ENTER(cycid);
234 CHECK_TSKCTX_UNL();
235 CHECK_CYCID(cycid);
236 p_cyccb = get_cyccb(cycid);
237
238 t_lock_cpu();
239 if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
240 ercd = E_NOEXS;
241 }
242 else if (CYCID(p_cyccb) > tmax_scycid) {
243 if (p_cyccb->cycsta) {
244 p_cyccb->cycsta = false;
245 tmevtb_dequeue(&(p_cyccb->tmevtb));
246 }
247
248 p_cycinib = (CYCINIB *)(p_cyccb->p_cycinib);
249 p_cycinib->cycatr = TA_NOEXS;
250 queue_insert_prev(&free_cyccb, ((QUEUE *) &(p_cyccb->tmevtb)));
251 ercd = E_OK;
252 }
253 else {
254 ercd = E_OBJ;
255 }
256 t_unlock_cpu();
257
258 error_exit:
259 LOG_DEL_CYC_LEAVE(ercd);
260 return(ercd);
261}
262
263#endif /* TOPPERS_del_cyc */
264
265/*
266 * 周期ハンドラの動作開始
267 */
268#ifdef TOPPERS_sta_cyc
269
270ER
271sta_cyc(ID cycid)
272{
273 CYCCB *p_cyccb;
274 ER ercd;
275
276 LOG_STA_CYC_ENTER(cycid);
277 CHECK_TSKCTX_UNL();
278 CHECK_CYCID(cycid);
279 p_cyccb = get_cyccb(cycid);
280
281 t_lock_cpu();
282 if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
283 ercd = E_NOEXS;
284 }
285 else {
286 if (p_cyccb->cycsta) {
287 tmevtb_dequeue(&(p_cyccb->tmevtb));
288 }
289 else {
290 p_cyccb->cycsta = true;
291 }
292 tmevtb_enqueue_cyc(p_cyccb, base_time + p_cyccb->p_cycinib->cycphs);
293 ercd = E_OK;
294 }
295 t_unlock_cpu();
296
297 error_exit:
298 LOG_STA_CYC_LEAVE(ercd);
299 return(ercd);
300}
301
302#endif /* TOPPERS_sta_cyc */
303
304/*
305 * 周期ハンドラの動作停止
306 */
307#ifdef TOPPERS_stp_cyc
308
309ER
310stp_cyc(ID cycid)
311{
312 CYCCB *p_cyccb;
313 ER ercd;
314
315 LOG_STP_CYC_ENTER(cycid);
316 CHECK_TSKCTX_UNL();
317 CHECK_CYCID(cycid);
318 p_cyccb = get_cyccb(cycid);
319
320 t_lock_cpu();
321 if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
322 ercd = E_NOEXS;
323 }
324 else {
325 if (p_cyccb->cycsta) {
326 p_cyccb->cycsta = false;
327 tmevtb_dequeue(&(p_cyccb->tmevtb));
328 }
329 ercd = E_OK;
330 }
331 t_unlock_cpu();
332
333 error_exit:
334 LOG_STP_CYC_LEAVE(ercd);
335 return(ercd);
336}
337
338#endif /* TOPPERS_stp_cyc */
339
340/*
341 * 周期ハンドラの状態参照
342 */
343#ifdef TOPPERS_ref_cyc
344
345ER
346ref_cyc(ID cycid, T_RCYC *pk_rcyc)
347{
348 CYCCB *p_cyccb;
349 ER ercd;
350
351 LOG_REF_CYC_ENTER(cycid, pk_rcyc);
352 CHECK_TSKCTX_UNL();
353 CHECK_CYCID(cycid);
354 p_cyccb = get_cyccb(cycid);
355
356 t_lock_cpu();
357 if (p_cyccb->p_cycinib->cycatr == TA_NOEXS) {
358 ercd = E_NOEXS;
359 }
360 else {
361 if (p_cyccb->cycsta) {
362 pk_rcyc->cycstat = TCYC_STA;
363 pk_rcyc->lefttim = tmevt_lefttim(&(p_cyccb->tmevtb));
364 }
365 else {
366 pk_rcyc->cycstat = TCYC_STP;
367 }
368 ercd = E_OK;
369 }
370 t_unlock_cpu();
371
372 error_exit:
373 LOG_REF_CYC_LEAVE(ercd, pk_rcyc);
374 return(ercd);
375}
376
377#endif /* TOPPERS_ref_cyc */
378
379/*
380 * 周期ハンドラ起動ルーチン
381 */
382#ifdef TOPPERS_cyccal
383
384void
385call_cychdr(CYCCB *p_cyccb)
386{
387 PRI saved_ipm;
388
389 /*
390 * 次回の起動のためのタイムイベントブロックを登録する.
391 *
392 * 同じタイムティックで周期ハンドラを再度起動すべき場合には,この
393 * 関数からsignal_timeに戻った後に,再度この関数が呼ばれることにな
394 * る.
395 */
396 tmevtb_enqueue_cyc(p_cyccb, p_cyccb->evttim + p_cyccb->p_cycinib->cyctim);
397
398 /*
399 * 周期ハンドラを,CPUロック解除状態で呼び出す.
400 */
401 saved_ipm = i_get_ipm();
402 i_unlock_cpu();
403
404 LOG_CYC_ENTER(p_cyccb);
405 (*((CYCHDR)(p_cyccb->p_cycinib->cychdr)))(p_cyccb->p_cycinib->exinf);
406 LOG_CYC_LEAVE(p_cyccb);
407
408 if (!i_sense_lock()) {
409 i_lock_cpu();
410 }
411 i_set_ipm(saved_ipm);
412}
413
414#endif /* TOPPERS_cyccal */
Note: See TracBrowser for help on using the repository browser.