FreeCalypso > hg > tcs211-c139
comparison chipsetsw/riviera/rvf/rvf_task.c @ 0:509db1a7b7b8
initial import: leo2moko-r1
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 01 Jun 2015 03:24:05 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:509db1a7b7b8 |
---|---|
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 |