comparison gsm-fw/riviera/rvf/rvf_time.c @ 143:afceeeb2cba1

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