comparison src/cs/riviera/rvf/rvf_time.c @ 0:92470e5d0b9e

src: partial import from FC Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 15 May 2020 01:28:16 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:92470e5d0b9e
1 /****************************************************************************/
2 /* */
3 /* Name rvf_time.c */
4 /* */
5 /* Function this file contains rvf time related functions */
6 /* */
7 /* Version 0.1 */
8 /* */
9 /* Date Modification */
10 /* ------------------------------------ */
11 /* 3/12/99 Create */
12 /* 10/27/1999 remove all non-nucleus sections (#ifdef) */
13 /* 30/11/99 compliant to RV coding guidelines */
14 /* 31/01/2003 Timer Redesign/Impl.RV2 Gary TOTNEY */
15 /* */
16 /* Author David Lamy-Charrier (dlamy@tif.ti.com) */
17 /* */
18 /* (C) Copyright 1999 by Texas Instruments Incorporated, All Rights Reserved*/
19 /****************************************************************************/
20
21 #include "nucleus.h"
22
23 #include "rvm/rvm_use_id_list.h"
24 #include "rvm/rvm_i.h" // only for MBs [coupling issue]
25 #include "rvm/rvm_api.h"// MSG [coupling issue]
26 #include "rvf/rvf_i.h"
27 #include "rvf/rvf_api.h"
28 #include <string.h>
29
30
31
32 /*
33 ** Define the time control array
34 */
35 static NU_TIMER rvf_Timer[MAX_RVF_TASKS][RVF_NUM_TASK_TIMERS];
36
37 //extern T_RVF_MB_ID rvm_timer_mem_bank;
38
39 #define _RALLOC_TIMER_BLK(tb) rvf_get_buf(rvm_timer_mem_bank, sizeof(NU_TIMER), tb)
40 #define _RALLOC_TMS_MSG(id, tb) rvf_get_msg_buf(rvm_tm_notify_mem_bank, sizeof(T_RVF_TMS_MSG), id, tb)
41
42
43 /* PRIVATE FUNC FWD DECLs */
44 T_RV_TM_ID _invoke_tm(T_RVF_G_ADDR_ID gid, UINT32 t, UINT8 cont, void* action, UINT8 lg);
45
46 /*******************************************************************************
47 **
48 ** Function _rvf_timer_expire
49 **
50 ** Description This internal function is called by Nucleus OS, when a task
51 ** timer expires. It sets the corresponding event.
52 **
53 ** Returns void
54 **
55 *******************************************************************************/
56 void _rvf_timer_expire(UNSIGNED timer_id)
57 {
58 rvf_disable(14);
59 /* send the corresponding timer event */
60 rvf_send_event((UINT8)(timer_id / RVF_NUM_TASK_TIMERS),(UINT16)(EVENT_MASK(((timer_id % RVF_NUM_TASK_TIMERS)+4)) ) );
61 rvf_enable();
62 }
63
64 void _rvf_tm_notify(UNSIGNED timer_id) {
65 T_RVF_TM_UBLK tmr;
66 T_RVF_TM_ATTRIB_UBLK attr;
67 UINT32 tmid=0, cont=0, d;
68 OPTION opt;
69 T_RVF_TMS_MSG* p_msg=NULL;
70
71 if(timer_id) tmr.id=timer_id;
72
73 if(NU_Timer_Information(tmr.ptr,attr.str, &opt, (UNSIGNED*)&d, (UNSIGNED*)&tmid, (UNSIGNED*)&d, (UNSIGNED*) &cont) == NU_INVALID_TIMER) { // use to get p_attrib
74 rvf_send_trace ("FATAL: RVF TIMER ATTIRBUTE ERROR!",
75 49,
76 NULL_PARAM,
77 RV_TRACE_LEVEL_WARNING,
78 0);
79
80 }
81 /* printf("%ld %ld %d:", attr.attrib.host_addr_id,
82 attr.attrib.action,
83 attr.attrib.legacyFlag);
84 */
85 if(!pRtAddrIdTable[attr.attrib.host_addr_id]) return; // Don't waste time in HISR /* MUST BE REPLACED WITH CACHED MSG'ing */
86
87 // Will utilise active caching in near future, limiting HISR duration
88 if((_RALLOC_TMS_MSG(RVM_TMS_MSG, (T_RVF_MSG**)&p_msg))==RVF_RED){
89 rvf_send_trace ("FATAL: RVF TIMER HISR: Insufficient resources!",
90 49,
91 NULL_PARAM,
92 RV_TRACE_LEVEL_WARNING,
93 0);
94
95 return; // (RV_MEMORY_ERR);
96 }
97 p_msg->hdr.msg_id=RVM_TMS_MSG;
98 p_msg->tm_id=tmr.id;
99 p_msg->cont=cont;
100 p_msg->action=attr.attrib.action;
101 rvf_disable(14);
102 rvf_send_priority_msg(attr.attrib.host_addr_id, p_msg); // NOTE: must have id and recognised in FSM core
103 rvf_enable();
104 }
105
106 /********************************************************************************/
107 /* */
108 /* Function Name: rvf_create_timer */
109 /* */
110 /* Purpose: This function is reponsible for stopping timers. */
111 /* */
112 /* Revision History: */
113 /* */
114 /********************************************************************************/
115 T_RVF_TIMER_ID rvf_create_timer(T_RVF_G_ADDR_ID g_addrId,
116 UINT32 tmDuration,
117 BOOLEAN isContinuous,
118 void* p_action) {
119
120 return _invoke_tm(g_addrId, tmDuration, isContinuous, p_action, 0);
121 }
122
123 // this exists as part of an on-going initiative to deprecate rvf: start/stop timers
124 T_RV_TM_ID _invoke_tm(T_RVF_G_ADDR_ID gid, UINT32 t, UINT8 cont, void* action, UINT8 lg) {
125 T_RVF_TM_UBLK tmr;
126 T_RVF_TM_ATTRIB_UBLK tm_attrib;
127 UINT32 re_sched=0;
128 OPTION opt=NU_DISABLE_TIMER;
129 STATUS status;
130
131 if(t) opt=NU_ENABLE_TIMER;
132 if(cont) re_sched=t;
133
134 // TO DO... ret. 0 if alloc fails
135 if(_RALLOC_TIMER_BLK((T_RVF_BUFFER**)&tmr.ptr)) return 0;
136
137 tm_attrib.attrib.host_addr_id =gid;
138 tm_attrib.attrib.action =action;
139 tm_attrib.attrib.legacyFlag =lg;
140
141 status=NU_Create_Timer( tmr.ptr, // TIMER CONTROL BLOCK
142 tm_attrib.str, // timer name (overloaded)
143 _rvf_tm_notify, // expiration routine to call
144 tmr.id, // unique id which enables to find a specific task and a specific timer
145 t, // duration
146 re_sched, // continuous = 1
147 opt);
148
149 if(status!=NU_SUCCESS) tmr.id=0;
150
151 return (UINT32)tmr.id;
152 }
153
154 /*T_RVF_RET rvf_get_remaining_time(T_RV_TM_ID tid, UINT32* t) {
155 T_RVF_TM_UBLK tmr;
156
157 tmr.id=tid;
158 if(NU_Get_Remaining_Time(tmr.ptr, (UNSIGNED*)&t)==NU_INVALID_TIMER) return RV_INVALID_PARAMETER;
159
160 return RVF_OK;
161 }*/
162
163 /*******************************************************************************
164 **
165 ** Function rvf_del_timer
166 **
167 ** Description This function is called by an application to delete a timer
168 ** entry from a timer list.
169 **
170 ** Returns void
171 **
172 *******************************************************************************/
173 void rvf_del_timer(T_RV_TM_ID tm_id) {
174 T_RVF_TM_UBLK tmr;
175
176 if(tm_id) tmr.id=tm_id;
177
178 NU_Control_Timer(tmr.ptr, NU_DISABLE_TIMER);
179 NU_Delete_Timer(tmr.ptr);
180 rvf_free_buf(tmr.ptr);
181 }
182
183 void rvf_reset_timer(T_RV_TM_ID tm_id, UINT32 new_duration,
184 BOOLEAN isContinuous) {
185 T_RVF_TM_UBLK tmr;
186 UINT32 re_sched=0;
187
188 if(isContinuous)re_sched=new_duration;
189 if(tm_id) tmr.id=tm_id;
190
191 NU_Control_Timer(tmr.ptr, NU_DISABLE_TIMER);
192
193 if(new_duration) {
194 NU_Reset_Timer( tmr.ptr,
195 _rvf_tm_notify,
196 new_duration,
197 re_sched,
198 NU_ENABLE_TIMER);
199 }
200
201 }
202
203 /*******************************************************************************
204 **
205 ** Function _rvf_timers_init
206 **
207 ** Description This internal function is called once at startup to initialize
208 ** all the timer structures.
209 **
210 ** Returns void
211 **
212 *******************************************************************************/
213 void _rvf_timers_init(void)
214 {
215 UINT8 task_num, timer_num;
216
217 for (task_num = 0; task_num< MAX_RVF_TASKS; task_num++)
218 {
219 for (timer_num = 0; timer_num < RVF_NUM_TASK_TIMERS; timer_num++)
220 {
221 NU_Create_Timer( &(rvf_Timer[task_num][timer_num]),/* TIMER CONTROL BLOCK*/
222 "", /* timer name */
223 _rvf_timer_expire, /* expiration routine to call*/
224 (task_num * RVF_NUM_TASK_TIMERS) +timer_num,
225 /* unique id which enables to find a specific task and a specific timer*/
226 1,
227 0,
228 NU_DISABLE_TIMER);
229 }
230 }
231 }
232
233 /*******************************************************************************
234 **
235 ** Function rvf_get_time_stamp
236 **
237 ** Description This function formats the time into a user area
238 **
239 ** Returns the address of the user area containing the formatted time
240 **
241 *******************************************************************************/
242 char *rvf_get_time_stamp(char *tbuf)
243 {
244 UINT32 ms_time;
245 UINT32 s_time;
246 UINT32 m_time;
247 UINT32 h_time;
248 char *p_out = tbuf;
249
250 ms_time = rvf_get_tick_count();
251 s_time = ms_time/100; /* 100 Ticks per second */
252 m_time = s_time/60;
253 h_time = m_time/60;
254
255 ms_time -= s_time*100;
256 s_time -= m_time*60;
257 m_time -= h_time*60;
258
259 *p_out++ = (char)((h_time / 10) + '0');
260 *p_out++ = (char)((h_time % 10) + '0');
261 *p_out++ = ':';
262 *p_out++ = (char)((m_time / 10) + '0');
263 *p_out++ = (char)((m_time % 10) + '0');
264 *p_out++ = ':';
265 *p_out++ = (char)((s_time / 10) + '0');
266 *p_out++ = (char)((s_time % 10) + '0');
267 *p_out++ = ':';
268 *p_out++ = (char)((ms_time / 10) + '0');
269 *p_out++ = (char)((ms_time % 10) + '0');
270 *p_out++ = ':';
271 *p_out = 0;
272
273 return tbuf;
274 }
275
276
277 /*******************************************************************************
278 **
279 ** Function rvf_get_tick_count
280 **
281 ** Description This function returns the current Nucleus system ticks
282 **
283 ** Returns ticks
284 **
285 *******************************************************************************/
286 UINT32 rvf_get_tick_count(void)
287 {
288 return NU_Retrieve_Clock();
289 }
290
291
292 /*******************************************************************************
293 **
294 ** Function rvf_start_timer
295 **
296 ** Description An application can call this function to start one of
297 ** it's four general purpose timers. Any of the four timers
298 ** can be 1-shot or continuous. If a timer is already running,
299 ** it will be reset to the new paramaters.
300 **
301 ** Returns void
302 **
303 *******************************************************************************/
304 void rvf_start_timer (UINT8 tnum, UINT32 ticks, BOOLEAN is_continuous)
305 { T_RVF_G_ADDR_ID task_id = rvf_get_taskid();
306
307 if(tnum==RVF_TIMER_3 || tnum==RVF_TIMER_2) { // reserved for rvf timer service
308 rvf_send_trace ("WARNING: Timers 2 & 3 are deprecated!",
309 37,
310 NULL_PARAM,
311 RV_TRACE_LEVEL_DEBUG_LOW,
312 0);
313 // return;
314 }
315 if (!ticks) // check if ticks == 0, set it to 1
316 { ticks = 1;
317 }
318
319 // disable Nucleus timer
320 NU_Control_Timer( &(rvf_Timer[task_id][tnum]),
321 NU_DISABLE_TIMER );
322
323 // reset the timer with the new settings
324 NU_Reset_Timer( &(rvf_Timer[task_id][tnum]),
325 _rvf_timer_expire,
326 ticks,
327 is_continuous? ticks:0, // if timer is continuous, reload it
328 NU_ENABLE_TIMER);
329 }
330
331 /*******************************************************************************
332 **
333 ** Function rvf_stop_timer
334 **
335 ** Description An application can call this function to stop one of
336 ** it's four general purpose timers. There is no harm in
337 ** stopping a timer that is already stopped.
338 **
339 ** Returns void
340 **
341 *******************************************************************************/
342 void rvf_stop_timer (UINT8 tnum)
343 { T_RVF_G_ADDR_ID task_id = rvf_get_taskid();
344
345 /* disable Nucleus timer */
346 NU_Control_Timer( &(rvf_Timer[task_id][tnum]),
347 NU_DISABLE_TIMER );
348 }
349
350 /*******************************************************************************
351 **
352 ** Function rvf_init_timer_list
353 **
354 ** Description This function is called by applications when they
355 ** want to initialize a timer list.
356 **
357 ** Returns void
358 **
359 *******************************************************************************/
360 void rvf_init_timer_list (T_RVF_TIMER_LIST_Q *p_timer_listq)
361 {
362 p_timer_listq->p_first = NULL;
363 p_timer_listq->p_last = NULL;
364 p_timer_listq->last_ticks = 0;
365 }
366
367 /*******************************************************************************
368 **
369 ** Function rvf_init_timer_list_entry
370 **
371 ** Description This function is called by the applications when they
372 ** want to initialize a timer list entry. This must be
373 ** done prior to first use of the entry.
374 **
375 ** Returns void
376 **
377 *******************************************************************************/
378 void rvf_init_timer_list_entry (T_RVF_TIMER_LIST_ENT *p_tle)
379 {
380 p_tle->p_next = NULL;
381 p_tle->p_prev = NULL;
382 p_tle->ticks = 0xFFFFFFFFL;
383 }
384
385
386 /*******************************************************************************
387 **
388 ** Function rvf_update_timer_list
389 **
390 ** Description This function is called by the applications when they
391 ** want to update a timer list. This should be at every
392 ** timer list unit tick, e.g. once per sec, once per minute etc.
393 **
394 ** Returns the number of timers that have expired
395 **
396 *******************************************************************************/
397 UINT16 rvf_revise_timer_list (T_RVF_G_ADDR_ID gid){
398 if(!pRtAddrIdTable[gid] );
399 // !pRtAddrIdTable[gid]->p_tm_q ||
400 // pRtAddrIdTable[gid]->p_tm_q->timerCnt==0 ||
401 // pRtAddrIdTable[gid]->polling_tm!=0 ) return 0; /* rvf abort */
402 // return rvf_update_timer_list(pRtAddrIdTable[gid]->p_tm_q); /* tms notify */
403 return 0;
404 }
405 UINT16 rvf_update_timer_list (T_RVF_TIMER_LIST_Q *p_timer_listq)
406 {
407 T_RVF_TIMER_LIST_ENT *p_tle;
408 UINT16 num_time_out = 0;
409
410 p_tle = p_timer_listq->p_first;
411
412 /* First, get the guys who have previously timed out */
413 while ((p_tle) && (p_tle->ticks == 0))
414 {
415 num_time_out++;
416 p_tle = p_tle->p_next;
417 }
418
419 /* Now, get the guys who have just timed out */
420 if ((p_tle) && (p_tle->ticks))
421 {
422 if (--p_tle->ticks == 0)
423 {
424 while (p_tle != NULL && p_tle->ticks == 0)
425 {
426 num_time_out++;
427 p_tle = p_tle->p_next;
428 }
429 }
430 }
431
432 if (p_timer_listq->last_ticks)
433 p_timer_listq->last_ticks--;
434
435 return (num_time_out);
436 }
437
438
439
440 /*******************************************************************************
441 **
442 ** Function rvf_add_to_timer_list
443 **
444 ** Description This function is called by an application to add a timer
445 ** entry to a timer list.
446 **
447 ** Returns void
448 **
449 *******************************************************************************/
450 void rvf_add_to_timer_list (T_RVF_TIMER_LIST_Q *p_timer_listq, T_RVF_TIMER_LIST_ENT *p_tle)
451 {
452 UINT32 nr_ticks_total;
453 T_RVF_TIMER_LIST_ENT *p_temp;
454
455 if (p_tle->ticks >= p_timer_listq->last_ticks)
456 {
457 if (p_timer_listq->p_first == NULL)
458 p_timer_listq->p_first = p_tle;
459 else
460 {
461 if (p_timer_listq->p_last != NULL)
462 p_timer_listq->p_last->p_next = p_tle;
463
464 p_tle->p_prev = p_timer_listq->p_last;
465 }
466
467 p_tle->p_next = NULL;
468 p_timer_listq->p_last = p_tle;
469 nr_ticks_total = p_tle->ticks;
470 p_tle->ticks = p_tle->ticks - p_timer_listq->last_ticks;
471
472 p_timer_listq->last_ticks = nr_ticks_total;
473 }
474 else
475 {
476 p_temp = p_timer_listq->p_first;
477 while (p_tle->ticks > p_temp->ticks)
478 {
479 p_tle->ticks = p_tle->ticks - p_temp->ticks;
480 p_temp = p_temp->p_next;
481 }
482 if (p_temp == p_timer_listq->p_first)
483 {
484 p_tle->p_next = p_timer_listq->p_first;
485 p_timer_listq->p_first->p_prev = p_tle;
486 p_timer_listq->p_first = p_tle;
487 }
488 else
489 {
490 p_temp->p_prev->p_next = p_tle;
491 p_tle->p_prev = p_temp->p_prev;
492 p_temp->p_prev = p_tle;
493 p_tle->p_next = p_temp;
494 }
495 p_temp->ticks = p_temp->ticks - p_tle->ticks;
496 }
497 }
498
499 /*******************************************************************************
500 **
501 ** Function rvf_remove_from_timer_list
502 **
503 ** Description This function is called by an application to remove a timer
504 ** entry from a timer list.
505 **
506 ** Returns void
507 **
508 *******************************************************************************/
509 void rvf_remove_from_timer_list (T_RVF_TIMER_LIST_Q *p_timer_listq, T_RVF_TIMER_LIST_ENT *p_tle)
510 {
511 if (p_tle == NULL || p_tle->ticks == 0xFFFFFFFFL || p_timer_listq->p_first == NULL)
512 {
513 return;
514 }
515
516 /* Add the ticks remaining in this timer to the next guy in the list.
517 */
518 if (p_tle->p_next != NULL)
519 {
520 p_tle->p_next->ticks += p_tle->ticks;
521 }
522 else
523 {
524 p_timer_listq->last_ticks -= p_tle->ticks;
525 }
526
527 /* Unlink timer from the list.
528 */
529 if (p_timer_listq->p_first == p_tle)
530 {
531 p_timer_listq->p_first = p_tle->p_next;
532
533 if (p_timer_listq->p_first != NULL)
534 p_timer_listq->p_first->p_prev = NULL;
535
536 if (p_timer_listq->p_last == p_tle)
537 p_timer_listq->p_last = NULL;
538 }
539 else
540 {
541 if (p_timer_listq->p_last == p_tle)
542 {
543 p_timer_listq->p_last = p_tle->p_prev;
544
545 if (p_timer_listq->p_last != NULL)
546 p_timer_listq->p_last->p_next = NULL;
547 }
548 else
549 {
550 if (p_tle->p_next != NULL && p_tle->p_next->p_prev == p_tle)
551 p_tle->p_next->p_prev = p_tle->p_prev;
552 else
553 {
554 /* Error case - chain messed up ?? */
555 return;
556 }
557
558 if (p_tle->p_prev != NULL && p_tle->p_prev->p_next == p_tle)
559 p_tle->p_prev->p_next = p_tle->p_next;
560 else
561 {
562 /* Error case - chain messed up ?? */
563 return;
564 }
565 }
566 }
567
568 p_tle->p_next = p_tle->p_prev = NULL;
569 p_tle->ticks = 0xFFFFFFFFL;
570 }
571
572
573 /*******************************************************************************
574 **
575 ** Function rvf_get_expired_entry
576 **
577 ** Description This function returns a pointer to the first expired entry in
578 ** the timer list queue.
579 ** If no entry in the queue has expired, it returns NULL.
580 **
581 ** Returns T_RVF_TIMER_LIST_ENT * : pointer to the expired entry if any.
582 **
583 *******************************************************************************/
584 T_RVF_TIMER_LIST_ENT * rvf_get_expired_entry (T_RVF_TIMER_LIST_Q *p_timer_listq)
585 {
586 T_RVF_TIMER_LIST_ENT * p_tle;
587 /* test if the first entry in the queue has expired */
588 if ( (p_timer_listq->p_first != NULL) && (p_timer_listq->p_first->ticks == 0) )
589 {
590
591 p_tle = p_timer_listq->p_first;
592 if(p_tle->t_init) {
593 p_tle->ticks=p_tle->t_init;
594 } else {
595 /* unlink entry from the list */
596 p_timer_listq->p_first = p_tle->p_next;
597
598 if (p_timer_listq->p_first != NULL)
599 p_timer_listq->p_first->p_prev = NULL;
600
601 if (p_timer_listq->p_last == p_tle)
602 p_timer_listq->p_last = NULL;
603
604 p_tle->p_next = NULL;
605 p_tle->p_prev = NULL;
606 p_tle->ticks = 0xFFFFFFFFL;
607 //return p_tle;
608 }
609 return p_tle;
610 }
611 else
612 { return NULL;
613 }
614 }
615
616
617
618
619
620
621
622
623