comparison src/cs/riviera/rvf/rvf_task.c @ 0:945cf7f506b2

src/cs: chipsetsw import from tcs211-fcmodem binary blobs and LCD demo files have been excluded, all line endings are LF only
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 25 Sep 2016 22:50:11 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:945cf7f506b2
1 /****************************************************************************/
2 /* */
3 /* Name rvf_task.c */
4 /* */
5 /* Function this file contains \rvf task related functions */
6 /* */
7 /* Version 0.1 */
8 /* */
9 /* Date Modification */
10 /* ------------------------------------ */
11 /* 3/12/99 Create */
12 /* 10/27/99 remove all non-nucleus sections (#ifdef) */
13 /* change tasks priority and time_slicing */
14 /* 11/17/1999 change RVF_create_task and RVF_get_taskid functions */
15 /* 30/11/99 compliant to RV coding guidelines */
16 /* 28/08/2000 add mutex related functions. */
17 /* */
18 /* Author David Lamy-Charrier (dlamy@tif.ti.com) */
19 /* */
20 /* (C) Copyright 1999 by Texas Instruments Incorporated, All Rights Reserved*/
21 /****************************************************************************/
22
23 #ifndef _WINDOWS
24 #include "config/rv.cfg"
25 #endif
26
27 #include "nucleus.h"
28
29 #include "rv/rv_general.h"
30 #include "rvf/rvf_api.h"
31 #include "rvf/rvf_i.h"
32 #include "rvm/rvm_i.h" /* ONLY for Task Codes */
33 #include "rvm/rvm_use_id_list.h"
34 #include <stdio.h>
35 #include <string.h>
36
37 /* include the rvtool_trace.h file only in the RivieraTool */
38 #ifdef _WINDOWS
39 #ifndef _CONSOLE
40 // #include "rvtool_trace.h"
41 #endif
42 #include <windows.h>
43 #endif
44
45 #define RVF_STATIC_ALLOC_NB 1
46
47 /**********************************************************************
48 ** Nucleus specific definitions
49 */
50
51 typedef void (*NU_TASK_ENTRY)(UNSIGNED, VOID *); //
52
53 /* array of tasks */
54 /**********************************************************************
55 * Note: if dynamic mem alloc of "pOSTCB" creates too much fragentation
56 * The origianl way me be utilised and pointed to by a addr_id table
57 * structure, which is proposed for type 2 support.
58 ***********************************************************************/
59
60 #define _RALLOC_TASK_CNTRL_BLK(tb) rvf_get_buf(rvm_sys_mem_bank, sizeof(NU_TASK), tb)
61 #define _RALLOC_TASK_EVT_GRP(tb) rvf_get_buf(rvm_sys_mem_bank, sizeof(NU_EVENT_GROUP), tb)
62 #define _RALLOC_TASK_RT_ADDR_DATA(tb) rvf_get_buf(rvm_sys_mem_bank, sizeof(T_RVF_RT_ADDR_ID_DATA), tb)
63 //#define _RALLOC_TASK_RT_TM(tb) rvf_get_buf(rvm_sys_mem_bank, sizeof(T_RVF_TIMER_LIST_Q), tb)
64
65 /*static NU_TASK bOSTCB[RVF_STATIC_ALLOC_NB];
66 static NU_EVENT_GROUP bOSEvtGrp[RVF_STATIC_ALLOC_NB];
67 static UINT8 *bOSStack;
68 static UINT16 bOSStackSize;
69 static char bOSTName[RVF_STATIC_ALLOC_NB][RVF_STATIC_ALLOC_NB];
70 */
71
72 static UINT8 task_counter = 0;
73 static INT16 OSDisableNesting = 0;
74 static BOOL OSInterruptAlreadyMasked = FALSE;
75 static INT32 OSLastIntLevel;
76 static T_RVF_G_ADDR_ID _RDV=RVF_INVALID_ADDR_ID;
77
78 T_RVF_RET _initSysRtData(void);
79
80
81 /*******************************************************************************
82 **
83 ** Function rvf_AllocTaskXyz()
84 **
85 ** Description
86 **
87 **
88 ** Returns T_RVF_MB_STATUS
89 **
90 *******************************************************************************/
91 T_RVF_RET _initSysRtData(void) { /*A-M-E-N-D-E-D!*/
92 int i=0;
93
94 for (i=0; i < MAX_RVF_G_ADDR_ID; i++) pRtAddrIdTable[i]=NULL;
95
96 // pOSTCB[0]=&OSTCB[0];
97 return RVF_OK;
98 }
99
100 /*******************************************************************************
101 **
102 ** Function rvf_init
103 **
104 ** Description This function is called once at startup to initialize
105 ** all the rvf (timer, buffer...).
106 **
107 ** Returns void
108 **
109 *******************************************************************************/
110 void rvf_init(void) {
111 /* UINT8 i; */
112
113 /* Initialize RVF variables */
114 /*for (i = 0; i < MAX_RVF_TASKS; i++) {
115 OSStack[i] = 0;
116 OSStackSize[i] = 0;
117 OSTName[i][0] = 0;
118 memset( &OSTCB[i], 0, sizeof(NU_TASK) );
119 memset( &OSEvtGrp[i], 0, sizeof(NU_EVENT_GROUP) );
120 }
121 // for (i = 0; i < 1; i++) memset( &OSTCB[i], 0, sizeof(NU_TASK) );
122 */
123 _initSysRtData();
124 _rvf_buffer_init();
125 _rvf_timers_init();
126 }
127
128 /*******************************************************************************
129 **
130 ** Function _rvf_name_cpy
131 **
132 ** Description Internal function which copy a string in a buffer.
133 ** The string may be null-terminated or length bytes long.
134 **
135 ** Returns void
136 **
137 *******************************************************************************/
138 void _rvf_name_cpy(char * dest, char * source, UINT8 length) {
139 UINT8 cpt;
140 for( cpt = 0; cpt < length ; cpt++) {
141 dest[cpt] = source[cpt];
142 if (source[cpt] == 0) { return;}
143 }
144 }
145
146 T_RVF_G_ADDR_ID rvf_get_context() {
147 T_RVF_G_ADDR_ID gid=rvf_get_taskid();
148 if(pRtAddrIdTable[gid]->type_code==ET2_HOST_TASK) {
149 return pRtAddrIdTable[gid]->virtualContext;
150 } else {
151 return pRtAddrIdTable[gid]->host_addr_id;
152 }
153 }
154
155 void rvf_setRDV(T_RVF_G_ADDR_ID tid,T_RVF_G_ADDR_ID vid) {
156 if(pRtAddrIdTable[tid]) pRtAddrIdTable[tid]->virtualContext=vid;
157 }
158
159
160 /**************************************************************
161 * Function _rvf_name_cpy
162 *
163 ***************************************************************/
164 T_RVF_G_ADDR_ID rvf_allocate_task_id(UINT8 isRealTask) {
165 T_RVF_G_ADDR_ID i=0;
166 UINT8 isTask=1;
167
168 /* Note: differentiation is made between REAL and VIRTUAL IDs
169 * to provide for backwards compatabible LEGACY timer implementations
170 * The Real task ids should be in sync with:
171 * "static rvf_Timer[MAX_RVF_TASKS][RVF_NUM_TASK_TIMERS]",
172 * defined in "rvf_time.c". In the future, one NU_Timer blk will
173 * be pointed to in the rt global addr table. Hence, eliminating
174 * the large resource of "rvf_Timer[][]"
175 */
176 if(!pRtAddrIdTable[i]) return RVF_INVALID_ADDR_ID;
177
178 if(isRealTask) {
179 /* REAL TASK */
180 for(i=0; pRtAddrIdTable[i]!=NULL && i<MAX_RVF_TASKS; i++);
181
182 if (i < MAX_RVF_TASKS) { /* alloc. and init. */
183 if(_RALLOC_TASK_RT_ADDR_DATA((T_RVF_BUFFER**)&pRtAddrIdTable[i])) return RVF_INVALID_TASK;
184 memset( pRtAddrIdTable[i], 0, sizeof(T_RVF_RT_ADDR_ID_DATA) );
185 rvf_mbox_buffer_init(pRtAddrIdTable[i]);
186
187 } else return RVF_INVALID_ADDR_ID;
188 } else {
189 /* VIRTUAL TASK */
190 for(i=MAX_RVF_TASKS; pRtAddrIdTable[i]!=NULL && i<MAX_RVF_G_ADDR_ID; i++);
191
192 if (i < MAX_RVF_G_ADDR_ID) { /* alloc. and init. */
193 if(_RALLOC_TASK_RT_ADDR_DATA((T_RVF_BUFFER**)&pRtAddrIdTable[i])) return RVF_INVALID_TASK;
194 memset( pRtAddrIdTable[i], 0, sizeof(T_RVF_RT_ADDR_ID_DATA) );
195 rvf_mbox_buffer_init(pRtAddrIdTable[i]);
196
197 } else return RVF_INVALID_ADDR_ID;
198 }
199
200 return i;
201 }
202
203 /* MUST RESOLVE ERROR CODES '1' is just for P of C */
204 T_RVF_RET rvf_setRtAddrSweIndex(T_RVF_G_ADDR_ID id, UINT8 sweIndex) {
205 if(id>=MAX_RVF_G_ADDR_ID) return 1;
206 pRtAddrIdTable[id]->swe_db_index=sweIndex;
207 // pRtAddrIdTable[id]->type_code=tcode; /* allows type to be set if not in swe */
208 return RVF_OK;
209 }
210
211 T_RVF_RET rvf_setHostTaskStackPtr(T_RVF_G_ADDR_ID id, UINT8* pStack) { /* deprecated ! */
212 if(id>=MAX_RVF_TASKS) return 1;
213 pRtAddrIdTable[id]->p_os_stack=pStack;
214
215 return RVF_OK;
216 }
217
218 T_RVF_RET rvf_isHostingTaskIdle(T_RVF_G_ADDR_ID id, UINT8* status) { /* deprecated ! */
219 if(id>=MAX_RVF_TASKS) return RVF_INVALID_PARAMETER;
220 if(!pRtAddrIdTable[id]) return RVF_INVALID_PARAMETER;
221 if(pRtAddrIdTable[id]->type_code!=ET2_HOST_TASK) return RVF_INVALID_PARAMETER;
222
223 if(pRtAddrIdTable[id]->hosting_count==0) *status=1;
224 return RVF_OK;
225 }
226
227 /* convenience/helper fnc. */
228 T_RVF_G_ADDR_ID resolveHostAddrId(T_RVF_G_ADDR_ID id) {
229 if(!pRtAddrIdTable[id]) return RVF_INVALID_ADDR_ID;
230 return pRtAddrIdTable[id]->host_addr_id;
231 }
232
233 /* HostingCounter enables one to deduce if task can be terminated */
234 /* ERROR return val must be revised */
235 T_RVF_RET rvf_registerToHost(T_RVF_G_ADDR_ID host_id, T_RVF_G_ADDR_ID eid) {
236 UINT8 i;
237
238 if (host_id >= MAX_RVF_TASKS || eid >= MAX_RVF_G_ADDR_ID ) return RV_INVALID_PARAMETER;;
239
240 for(i=0;pRtAddrIdTable[host_id]->parasites[i]!=0 && i < MAX_PARASITES; i++);
241
242 pRtAddrIdTable[host_id]->parasites[i]=eid;
243 pRtAddrIdTable[host_id]->hosting_count++;
244
245 return RVF_OK;
246 }
247
248 T_RVF_RET rvf_unregisterFromHost(T_RVF_G_ADDR_ID host_id, T_RVF_G_ADDR_ID pid) {
249 UINT8 i=0;
250 if (pRtAddrIdTable[host_id]->hosting_count !=0) {
251 for(i=0; i<MAX_PARASITES || pRtAddrIdTable[host_id]->parasites[i]==pid; i++);
252 pRtAddrIdTable[host_id]->parasites[i]=0;
253
254 pRtAddrIdTable[host_id]->hosting_count--;
255 } else return RV_INVALID_PARAMETER;
256
257 return RVF_OK;
258 }
259
260 T_RVF_RET rvf_associateGrpToHost(T_RVF_G_ADDR_ID host_id, T_RVF_GD_ID gd_id) {
261
262 if (host_id >= MAX_RVF_TASKS ) return RV_INVALID_PARAMETER;
263
264 pRtAddrIdTable[host_id]->gdHost=gd_id;
265
266 return RVF_OK;
267 }
268
269 /*T_RVF_RET rvf_unregisterGrpFromHost(T_RVF_G_ADDR_ID host_id, T_RVF_G_ADDR_ID pid) {
270 if (pRtAddrIdTable[host_id]->hosting_count !=0) {
271 pRtAddrIdTable[host_id]->parasites[pid]=0;
272 pRtAddrIdTable[host_id]->hosting_count--;
273 } else return RV_INVALID_PARAMETER;
274
275 return RVF_OK;
276 }*/
277
278 T_RVF_G_ADDR_ID rvf_resolveHostingAddrId(T_RVM_GROUP_DIRECTIVE gd) {
279 int i=0;
280
281 for(i=1; i<MAX_RVF_TASKS; i++) { // i=1 by-pass RVM task
282 if(pRtAddrIdTable[i]!=NULL) {
283 if( pRtAddrIdTable[i]->type_code==ET2_HOST_TASK &&
284 // pRtAddrIdTable[i]->priority==priority && // to do ...
285 // pRtAddrIdTable[i]->os_stack_size>=stack_size
286 pRtAddrIdTable[i]->gdHost==gd.group_directive &&
287 pRtAddrIdTable[i]->hosting_count<MAX_PARASITES ) return i; // def. 10 A+ .
288 }
289 }
290
291 return RVF_INVALID_ADDR_ID; /* nothing found ret. param must be invalid*/
292 }
293
294 /*********************************************************************
295 * start() and stop() should be added to params, due to defered calling
296 * Allow for parasites to be added at RT and their start to be called.
297 *********************************************************************/
298 T_RVF_RET rvf_create_virtual_task (T_RV_RET (* handle_message)(T_RV_HDR * msg),
299 T_RV_RET (* handle_timer)(T_RV_HDR * msg),
300 T_RVF_G_ADDR_ID task_id, T_RVF_G_ADDR_ID host_task_id, char *taskname,
301 UINT8 priority, UINT8 tcode) {
302
303 if(!pRtAddrIdTable[task_id]) { /* allow for static init. or previous dyn init, eg. idle*/
304 if(_RALLOC_TASK_RT_ADDR_DATA((T_RVF_BUFFER**)&pRtAddrIdTable[task_id])) return RVF_INTERNAL_ERR;
305 memset( pRtAddrIdTable[task_id], 0, sizeof(T_RVF_RT_ADDR_ID_DATA) );
306
307 rvf_mbox_buffer_init(pRtAddrIdTable[task_id]);
308 } /*else printf("RVF: task rt addr %d already alloc'ed\n", task_id); */
309
310 pRtAddrIdTable[task_id]->host_addr_id=host_task_id;
311 pRtAddrIdTable[task_id]->symbolic_name=taskname;
312 pRtAddrIdTable[task_id]->handle_message=handle_message;
313 pRtAddrIdTable[task_id]->handle_timer=handle_timer;
314 pRtAddrIdTable[task_id]->type_code=tcode;
315
316 pRtAddrIdTable[task_id]->pOSTCB=NULL; /* init to NULL for res.'free' */
317 pRtAddrIdTable[task_id]->pOSEvtGrp=NULL;
318 pRtAddrIdTable[task_id]->p_os_stack=NULL;
319 // pRtAddrIdTable[task_id]->p_tm_q=NULL;
320
321 // rvf_registerToHost(host_task_id, task_id);
322
323 return RVF_OK;
324 }
325
326 T_RVF_RET rvf_register_t3_handlers (T_RVF_G_ADDR_ID task_id,
327 T_RV_RET (* handle_message)(T_RV_HDR * msg),
328 T_RV_RET (* handle_timer)(T_RV_HDR * msg) ) {
329
330 pRtAddrIdTable[task_id]->handle_message=handle_message;
331 pRtAddrIdTable[task_id]->handle_timer=handle_timer;
332
333 return RVF_OK;
334 }
335
336 /* RVM must create a stack with its MB and pass as params to task create */
337 /*T_RVF_RET rvf_create_host_task (T_RV_RET (* proxy)(void), T_RVF_G_ADDR_ID task_id,
338 char *taskname, UINT8 *stack, UINT16 stacksize,
339 UINT8 priority, UINT8 tcode, UINT8 time_slicing, T_RVF_TASK_STATE suspend) {
340
341 return rvf_create_task( (TASKPTR)proxy, task_id, taskname, stack, stacksize,\
342 priority, tcode, time_slicing, suspend ) ;
343
344 }*/
345
346 /*******************************************************************************
347 **
348 ** Function rvf_create_task
349 **
350 ** Description This function is called to create a new rvf task.
351 ** time_slice represents the number of Nucleus ticks before a task is interrupted.
352 ** 0 for no time-slicing.
353 **
354 ** Returns RVF_OK if successful, else an error code
355 **
356 *******************************************************************************/
357 T_RVF_RET rvf_create_legacy_task (TASKPTR task_entry, UINT8 task_id, char *taskname, UINT8 *stack, UINT16 stacksize, UINT8 priority, UINT8 time_slicing, T_RVF_TASK_STATE is_suspend) {
358
359 return rvf_create_task(task_entry,task_id,taskname,stack,stacksize,priority,ET4_TASK,time_slicing,is_suspend);
360 }
361
362 T_RVF_RET rvf_create_task (TASKPTR task_entry, T_RVF_G_ADDR_ID task_id, char *taskname, UINT8 *stack, UINT16 stacksize,
363 UINT8 priority, UINT8 tcode, UINT8 time_slicing, T_RVF_TASK_STATE suspend) {
364
365 /*if (task_id >= MAX_RVF_TASKS) { return 1; } */
366 if (task_counter >= MAX_RVF_TASKS) { return 1; }
367
368 /* fill the task stack with a 0xFE pattern to allow use with stack monitoring tool */
369 memset( stack, 0xFE, stacksize );
370
371 /* allow for immediate task creation, eg. no alloc taskId(), but #defined task No. Dangerous!*/
372 if(!pRtAddrIdTable[task_id]) {
373 if(_RALLOC_TASK_RT_ADDR_DATA((T_RVF_BUFFER**)&pRtAddrIdTable[task_id])) return RVF_INTERNAL_ERR;
374 memset( pRtAddrIdTable[task_id], 0, sizeof(T_RVF_RT_ADDR_ID_DATA) );
375
376 rvf_mbox_buffer_init(pRtAddrIdTable[task_id]);
377 } /*else printf("RVF: task rt addr %d already alloc'ed\n", task_id); */
378
379 /*if(_RALLOC_TASK_RT_TM((T_RVF_BUFFER**)&pRtAddrIdTable[task_id]->p_tm_q)) {
380 rvf_free_buf(pRtAddrIdTable[task_id]);
381 pRtAddrIdTable[task_id]=NULL;
382 return RVF_INTERNAL_ERR;
383 } else pRtAddrIdTable[task_id]->p_tm_q->timerCnt=0;*/
384
385 pRtAddrIdTable[task_id]->hosting_count=0;
386 pRtAddrIdTable[task_id]->host_addr_id=task_id;
387 pRtAddrIdTable[task_id]->symbolic_name=taskname;
388 pRtAddrIdTable[task_id]->priority=priority;
389 pRtAddrIdTable[task_id]->type_code=tcode;
390
391 memset(&pRtAddrIdTable[task_id]->parasites, 0, (sizeof(T_RVF_G_ADDR_ID)*MAX_PARASITES));
392
393 if (stack) {
394 pRtAddrIdTable[task_id]->p_os_stack = (UINT8 *)stack;// - stacksize;
395 pRtAddrIdTable[task_id]->os_stack_size = stacksize;
396 } else {
397 // rvf_free_buf(pRtAddrIdTable[task_id]->p_tm_q);
398 rvf_free_buf(pRtAddrIdTable[task_id]);
399 pRtAddrIdTable[task_id]=NULL;
400 return RVF_INTERNAL_ERR;
401 }
402
403 if(_RALLOC_TASK_CNTRL_BLK((T_RVF_BUFFER**)&pRtAddrIdTable[task_id]->pOSTCB)) {
404 rvf_free_buf(stack);
405 // rvf_free_buf(pRtAddrIdTable[task_id]->p_tm_q);
406 rvf_free_buf(pRtAddrIdTable[task_id]);
407 pRtAddrIdTable[task_id]=NULL;
408 return RVF_INTERNAL_ERR;
409 }
410 memset( pRtAddrIdTable[task_id]->pOSTCB, 0, sizeof(NU_TASK) );
411
412 if(_RALLOC_TASK_EVT_GRP((T_RVF_BUFFER**)&pRtAddrIdTable[task_id]->pOSEvtGrp)) {
413 rvf_free_buf(pRtAddrIdTable[task_id]->pOSTCB);
414 rvf_free_buf(stack);
415 // rvf_free_buf(pRtAddrIdTable[task_id]->p_tm_q);
416 rvf_free_buf(pRtAddrIdTable[task_id]);
417 pRtAddrIdTable[task_id]=NULL;
418 return RVF_INTERNAL_ERR;
419 }
420 memset( pRtAddrIdTable[task_id]->pOSEvtGrp, 0, sizeof(NU_EVENT_GROUP) );
421
422 /* Create one Event Group for this task */
423 if( NU_SUCCESS != \
424 NU_Create_Event_Group (pRtAddrIdTable[task_id]->pOSEvtGrp,\
425 taskname) ) {
426 return RVF_INTERNAL_ERR;
427 }
428
429 //}
430 /* Create Task */
431 if ( NU_SUCCESS !=
432 NU_Create_Task (pRtAddrIdTable[task_id]->pOSTCB, /* Task Control Block */
433 taskname, /*taskname,*/ /* Task Name */
434 (NU_TASK_ENTRY )task_entry, /* Task Entry Function */
435 0, /* why prev. task_id ??? */ /* ARGC A-M-E-N-D-E-D! */
436 NULL, /* ARGV */
437 pRtAddrIdTable[task_id]->p_os_stack, /* Begining of Stack */
438 pRtAddrIdTable[task_id]->os_stack_size, /* Stack size */
439 priority, /* Priority */
440 time_slicing, /* Time Slicing Period*/
441 NU_PREEMPT, /* Preemption allowed */
442 (OPTION)(suspend == RUNNING ? NU_START : NU_NO_START) )/* Start the task or suspend it */
443 ) {
444 return RVF_INTERNAL_ERR;
445 }
446 task_counter++; /* MUST 'DEC' ON TASK TERMINATION */
447
448 return RVF_OK;
449 }
450
451 /* to be called from func. 'create_tasks()' of module "create_RVtasks.c"
452 * utilises static alloated system variables */
453 /*T_RVF_RET rvf_create_boot_task (TASKPTR task_entry, UINT8 task_id, char *taskname, UINT8 *stack, UINT16 stacksize, UINT8 priority, UINT8 time_slicing, T_RVF_TASK_STATE suspend) {
454 if (task_id >= MAX_RVF_TASKS) { return 1;}
455
456 if (stack) {
457 bOSStack = (UINT8 *)stack;// - stacksize;
458 bOSStackSize = stacksize;
459 }
460 // copy the task name into an internal buffer
461 _rvf_name_cpy( &(bOSTName[0][0]), taskname, RVF_MAX_TASK_LEN);
462
463 // fill the task stack with a 0xFE pattern to allow use with stack monitoring tool
464 memset( stack, 0xFE, stacksize );
465
466 // Create one Event Group for this task
467 if( NU_SUCCESS != NU_Create_Event_Group (&bOSEvtGrp[0], taskname) ){
468 return RVF_INTERNAL_ERR;
469 }
470
471 // Create Task
472 if ( NU_SUCCESS !=
473 NU_Create_Task (&bOSTCB[0], // (reserved)Task Control Block
474 taskname, // Task Name
475 (NU_TASK_ENTRY )task_entry, // Task Entry Function
476 task_id, // ARGC
477 NULL, // ARGV
478 bOSStack, // Begining of Stack
479 stacksize, // Stack size
480 priority, // Priority
481 time_slicing, // Time Slicing Period
482 NU_PREEMPT, // Preemption allowed
483 (OPTION)(suspend == RUNNING ? NU_START : NU_NO_START) )// Start the task or suspend it
484 )
485 { return RVF_INTERNAL_ERR;
486 }
487 task_counter++;
488 return RVF_OK;
489 }*/
490
491 /* Later timer blk must be added, once made dynamic */
492 T_RVF_RET rvf_free_sys_resources(T_RVF_G_ADDR_ID gid, UINT8 rm) {
493
494 if(!pRtAddrIdTable[gid]) return RVF_INTERNAL_ERR;
495
496 if(rm==1 || rm==2) {
497 if(pRtAddrIdTable[gid]->pOSTCB)rvf_free_buf(pRtAddrIdTable[gid]->pOSTCB);
498 if(pRtAddrIdTable[gid]->pOSEvtGrp)rvf_free_buf(pRtAddrIdTable[gid]->pOSEvtGrp);
499 if(pRtAddrIdTable[gid]->p_os_stack)rvf_free_buf(pRtAddrIdTable[gid]->p_os_stack);
500
501 task_counter--;
502 }
503 if(rm==0 || rm==2) {
504 if(pRtAddrIdTable[gid])rvf_free_buf(pRtAddrIdTable[gid]);
505 pRtAddrIdTable[gid]=NULL;
506 }
507
508 return RVF_OK;
509 }
510
511 /*******************************************************************************
512 **
513 ** Function rvf_exit_task
514 **
515 ** Description This function is called to stop a rvf task.
516 ** A task can kill another task or itself.
517 **
518 ** Returns void
519 **
520 *******************************************************************************/
521 void rvf_exit_task (T_RVF_G_ADDR_ID task_id)
522 {
523 if(!pRtAddrIdTable[task_id]) return;
524 /*
525 ** Empty task's mail box
526 */
527 _rvf_empty_mailboxes(task_id);
528
529 /*
530 ** Terminate task
531 */
532 NU_Terminate_Task(pRtAddrIdTable[task_id]->pOSTCB); /*&OSTCB[task_id]);*/
533 NU_Delete_Task(pRtAddrIdTable[task_id]->pOSTCB);
534
535 /*
536 ** Delete related event group
537 */
538 NU_Delete_Event_Group (pRtAddrIdTable[task_id]->pOSEvtGrp);
539
540 pRtAddrIdTable[task_id]->p_os_stack=0;
541 //OSStack[task_id] = 0;
542 }
543
544
545 /*******************************************************************************
546 **
547 ** Function rvf_suspend_task
548 **
549 ** Description This function is called to suspend a rvf task.
550 ** A task can suspend another task or itself.
551 **
552 ** Returns void
553 **
554 *******************************************************************************/
555 T_RVF_RET rvf_suspend_task (T_RVF_G_ADDR_ID task_id)
556 {
557 if(!pRtAddrIdTable[task_id]) return RVF_INVALID_PARAMETER;
558 NU_Suspend_Task(pRtAddrIdTable[task_id]->pOSTCB); // A-M-E-N-D-E-D!
559
560 return RVF_OK;
561 }
562
563
564 /*******************************************************************************
565 **
566 ** Function rvf_wait
567 **
568 ** Description This function is called by tasks to wait for a specific
569 ** event or set of events. The task may specify the duration
570 ** that it wants to wait for, or 0 if infinite.
571 **
572 ** Returns the event mask of received events or zero if timeout
573 **
574 *******************************************************************************/
575 UINT16 rvf_wait (UINT16 flag, UINT32 timeout) {
576 T_RVF_G_ADDR_ID rtask = rvf_get_taskid();
577
578 if (!timeout) timeout = 0xFFFFFFFFL;
579
580 return rvf_evt_wait(rtask, flag, timeout);
581 }
582
583 UINT16 rvf_evt_wait(T_RVF_G_ADDR_ID rtask, UINT16 flag, UINT32 timeout) {
584
585 #define RVF_RET_TIME_OUT 0
586
587 UINT16 mbxEvt = 0;
588 UNSIGNED evt = 0;
589 UNSIGNED clear = 0;
590 STATUS status_ret;
591
592 /* Check if anything in any of the mailboxes. Possible race condition. */
593
594 if (rtask>=MAX_RVF_TASKS || !pRtAddrIdTable[rtask]) {
595 RVM_TRACE_WARNING_PARAM("RVF: Illegal MBOX or MBOX not ready!", rtask);
596 return (UINT16) RVF_RET_TIME_OUT;
597 }
598
599 if (pRtAddrIdTable[rtask] && pRtAddrIdTable[rtask]->OSTaskQFirst[0])
600 mbxEvt |= RVF_TASK_MBOX_0_EVT_MASK;
601 if (pRtAddrIdTable[rtask] && pRtAddrIdTable[rtask]->OSTaskQFirst[1])
602 mbxEvt |= RVF_TASK_MBOX_1_EVT_MASK;
603 if (pRtAddrIdTable[rtask] && pRtAddrIdTable[rtask]->OSTaskQFirst[2])
604 mbxEvt |= RVF_TASK_MBOX_2_EVT_MASK;
605 if (pRtAddrIdTable[rtask] && pRtAddrIdTable[rtask]->OSTaskQFirst[3])
606 mbxEvt |= RVF_TASK_MBOX_3_EVT_MASK;
607
608 /* If any valid event if pending, return immediately */
609 if (mbxEvt & flag)
610 {
611 /* Return only those bits which user wants... */
612 evt = (UINT16) (mbxEvt & flag);
613
614 /* clear the nucleus event(s) for mailboxes */
615 if ( mbxEvt & 0x000F ) /* a mailbox event is signaled*/
616 { NU_Retrieve_Events (pRtAddrIdTable[rtask]->pOSEvtGrp, (UNSIGNED) mbxEvt & 0x000F, NU_AND_CONSUME,
617 (UNSIGNED *)&clear, NU_NO_SUSPEND);
618 }
619
620
621 return ((UINT16) evt);
622 }
623
624
625 if(pRtAddrIdTable[rtask]) {
626 status_ret = NU_Retrieve_Events (pRtAddrIdTable[rtask]->pOSEvtGrp,
627 (UNSIGNED) flag, NU_OR_CONSUME,
628 (UNSIGNED *)&evt, timeout );
629 if ( status_ret == NU_SUCCESS) {
630 return (UINT16) evt;
631 } else { /* timeout or error case */
632 return (UINT16) RVF_RET_TIME_OUT;
633 }
634 } return (UINT16) RVF_RET_TIME_OUT;
635 }
636
637 /*******************************************************************************
638 **
639 ** Function rvf_wait_for_specific_msg
640 **
641 ** Description This function is called by tasks to wait for a specific
642 ** message in the specified mailbox. The task may specify the duration
643 ** that it wants to wait for, or 0 if infinite.
644 **
645 ** Returns A pointer to the message, NULL in case of time-out.
646 **
647 *******************************************************************************/
648 T_RVF_BUFFER * rvf_wait_for_specific_msg(UINT16 msg_code, UINT8 mbox, UINT32 timeout)
649 {
650 T_RVF_G_ADDR_ID task_id = rvf_get_taskid();
651 T_RVF_BUFFER * p_buf = NULL;
652 T_RVF_INTERNAL_BUF * p_hdr;
653 UNSIGNED clear = 0;
654 STATUS status_ret;
655 UINT32 wait_time;
656 UINT32 init_time = rvf_get_tick_count();
657
658
659 /* check input parameter */
660 if ( mbox >= RVF_NUM_TASK_MBOX) /* NOTE: must be def to 2 max */
661 { rvf_send_trace( "RVF: rvf_wait_for_specific_msg(): invalid mailbox id", 52, NULL_PARAM, RV_TRACE_LEVEL_ERROR, RVM_USE_ID);
662 return p_buf;
663 }
664
665 if(!timeout)
666 timeout = 0xFFFFFFFFL;
667 wait_time = timeout;
668
669 while( (rvf_get_tick_count() - init_time) < timeout )
670 {
671 /* test all messages in the mailbox */
672 if( pRtAddrIdTable[task_id]->OSTaskQFirst[mbox] )
673 {
674 rvf_disable(9);
675 p_hdr = pRtAddrIdTable[task_id]->OSTaskQFirst[mbox];
676 p_buf = MEM2USER(p_hdr);
677 /* test the first one */
678 if ( ((T_RV_HDR *)p_buf)->msg_id == msg_code )
679 { /* message found, return it */
680 pRtAddrIdTable[task_id]->OSTaskQFirst[mbox] = p_hdr->p_next;
681 p_hdr->p_next = NULL;
682
683 #if RVF_ENABLE_BUF_LINKAGE_CHECK
684 RVF_SET_BUF_UNLINKED(p_hdr);
685 #endif
686 /* clear the Nucleus Event for this mailbox */
687 NU_Retrieve_Events( pRtAddrIdTable[task_id]->pOSEvtGrp, EVENT_MASK(mbox), NU_AND_CONSUME,
688 (UNSIGNED *)&clear, NU_NO_SUSPEND);
689 rvf_enable();
690 return p_buf;
691 }
692
693 while(p_hdr->p_next != NULL)
694 {
695 p_buf = MEM2USER(p_hdr->p_next);
696 if ( ((T_RV_HDR *)p_buf)->msg_id == msg_code )
697 { /* remove it from the list */
698 p_hdr->p_next = ( (T_RVF_INTERNAL_BUF *) USER2MEM(p_buf))->p_next;
699 /* check if it the last one */
700 if ( pRtAddrIdTable[task_id]->OSTaskQLast[mbox] == USER2MEM(p_buf) )
701 { pRtAddrIdTable[task_id]->OSTaskQLast[mbox] = p_hdr;
702 }
703 ((T_RVF_INTERNAL_BUF *) USER2MEM(p_buf))->p_next = NULL;
704
705 #if RVF_ENABLE_BUF_LINKAGE_CHECK
706 RVF_SET_BUF_UNLINKED(USER2MEM(p_buf));
707 #endif
708 rvf_enable();
709 return p_buf;
710 }
711 p_hdr = p_hdr->p_next;
712 }
713
714 rvf_enable();
715 }
716
717 /* here, the message has not been found, so wait for a new message */
718
719 if ((wait_time != 0xFFFFFFFFL) &&
720 (timeout > rvf_get_tick_count() - init_time))
721 {
722 /* NU_Retrieve_Events bug: cannot call function with a parameter with F in MSB */
723 wait_time = (timeout - (rvf_get_tick_count() - init_time)) & 0x0FFFFFFFL;
724 }
725
726 status_ret = NU_Retrieve_Events( pRtAddrIdTable[task_id]->pOSEvtGrp, EVENT_MASK(mbox), NU_OR_CONSUME,
727 (UNSIGNED *)&clear, wait_time);
728
729 if( status_ret != NU_SUCCESS) /* time out */
730 { return NULL;
731 }
732
733 }
734 return NULL;
735 }
736
737
738 /*******************************************************************************
739 **
740 ** Function rvf_delay
741 **
742 ** Description This function is called by tasks to sleep unconditionally
743 ** for a specified amount of time.
744 **
745 ** Returns void
746 **
747 *******************************************************************************/
748 void rvf_delay (UINT32 timeout)
749 {
750 if (timeout == 0)
751 { timeout = 1;
752 }
753
754 NU_Sleep(timeout);
755
756 }
757
758
759 /*******************************************************************************
760 **
761 ** Function rvf_send_event
762 **
763 ** Description This function is called by tasks to send events to other
764 ** tasks. Tasks can also send events to themselves.
765 **
766 ** Returns 0 if all OK, else 1
767 **
768 *******************************************************************************/
769 UINT8 rvf_send_event (T_RVF_G_ADDR_ID task_id, UINT16 event) {
770
771 if (task_id >= MAX_RVF_TASKS || !pRtAddrIdTable[task_id] ) return 1;
772
773 NU_Set_Events (pRtAddrIdTable[task_id]->pOSEvtGrp, (UNSIGNED)event, NU_OR);
774
775 return 0;
776 }
777
778 /*******************************************************************************
779 **
780 ** Function rvf_get_taskid
781 **
782 ** Description This function gets the currently running task ID.
783 **
784 ** Returns task ID
785 **
786 *******************************************************************************/
787 T_RVF_G_ADDR_ID rvf_get_taskid(void) { /* Retrieve the taskid using index of the task pointer in the OSTCB array */
788 NU_TASK * currTask=0;
789 T_RVF_G_ADDR_ID taskId=RVF_INVALID_ADDR_ID;
790
791 currTask = NU_Current_Task_Pointer();
792
793 if( currTask != NU_NULL) {
794 /* find the task pointer in the OSTCB array */
795 for ( taskId = 0; taskId < MAX_RVF_TASKS; taskId++) {
796 if( (pRtAddrIdTable[taskId]!= NULL) &&
797 ((pRtAddrIdTable[taskId]->pOSTCB)) == currTask) return taskId;
798 }
799 return RVF_INVALID_ADDR_ID;
800 } else {
801 return RVF_INVALID_ADDR_ID; /* error case, must return an error code */
802 }
803 }
804
805
806 /*******************************************************************************
807 **
808 ** Function rvf_get_taskname
809 **
810 ** Description This function gets the currently running task name.
811 **
812 ** Returns pointer to task name or NULL if error
813 **
814 *******************************************************************************/
815 char* rvf_get_taskname(void)
816 { T_RVF_G_ADDR_ID id = rvf_get_taskid();
817
818 if (id == 0xFF) return NULL; /* return NULL if rvf_get_taskid returns 0xFF */
819
820 return pRtAddrIdTable[id]->symbolic_name; /*(OSTName[ id ]);*/
821 }
822
823 /*******************************************************************************
824 **
825 ** Function rvf_enable
826 **
827 ** Description This function enables interrupts.
828 **
829 ** Returns void
830 **
831 *******************************************************************************/
832 void rvf_enable(void)
833 {
834
835 if( --OSDisableNesting == 0) /* Control nesting interrupt */
836 {
837 if( OSInterruptAlreadyMasked == TRUE) /* check if interrupts have been disabled outside RVF,
838 in that case, do not enable interrupts */
839 { OSInterruptAlreadyMasked = FALSE;
840 }
841 else
842 { NU_Control_Interrupts(OSLastIntLevel);
843 }
844 }
845
846 }
847
848 #ifdef _WINDOWS
849
850 /*******************************************************************************
851 **
852 ** Function INT_Check_IRQ_Mask()
853 **
854 ** Description This function checks if the IRQ are disabled (outside RVF).
855 **
856 ** Returns IRQ mask
857 **
858 *******************************************************************************/
859 UINT32 INT_Check_IRQ_Mask(void)
860 {
861 return 0;
862 }
863 #else
864
865 /*-------------------------------------------------------*/
866 /* INT_Check_IRQ_Mask() */
867 /*-------------------------------------------------------*/
868 /* */
869 /* Description: check in the CPSR register if the IRQ */
870 /* are masked out or not. */
871 /* ------------ */
872 /* */
873 /*-------------------------------------------------------*/
874 /* Declaration of ASM INT_Check_IRQ_Mask function */
875 UINT32 INT_Check_IRQ_Mask(void);
876
877 asm(" .def $INT_Check_IRQ_Mask");
878 asm("$INT_Check_IRQ_Mask ");
879 asm(" .ref _INT_32_Check_IRQ_Mask");
880 asm(".state16");
881 asm(" ADR r0,_INT_32_Check_IRQ_Mask ");
882 asm(" BX r0 ");
883
884 asm(" .align");
885 asm(" .state32");
886 asm(" .def _INT_32_Check_IRQ_Mask");
887 asm("_INT_32_Check_IRQ_Mask ");
888
889 asm(" MRS r0,CPSR "); // pick up CPSR
890 asm(" BX lr "); // return to caller
891
892 #endif
893
894
895 /*******************************************************************************
896 **
897 ** Function rvf_disable
898 **
899 ** Description This function disables interrupts.
900 **
901 ** Returns void
902 **
903 *******************************************************************************/
904
905 #define RVF_IRQ_DISABLED_MASK 0x00000080
906
907 void rvf_disable(UINT8 who)
908 {
909
910 /* Control interrupt nesting ourselves */
911 if (OSDisableNesting == 0)
912 {
913 if ( INT_Check_IRQ_Mask() & RVF_IRQ_DISABLED_MASK) /* if IRQ are disabled (outside RVF) */
914 { OSInterruptAlreadyMasked = TRUE;
915 }
916 else
917 { OSLastIntLevel = NU_Control_Interrupts(NU_DISABLE_INTERRUPTS);
918 }
919 }
920 OSDisableNesting++;
921
922 }
923
924
925 /*******************************************************************************
926 **
927 ** Function rvf_used_stack
928 **
929 ** Description This function tries to calculate the amount of
930 ** stack used by looking for a zero.
931 **
932 ** Returns the number of non-zero bytes on the stack
933 **
934 *******************************************************************************/
935 UINT16 rvf_used_stack(T_RVF_G_ADDR_ID task)
936 {
937 UINT16 j, stacksize;
938 UINT8 *p;
939
940 if(!pRtAddrIdTable[task]) return 0;
941
942 stacksize = pRtAddrIdTable[task]->os_stack_size; /*OSStackSize[task];*/
943 p = pRtAddrIdTable[task]->p_os_stack; /*OSStack[task];*/
944 for(j = 0; (j < stacksize) && (*p++ == 0xFE); j++);
945
946 return ((UINT16)(stacksize - j));
947 }
948
949
950 /*******************************************************************************
951 **
952 ** Function rvf_dump_tasks
953 **
954 ** Description This function dump all the rvf tasks.
955 **
956 ** Returns void
957 **
958 *******************************************************************************/
959 void rvf_dump_tasks()
960 { UINT8 num_task;
961 char task_info[100];
962
963 rvf_send_trace("*** START DUMPING TASKS ***", 27, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
964
965 /* for each task, display its name, its id, its stack size*/
966 rvf_send_trace("*TASK_NAME Id Stack_size Used_stack", 35, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
967
968 for ( num_task = 0; num_task < MAX_RVF_G_ADDR_ID; num_task++ )
969 {
970 /* trace the task if it has been created*/
971 if (pRtAddrIdTable[num_task] != 0 ) {
972 sprintf( task_info, "%10.10s %2d %5d %5d",
973 pRtAddrIdTable[num_task]->symbolic_name /*OSTName[num_task]*/,
974 num_task,
975 pRtAddrIdTable[num_task]->os_stack_size,
976 rvf_used_stack( num_task) );
977 rvf_send_trace( task_info, 35, NULL_PARAM, RV_TRACE_LEVEL_DEBUG_HIGH, RVM_USE_ID);
978 }
979 }
980 /* find a way to track task stack usage and display it */
981 /* using NU_Check_Stack, NU_Task_Information or finding the first non-zero value in the stack */
982 }
983
984
985 /****************************************************************************/
986 /* For Big Endian Processors swap the bytes */
987 #if defined(__BIG_ENDIAN)
988 UINT16 ntohs(UINT16 n)
989 {
990 register UINT8 tmp;
991 register UINT8 *p=(UINT8 *)&n;
992
993 tmp = p[0];
994 p[0] = p[1];
995 p[1] = tmp;
996
997 return n;
998 }
999
1000 UINT32 ntohl(UINT32 n)
1001 {
1002 register UINT8 tmp;
1003 register UINT8 *p=(UINT8 *)&n;
1004
1005 tmp = p[0];
1006 p[0] = p[3];
1007 p[3] = tmp;
1008
1009 tmp = p[1];
1010 p[1] = p[2];
1011 p[2] = tmp;
1012
1013 return n;
1014 }
1015
1016 #endif /* __BIG_ENDIAN*/
1017
1018
1019
1020
1021 /******************************************************************************
1022 **
1023 ** Function rvf_send_trace
1024 **
1025 ** Description This function displays a message essentially for debug purposes.
1026 ** It displays the msg_length characters of the string pointed by msg
1027 ** and the value of val.
1028 **
1029 ** Returns void
1030 **
1031 ******************************************************************************/
1032 #ifdef _WINDOWS
1033 #ifndef _CONSOLE
1034 void rvf_send_trace1( INT8 * msg, UINT8 msg_length, UINT32 val, UINT8 TRACE_LEVEL, UINT32 swe_use_id)
1035 {
1036 /* Function to display trace message for Tool */
1037
1038 UINT32 trace_type = swe_use_id;
1039
1040 Trace( msg, msg_length, val, TRACE_LEVEL, trace_type);
1041 }
1042 #endif
1043 #endif
1044
1045 #ifdef _CONSOLE /* CONSOLE */
1046 void rvf_send_trace1( INT8 * msg, UINT8 msg_length, UINT32 val, UINT8 TRACE_LEVEL, UINT32 swe_use_id) {
1047 const int MAX = 1000;
1048 static int l = 0;
1049 char buf[100];
1050 HANDLE out = 0;
1051 int nb;
1052
1053 if(!out)out=GetStdHandle(STD_OUTPUT_HANDLE);
1054
1055 rvf_disable(25);
1056
1057 sprintf(buf,"%s %d\n", msg, val);
1058 WriteConsole(out, buf, strlen(buf), &nb, NULL);
1059
1060 if(l>=MAX) {
1061 system("cls");
1062 l=0;
1063 } else l++;
1064
1065 rvf_enable();
1066 }
1067 #endif /* CONSOLE */
1068
1069 /*******************************************************************************
1070 **
1071 ** Function rvf_resume_task
1072 **
1073 ** Description This function is called to resume a rvf task which is in a suspend state.
1074 **
1075 ** Returns RVF_OK if successful, else an error code
1076 **
1077 *******************************************************************************/
1078 T_RVF_RET rvf_resume_task( T_RVF_G_ADDR_ID taskid)
1079 {
1080 if(!pRtAddrIdTable[taskid]) return RVF_INVALID_PARAMETER;
1081 if(!pRtAddrIdTable[taskid]->pOSTCB) return RVF_INVALID_PARAMETER;
1082 /* resume the task */
1083 if ( NU_INVALID_TASK == NU_Resume_Task( pRtAddrIdTable[taskid]->pOSTCB) ) {// A-M-E-N-D-E-D!
1084 return RVF_INTERNAL_ERR; //RVF_INVALID_PARAMETER;
1085 }
1086 return RVF_OK;
1087 }
1088
1089 /*******************************************************************************
1090 **
1091 ** Function rvf_initialize_mutex
1092 **
1093 ** Description This function initialize a mutex structure, which will be used
1094 ** to protect shared variables against simultaneous access.
1095 **
1096 ** Returns RVF_OK if successful, else an error code
1097 **
1098 *******************************************************************************/
1099 T_RVF_RET rvf_initialize_mutex( T_RVF_MUTEX * mutex)
1100 {
1101
1102 /* initializes the mutex structure */
1103
1104 if( NU_Create_Semaphore( (NU_SEMAPHORE *)mutex, "RVF", 1, NU_PRIORITY ) != NU_SUCCESS)
1105 { return RVF_INTERNAL_ERR;
1106 }
1107
1108 return RVF_OK;
1109 }
1110
1111 /*******************************************************************************
1112 **
1113 ** Function rvf_lock_mutex
1114 **
1115 ** Description This function locks a mutex to avoid simultaneous access.
1116 ** If the mutex is already locked, the task is suspended
1117 ** until the mutex is unlocked.
1118 **
1119 ** Returns RVF_OK if successful, else an error code
1120 **
1121 *******************************************************************************/
1122 T_RVF_RET rvf_lock_mutex( T_RVF_MUTEX * mutex)
1123 {
1124 if( NU_Obtain_Semaphore( (NU_SEMAPHORE *)mutex, NU_SUSPEND ) != NU_SUCCESS)
1125 { return RVF_INTERNAL_ERR;
1126 }
1127
1128 return RVF_OK;
1129 }
1130
1131 /*******************************************************************************
1132 **
1133 ** Function rvf_unlock_mutex
1134 **
1135 ** Description This function unlocks a mutex to avoid simultaneous access.
1136 **
1137 ** Returns RVF_OK if successful, else an error code
1138 **
1139 *******************************************************************************/
1140 T_RVF_RET rvf_unlock_mutex( T_RVF_MUTEX * mutex)
1141 {
1142 if( NU_Release_Semaphore( (NU_SEMAPHORE *)mutex ) != NU_SUCCESS)
1143 { return RVF_INTERNAL_ERR;
1144 }
1145
1146 return RVF_OK;
1147 }
1148
1149 /*******************************************************************************
1150 **
1151 ** Function rvf_delete_mutex
1152 **
1153 ** Description This function deletes a previously created mutex.
1154 **
1155 ** Returns RVF_OK if successful, else an error code
1156 **
1157 *******************************************************************************/
1158 T_RVF_RET rvf_delete_mutex( T_RVF_MUTEX * mutex)
1159 {
1160 if( NU_Delete_Semaphore( (NU_SEMAPHORE *)mutex ) != NU_SUCCESS)
1161 { return RVF_INTERNAL_ERR;
1162 }
1163
1164 return RVF_OK;
1165 }
1166
1167 void rvf_yield() { NU_Relinquish(); }
1168
1169 /* convenience function */
1170 UINT8 rvf_isType2() {
1171 if(pRtAddrIdTable[rvf_get_taskid()]->type_code==ET2_HOST_TASK) return 1;
1172 else return 0;
1173 }
1174