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