FreeCalypso > hg > fc-tourmaline
view src/cs/riviera/rvm/rvm_swe_hdlr.c @ 300:edcb8364d45b
L1: resurrect TCH tap feature
In this new incarnation of our TCH tap feature, we support DL sniffing
in all 3 of FR1, HR1 and EFR, and the new implementation will capture
every 20 ms frame where the old one silently skipped a frame (sent
nothing) during FACCH stealing. The wire interface on RVTMUX changed
slightly, and fc-shell tch record will need to be updated to support
the new version.
TCH UL play or substitution is supported for FR1 and EFR only;
support for HR1 can be added later if needed.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 13 Dec 2022 02:44:01 +0000 |
parents | 4e78acac3d88 |
children |
line wrap: on
line source
/** * * @file rvm_swe_hdlr.c * * This file contains the functions related to SWEs management within RVM. * * @author David Lamy-Charrier (d-lamy@ti.com) * @version 0.1 * */ /* * Revision History: * * 10/26/2001 David Lamy-Charrier Create for Riviera 1.6. * * (C) Copyright 2001 by Texas Instruments Incorporated, All Rights Reserved */ #include <stdio.h> #include "rvf/rvf_env.h" #include "rvm/rvm_gen.h" #include "rvm/rvm_api.h" #include "rvm/rvm_i.h" #include "rvf/rvf_i.h" /* ET2 rvf private invocation API */ #include "rvf/rvf_api.h" /* A-M-E-N-D-E-D! */ /* temporary inclusion for HCI pb on WINDOWS */ /* TO DO: remove it. */ #include "rvm/rvm_use_id_list.h" #include <string.h> extern T_RVM_CONST_SWE_INFO RVM_SWE_GET_INFO_ARRAY[]; extern T_RVM_USE_ID * RVM_TYPE2_SWE_GROUPS[]; extern BOOLEAN rvm_allocated_task_id [MAX_RVF_TASKS]; extern T_RVM_KNOWN_SWE * rvm_swe_array; /* private */ T_RVM_RETURN _fatal(T_RVM_PROCESSING_SWE* appli, UINT8 rm); /*********************************************************************** * Function _resolve_t2_grouping (private) * * Description resolves number of group directives & ret. group count *************************************************************************/ UINT8 _resolve_t2_grouping(T_RVM_PROCESSING_SWE* appli, T_RVM_GROUP_DIRECTIVE* gd) { T_RVM_INFO_SWE swe_info; T_RVM_PROCESSING_SWE* cur_swe = appli; UINT8 i=0, j=0, k=0; for(; cur_swe != NULL;) { UINT8 swe_index = cur_swe->swe_id; rvm_swe_array[swe_index].swe_get_info(&swe_info); if (rvm_swe_array[swe_index].swe_state !=SWE_RUNNING && //== SWE_NOT_STARTED && swe_info.swe_type==RVM_SWE_TYPE_2) { for(i=0; i<MAX_GRPS; i++) { if(swe_info.type_info.type2.swe_group_directive == gd[i].group_directive) { for(k=0; gd[i].hosted_swe_db_index[k]!=0; k++); if(k<MAX_COMPOSITES) { gd[i].hosted_swe_db_index[k]=swe_index; } else { /* TO DO ... ERROR !!! */ } // RVM_TRACE_WARNING_PARAM("rvm.SweHndlr.resolve_t2_grouping(), appended to grp entry , nb=",\ // (UINT32)swe_index); //printf("rvm.SweHndlr.resolve_t2_grouping(): appended %d to group: %d\n",gd[i].hosted_swe_db_index[k], gd[i].host_task_addr); break; } else if( swe_info.type_info.type2.swe_group_directive != gd[i].group_directive && gd[i].host_task_addr==0 ) { /* Constraint! Expects all group priorites and stack sz to be equal * Additional method must be used to set highest entity pri. or resolve */ gd[i].host_task_addr=RVF_INVALID_ADDR_ID; //rvm_allocate_task_id(1); gd[i].group_directive=swe_info.type_info.type2.swe_group_directive; gd[i].task_priority=swe_info.type_info.type2.priority; gd[i].stack_size=swe_info.type_info.type2.stack_size; gd[i].hosted_swe_db_index[0]=swe_index; j++; // RVM_TRACE_WARNING_PARAM("rvm.SweHndlr.resolve_t2_grouping(), created grp entry , nb=",\ // (UINT32)swe_index); //printf("rvm.SweHndlr.resolve_t2_grouping(): created host group: %d AND append %d\n",gd[i].host_task_addr, gd[i].hosted_swe_db_index[0]); break; } } } else RVM_TRACE_WARNING_PARAM("rvm.SweHndlr.resolve_t2_grouping(), SWE Not type 2: ", rvm_swe_array[swe_index].swe_use_id); cur_swe = cur_swe->next_swe; /* process next SWE */ } //printf("rvm.SweHndlr.resolve_t2_grouping(): total group count: %d\n", j); //for(i=0; i<j; i++) /* de'bugger only!! */ // for(k=0; k<MAX_COMPOSITES && gd[i].hosted_swe_db_index[k]!=0; k++) // printf("host addr: %d, T2 swe_db_index %d\n", // gd[i].host_task_addr, gd[i].hosted_swe_db_index[k]); return j; } /******************************************************************************* ** Function rvm_allocate_task_id ** ** Description Internal function which allocate the first available ** task id to a SWE in creation *******************************************************************************/ T_RVM_TASK_ID rvm_allocate_task_id(UINT8 isRealTask) { /* UINT8 i=0; */ /* Find the 1st free task id If we reach the max: all task ids are allocated => not possible to start SWE.*/ /* while (rvm_allocated_task_id[i] == TRUE) { i++; if (i == MAX_RVF_TASKS) return RVF_INVALID_TASK; }*/ /* Lock task id and return its value. */ /* rvm_allocated_task_id[i] = TRUE; */ /* return ((T_RVM_TASK_ID) i); */ return (T_RVM_TASK_ID) rvf_allocate_task_id(isRealTask); /* A-M-E-N-D-E-D! */ } /******************************************************************************* ** ** Function rvm_set_swe_info ** ** Description This function call the set_info function of each SWEs required ** to start a specified SWE. ** ** Parameters: T_RVM_PROCESSING_SWE * appli: list of required SWEs with their parameters. ** ** Returns T_RVM_RETURN: RVM_OK if successful. ** *******************************************************************************/ T_RVM_RETURN rvm_set_swe_info(T_RVM_PROCESSING_SWE * appli) { T_RVM_PROCESSING_SWE * cur_swe = appli; UINT8 i; T_RVF_MB_ID _bk_id_table[RVM_MAX_NB_MEM_BK]; /* for each SWE in the list */ while( cur_swe != NULL ) { UINT8 swe_index = cur_swe->swe_id; if (rvm_swe_array[swe_index].swe_state != SWE_RUNNING) /* Call the set_info function for only those for which MB were just created */ { /* First build return path */ T_RVM_INFO_SWE swe_info; T_RV_RETURN_PATH return_path[RVM_MAX_NB_LINKED_SWE]; T_RVM_USE_ID linked_swe_use_id[RVM_MAX_NB_LINKED_SWE]; UINT8 nb_linked_swe = 0; rvm_swe_array[swe_index].swe_get_info(&swe_info); switch( swe_info.swe_type) { case(RVM_SWE_TYPE_1): { nb_linked_swe = swe_info.type_info.type1.nb_linked_swe; memcpy( linked_swe_use_id, swe_info.type_info.type1.linked_swe_id, RVM_MAX_NB_LINKED_SWE * sizeof(T_RVM_USE_ID) ); if(rvm_swe_array[swe_index].swe_state != SWE_NOT_STARTED) { for(i=0;i<swe_info.type_info.type1.nb_mem_bank; i++) { rvf_get_mb_id((char*)&swe_info.type_info.type1.mem_bank[i], &_bk_id_table[i]); } } break; } case(RVM_SWE_TYPE_2): { nb_linked_swe = swe_info.type_info.type2.nb_linked_swe; memcpy( linked_swe_use_id, swe_info.type_info.type2.linked_swe_id, RVM_MAX_NB_LINKED_SWE * sizeof(T_RVM_USE_ID) ); if((rvm_swe_array[cur_swe->swe_id].swe_addr_id = rvm_allocate_task_id(0))==RVF_INVALID_ADDR_ID) { return RVM_INTERNAL_ERR; } if(rvm_swe_array[swe_index].swe_state != SWE_NOT_STARTED) { for(i=0;i<swe_info.type_info.type2.nb_mem_bank; i++) { rvf_get_mb_id((char*)&swe_info.type_info.type2.mem_bank[i], &_bk_id_table[i]); } } break; } case(RVM_SWE_TYPE_3): { nb_linked_swe = swe_info.type_info.type3.nb_linked_swe; memcpy( linked_swe_use_id, swe_info.type_info.type3.linked_swe_id, RVM_MAX_NB_LINKED_SWE * sizeof(T_RVM_USE_ID) ); if((rvm_swe_array[cur_swe->swe_id].swe_addr_id = rvm_allocate_task_id(1))==RVF_INVALID_ADDR_ID) { return RVM_INTERNAL_ERR; } if(rvm_swe_array[swe_index].swe_state != SWE_NOT_STARTED) { for(i=0;i<swe_info.type_info.type3.nb_mem_bank; i++) { rvf_get_mb_id((char*)&swe_info.type_info.type3.mem_bank[i], &_bk_id_table[i]); } } break; } case(RVM_SWE_TYPE_4): { nb_linked_swe = swe_info.type_info.type4.nb_linked_swe; memcpy( linked_swe_use_id, swe_info.type_info.type4.linked_swe_id, RVM_MAX_NB_LINKED_SWE * sizeof(T_RVM_USE_ID) ); if((rvm_swe_array[cur_swe->swe_id].swe_addr_id = rvm_allocate_task_id(1))==RVF_INVALID_ADDR_ID) { return RVM_INTERNAL_ERR; } if(rvm_swe_array[swe_index].swe_state != SWE_NOT_STARTED) { for(i=0;i<swe_info.type_info.type4.nb_mem_bank; i++) { rvf_get_mb_id((char*)&swe_info.type_info.type4.mem_bank[i], &_bk_id_table[i]); } } break; } } rvm_swe_array[cur_swe->swe_id].swe_return_path.addr_id=rvm_swe_array[cur_swe->swe_id].swe_addr_id; for (i=0; i < nb_linked_swe; i++) { UINT8 linked_swe_index; if (rvm_get_swe_index(&linked_swe_index, linked_swe_use_id[i]) != RVM_OK) { return RVM_INTERNAL_ERR; } return_path[i].callback_func = rvm_swe_array[linked_swe_index].swe_return_path.callback_func; /* TO DO: manage addr_id for GROUP_MEMBER SWEs */ return_path[i].addr_id = rvm_swe_array[linked_swe_index].swe_addr_id; } if (cur_swe->rvm_functions.set_info != NULL ) { if(rvm_swe_array[swe_index].swe_state == SWE_NOT_STARTED) { cur_swe->rvm_functions.set_info(rvm_swe_array[cur_swe->swe_id].swe_addr_id, \ return_path, \ cur_swe->bk_id_table, \ rvm_error); } else { cur_swe->rvm_functions.set_info(rvm_swe_array[cur_swe->swe_id].swe_addr_id, \ return_path, \ _bk_id_table, \ rvm_error); } } } cur_swe = cur_swe->next_swe; /* process next SWE */ } return RVM_OK; } /******************************************************************************* ** ** Function rvm_initialize_swe ** ** Description This function initialize all the required SWEs which are not running. ** It also creates the tasks in a suspend state. ** Then it resumes the tasks and call the start function of each SWE. ** ** Parameters: T_RVM_PROCESSING_SWE * appli: list of required SWEs with their parameters. ** ** Returns T_RVM_RETURN: RVM_OK if successful. ** *******************************************************************************/ T_RVM_RETURN rvm_initialize_swe( T_RVM_PROCESSING_SWE * appli, T_RVM_GROUP_DIRECTIVE* gd, UINT8 t2cnt) { T_RVM_PROCESSING_SWE * cur_swe = appli; UINT8 i=0, j=0; UINT16 tuid=0; T_RVF_BUFFER* stack_ptr=NULL; T_RVM_INFO_SWE swe_info; #ifdef _WINDOWS BOOLEAN hci_started = FALSE; #endif /* for each SWE in the list, initialize it */ while( cur_swe != NULL ) { UINT8 swe_index = cur_swe->swe_id; if ( rvm_swe_array[swe_index].swe_state != SWE_RUNNING) { /* call its init function */ if (cur_swe->rvm_functions.init) { if (cur_swe->rvm_functions.init() != RVM_OK) { rvf_send_trace("RVM: Error Calling init function of swe nb ", 43, \ (UINT32)swe_index, RV_TRACE_LEVEL_ERROR, RVM_USE_ID ); } } } cur_swe = cur_swe->next_swe; } /* for each SWE in the list, create the task if necessary. */ cur_swe = appli; while( cur_swe != NULL ) { UINT8 swe_index = cur_swe->swe_id; if ( rvm_swe_array[swe_index].swe_state != SWE_RUNNING) { /* start the task if necessary in SUSPEND mode */ if ( cur_swe->swe_type == RVM_SWE_TYPE_4) { /* allocate a buffer for the stack */ if ( rvm_allocate_stack_buffer( cur_swe->stack_size, &rvm_swe_array[swe_index].stack_ptr) != RVM_OK) { rvf_send_trace("RVM: Error allocating stack nb:", 28, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_ERROR, RVM_USE_ID); /* TO DO: manage the error case */ return RVF_MEMORY_ERR; } /* start the task in suspend mode */ if (rvf_create_task((TASKPTR) cur_swe->rvm_functions.core, \ (UINT8)rvm_swe_array[swe_index].swe_addr_id,\ rvm_swe_array[swe_index].swe_name, \ rvm_swe_array[swe_index].stack_ptr, \ cur_swe->stack_size, \ cur_swe->priority, \ ET4_TASK,\ DEFAULT_TIME_SLICING, \ SUSPEND ) != RV_OK) { rvf_send_trace("RVM: Error Creating Task nb:", 28, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_ERROR, RVM_USE_ID); } rvf_setRtAddrSweIndex(rvm_swe_array[swe_index].swe_addr_id, swe_index); rvf_send_trace("RVM: Created task nb ", 21, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID); } else if (cur_swe->swe_type == RVM_SWE_TYPE_3) { /* allocate a buffer for the stack */ if ( rvm_allocate_stack_buffer( cur_swe->stack_size, &rvm_swe_array[swe_index].stack_ptr) != RVM_OK) { rvf_send_trace("RVM: Error allocating stack nb:", 28, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_ERROR, RVM_USE_ID); /* TO DO: manage the error case */ return RVF_MEMORY_ERR; } /* start the task in suspend mode */ if (rvf_create_task((TASKPTR)rvm_t3_proxy, \ (UINT8)rvm_swe_array[swe_index].swe_addr_id,\ rvm_swe_array[swe_index].swe_name, \ rvm_swe_array[swe_index].stack_ptr, \ cur_swe->stack_size, \ cur_swe->priority, \ ET3_TASK,\ DEFAULT_TIME_SLICING, \ SUSPEND ) != RV_OK) { rvf_send_trace("RVM: Error Creating E3 Task nb:", 28, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_ERROR, RVM_USE_ID); } rvf_register_t3_handlers(rvm_swe_array[swe_index].swe_addr_id, cur_swe->rvm_functions.handle_message, /* traverse list hence: cur_swe->rvm_functions */ cur_swe->rvm_functions.handle_timer ); rvf_setRtAddrSweIndex(rvm_swe_array[swe_index].swe_addr_id, swe_index); rvf_send_trace("RVM: Created task nb ", 21, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID); } } cur_swe = cur_swe->next_swe; /* process next SWE */ } /* resolve T2 grouping */ for(i=0; i<t2cnt; i++) { gd[i].host_task_addr=rvf_resolveHostingAddrId(gd[i]); if( gd[i].host_task_addr==RVF_INVALID_ADDR_ID) { if ( rvm_allocate_stack_buffer( gd[i].stack_size, &stack_ptr) != RVM_OK){ /* TO DO: manage the error case - ABORT & Clean-up if one or more linked Ent. fail */ //break; return RVF_MEMORY_ERR; } gd[i].host_task_addr=rvm_allocate_task_id(1); rvf_create_task((TASKPTR)rvm_t2_proxy, gd[i].host_task_addr, // "hosting_task", stack_ptr, gd[i].stack_size, gd[i].task_priority, ET2_HOST_TASK, DEFAULT_TIME_SLICING, SUSPEND); rvf_associateGrpToHost(gd[i].host_task_addr, gd[i].group_directive); } for(j=0; j<MAX_COMPOSITES && gd[i].hosted_swe_db_index[j]!=0; j++) { /* create virtual task for each "hosted_swe_db_index[]" */ rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_get_info(&swe_info); rvf_create_virtual_task(swe_info.type_info.type2.handle_message, swe_info.type_info.type2.handle_timer, rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_addr_id, gd[i].host_task_addr, rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_name, rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_priority, ET2_VTASK); rvf_setRtAddrSweIndex(rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_addr_id, gd[i].hosted_swe_db_index[j]); /* register each with associate host */ rvf_registerToHost( gd[i].host_task_addr, rvm_swe_array[gd[i].hosted_swe_db_index[j]].swe_addr_id); } } /* resume all hosting tasks... */ for(i=0; i<t2cnt; i++) rvf_resume_task((UINT8)gd[i].host_task_addr); /* start composites or virtual tasks */ for(i=0; i<t2cnt; i++) { rvm_start_group_req((UINT8)gd[i].host_task_addr, gd[i].hosted_swe_db_index); } /* for each SWE in the list, start it if necessary. */ for(cur_swe = appli; cur_swe != NULL; ) { UINT8 swe_index = cur_swe->swe_id; if ( rvm_swe_array[swe_index].swe_state != SWE_RUNNING) { /* if the SWE is a task, resume it */ if ( (cur_swe->swe_type == RVM_SWE_TYPE_3) || (cur_swe->swe_type == RVM_SWE_TYPE_4) ) { /* TO DO: check the return value */ if(rvf_resume_task((UINT8)rvm_swe_array[swe_index].swe_addr_id )!=RVF_OK) { RVM_TRACE_WARNING("RVM: ERROR! UNABLE TO RESUME SWE"); return RVF_INTERNAL_ERR; } rvf_send_trace("RVM: Resumed task nb ", 21, (UINT32)rvm_swe_array[swe_index].swe_addr_id, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID); rvf_send_trace("RVM: Resumed SWE ", 17, (UINT32)rvm_swe_array[swe_index].swe_use_id, RV_TRACE_LEVEL_DEBUG_LOW, RVM_USE_ID); #ifdef _WINDOWS if (rvm_swe_array[swe_index].swe_use_id == HCI_USE_ID ) { hci_started = TRUE; } #endif } else if(cur_swe->swe_type==RVM_SWE_TYPE_1) { /* A-M-E-N-D-E-D! */ /* call its init function */ if (cur_swe->rvm_functions.start) { if (cur_swe->rvm_functions.start() != RVM_OK) { rvf_send_trace("RVM: Error Calling start function of swe nb ", 44, \ (UINT32)swe_index, RV_TRACE_LEVEL_ERROR, RVM_USE_ID); } } } } /* increment the number of using swe and points to the using appli */ /* DOES NOT DEPEND ON THE STATE */ /*rvm_swe_array[swe_index].swe_get_info(&swe_info); switch( swe_info.swe_type) { case RVM_SWE_TYPE_1: if(!swe_info.type_info.type1.nb_linked_swe) rvm_swe_array[swe_index].nb_using_appli=0; break; case RVM_SWE_TYPE_2: if(!swe_info.type_info.type2.nb_linked_swe) rvm_swe_array[swe_index].nb_using_appli=0; break; case RVM_SWE_TYPE_3: if(!swe_info.type_info.type3.nb_linked_swe) rvm_swe_array[swe_index].nb_using_appli=0; break; case RVM_SWE_TYPE_4: if(!swe_info.type_info.type4.nb_linked_swe) rvm_swe_array[swe_index].nb_using_appli=0; break; default: rvm_swe_array[swe_index].nb_using_appli=0; }*/ // if(rvm_swe_array[swe_index].nb_using_appli) { // rvm_swe_array[swe_index].using_appli[rvm_swe_array[swe_index].nb_using_appli++] = appli->swe_id; // // } if(rvm_swe_array[appli->swe_id].nb_using_appli<RVM_MAX_SWE_USING ) { rvm_swe_array[appli->swe_id].using_appli[rvm_swe_array[appli->swe_id].nb_using_appli++]=swe_index; } else { RVM_TRACE_WARNING_PARAM("RVM: Unable to track 'Using Appli' list is full nb=", appli->swe_id); } cur_swe = cur_swe->next_swe; /* process next SWE */ } for(cur_swe=appli; cur_swe!=NULL; ) { rvm_swe_array[cur_swe->swe_id].swe_state = SWE_RUNNING; cur_swe = cur_swe->next_swe; } #ifdef _WINDOWS if (hci_started == TRUE) { rvf_delay(RVF_MS_TO_TICKS(1000)); } #endif return RVM_OK; } /******************************************************************************* ** ** Function rvm_stop_swe_list ** ** Description This function will call the stop functions when possible. ** ** Parameters: T_RVM_PROCESSING_SWE * appli: list of required SWEs with their parameters. ** ** Returns T_RVM_OK if all allocation are successful, ** else T_RVM_INTERNAL_ERR (then some SWE are not stopped. ** *******************************************************************************/ T_RVM_RETURN rvm_stop_swe_list( T_RVM_PROCESSING_SWE * appli, T_RV_HDR* hdr) { T_RVM_PROCESSING_SWE * cur_swe = appli; T_RVM_INFO_SWE swe_info; volatile T_RVM_RETURN rvm_ret_value = RVM_OK; T_RVM_STOP_MSG* p_msg=NULL; UINT8 i=0; /* for each SWE in the list */ while (cur_swe != NULL ) { UINT8 swe_index = cur_swe->swe_id; /* If nb_using_appli > 1, SWE cannot be stopped */ /* if (rvm_swe_array[swe_index].nb_using_appli > 1) { cur_swe = cur_swe->next_swe; continue; } // If nb_using_appli == 1 but using_appli != appli, SWE cannot be stopped if ((rvm_swe_array[swe_index].nb_using_appli == 1) && \ (rvm_swe_array[swe_index].using_appli[0] != appli->swe_id)) { cur_swe = cur_swe->next_swe; continue; } */ if (cur_swe->swe_type==RVM_SWE_TYPE_1) { //cater for de-init of lib if(cur_swe->rvm_functions.stop1)cur_swe->rvm_functions.stop1(); if(cur_swe->rvm_functions.kill)cur_swe->rvm_functions.kill(); cur_swe = cur_swe->next_swe; continue; } if (cur_swe->swe_type==RVM_SWE_TYPE_4) { // etype 4 restriction RVM_TRACE_WARNING_PARAM("RVM: Stop & Kill is not applicable to Type 4 entities, nb=", (UINT32)swe_index); for (rvm_swe_array[swe_index].nb_using_appli=0,i=0; i<RVM_MAX_SWE_USING; i++) { //reset using appli - workaround! rvm_swe_array[swe_index].using_appli[i] = RVM_INVALID_SWE_INDEX; } cur_swe = cur_swe->next_swe; continue; } /* Retrieve stop function with a get_info */ if (rvm_swe_array[swe_index].swe_get_info == NULL) { RVM_TRACE_WARNING_PARAM("RVM: SWE with no get info, cannot be stopped, nb=", (UINT32)swe_index); cur_swe = cur_swe->next_swe; rvm_ret_value = RVM_INTERNAL_ERR; continue; } rvm_swe_array[swe_index].swe_get_info( &swe_info); if (cur_swe->rvm_functions.stop == NULL) { RVM_TRACE_WARNING_PARAM("RVM: SWE with no stop function, cannot be stopped, nb=", (UINT32)swe_index); cur_swe = cur_swe->next_swe; continue; } if (rvf_get_buf( rvm_mem_bank, sizeof(T_RVM_STOP_MSG), (void **)&p_msg) == RVF_RED ) { RVM_TRACE_WARNING_PARAM("RVM: Unable to create STOP msg, nb=", (UINT32)swe_index); cur_swe = cur_swe->next_swe; continue; } p_msg->header.msg_id = RVM_STOP_MSG; p_msg->header.src_addr_id = hdr->src_addr_id; p_msg->header.dest_addr_id = hdr->dest_addr_id; // p_msg->header.callback_func = hdr->callback_func; p_msg->rp.callback_func = ((T_RVM_STOP_MSG*)hdr)->rp.callback_func; p_msg->status = SWE_STOPPING; p_msg->swe_num = swe_index; //((T_RVM_STOP_MSG*)hdr)->swe_num; if ( rvf_send_msg( rvm_swe_array[swe_index].swe_addr_id, p_msg) != RVF_OK) { rvm_ret_value = RVM_INTERNAL_ERR; cur_swe = cur_swe->next_swe; continue; } rvm_swe_array[swe_index].swe_state=SWE_STOPPING; /*printf("SHUTDOWN: SWE %s nb %d USING APPLI= %d\n",rvm_swe_array[swe_index].swe_name, swe_index, rvm_swe_array[swe_index].nb_using_appli); for(i=0; i<rvm_swe_array[swe_index].nb_using_appli; i++)printf(" %d, ", rvm_swe_array[swe_index].using_appli[i]); printf("\n");*/ for (rvm_swe_array[swe_index].nb_using_appli=0,i=0; i<RVM_MAX_SWE_USING; i++) { //reset using appli - workaround! rvm_swe_array[swe_index].using_appli[i] = RVM_INVALID_SWE_INDEX; } /*printf("SHUTDOWN: SWE %s nb %d USING APPLI= %d\n",rvm_swe_array[swe_index].swe_name, swe_index, rvm_swe_array[swe_index].nb_using_appli); for(i=0; i<rvm_swe_array[swe_index].nb_using_appli; i++)printf(" %d, ", rvm_swe_array[swe_index].using_appli[i]); printf("\n");*/ /* Stop SWE - amended to ASYNC */ /* TO DO: for type 2 and 3 SWEs, send a message to the host to call the stop function */ //cur_swe->rvm_functions.stop(NULL); /* Proceed to the next SWE */ cur_swe = cur_swe->next_swe; } return rvm_ret_value; } /******************************************************************************* ** ** Function rvm_suspend_swe_tasks ** ** Description This function will suspend all SWE that are tasks. ** ** Parameters: T_RVM_PROCESSING_SWE * appli: list of required SWEs with their parameters. ** ** Returns T_RVM_OK if all allocation are successful, ** else T_RVM_INTERNAL_ERR (then some SWE are not stopped. ** *******************************************************************************/ T_RVM_RETURN rvm_suspend_swe_tasks( T_RVM_PROCESSING_SWE * appli) { T_RVM_PROCESSING_SWE * cur_swe = appli; T_RVM_INFO_SWE swe_info; volatile T_RVM_RETURN rvm_ret_value = RVM_OK; /* for each SWE in the list */ while (cur_swe != NULL ) { UINT8 swe_index = cur_swe->swe_id; /* If nb_using_appli > 1, SWE cannot be stopped */ if (rvm_swe_array[swe_index].nb_using_appli > 1) { cur_swe = cur_swe->next_swe; continue; } /* If nb_using_appli == 1 but using_appli != appli, SWE cannot be stopped */ if ((rvm_swe_array[swe_index].nb_using_appli == 1) && \ (rvm_swe_array[swe_index].using_appli[0] != appli->swe_id)) { cur_swe = cur_swe->next_swe; continue; } /* Retrieve task info with a get_info */ if (rvm_swe_array[swe_index].swe_get_info == NULL) { RVM_TRACE_WARNING_PARAM("RVM: SWE with no get info, cannot be stopped, nb=", (UINT32)swe_index); cur_swe = cur_swe->next_swe; rvm_ret_value = RVM_INTERNAL_ERR; continue; } rvm_swe_array[swe_index].swe_get_info( &swe_info); /* If SWE is not a task, continue */ /* TO DO: manage group member SWEs */ if ( (swe_info.swe_type == RVM_SWE_TYPE_1) || (swe_info.swe_type == RVM_SWE_TYPE_2) ) { cur_swe = cur_swe->next_swe; continue; } /* Suspend SWE task */ rvf_suspend_task( (UINT8)rvm_swe_array[swe_index].swe_return_path.addr_id); RVM_TRACE_DEBUG_LOW_PARAM("RVM: Suspended task nb ", (UINT32) (rvm_swe_array[swe_index].swe_return_path.addr_id & 0x000000FF) ); /* Proceed to the next SWE */ cur_swe = cur_swe->next_swe; } return rvm_ret_value; } /******************************************************************************* ** ** Function rvm_kill_swe_list ** ** Description This function will call the kill functions when possible. ** It will also delete the task, the stack and the used MBs. ** ** Parameters: T_RVM_PROCESSING_SWE * appli: list of required SWEs with their parameters. ** ** Returns T_RVM_OK if everything is successful, ** else T_RVM_INTERNAL_ERR (then some SWE are not killed). ** *******************************************************************************/ T_RVM_RETURN rvm_kill_swe_list( T_RVM_PROCESSING_SWE * appli) { T_RVM_PROCESSING_SWE * cur_swe = appli; T_RVM_INFO_SWE swe_info; volatile T_RVM_RETURN rvm_ret_value = RVM_OK; /* for each SWE in the list */ while (cur_swe != NULL ) { UINT8 swe_index = cur_swe->swe_id; /* If nb_using_appli > 1, SWE cannot be killed */ if (rvm_swe_array[swe_index].nb_using_appli > 1) { cur_swe = cur_swe->next_swe; continue; } /* If nb_using_appli == 1 but using_appli != appli, SWE cannot be killed */ if ((rvm_swe_array[swe_index].nb_using_appli == 1) && \ (rvm_swe_array[swe_index].using_appli[0] != appli->swe_id)) { cur_swe = cur_swe->next_swe; continue; } /* Retrieve kill function with a get_info */ if (rvm_swe_array[swe_index].swe_get_info == NULL) { RVM_TRACE_WARNING_PARAM("RVM: SWE with no get info, cannot be killed, nb=", (UINT32)swe_index); cur_swe = cur_swe->next_swe; rvm_ret_value = RVM_INTERNAL_ERR; continue; } rvm_swe_array[swe_index].swe_get_info( &swe_info); if (cur_swe->rvm_functions.kill == NULL) { RVM_TRACE_WARNING_PARAM("RVM: SWE with no kill function, cannot be killed, nb=", (UINT32)swe_index); cur_swe = cur_swe->next_swe; rvm_ret_value = RVM_INTERNAL_ERR; continue; } /* Kill SWE */ cur_swe->rvm_functions.kill(); /* TO DO: manage group member SWEs */ /* If the SWE is a task, the task should be deleted, as well as its stack */ if ( (swe_info.swe_type == RVM_SWE_TYPE_3) || (swe_info.swe_type == RVM_SWE_TYPE_4) ) { rvf_exit_task((UINT8)(rvm_swe_array[swe_index].swe_return_path.addr_id)); rvf_free_buf(rvm_swe_array[swe_index].stack_ptr); RVM_TRACE_DEBUG_LOW_PARAM("RVM: Deleted task nb ", (UINT32)(rvm_swe_array[swe_index].swe_return_path.addr_id & 0x000000FF)); rvf_free_sys_resources(rvm_swe_array[swe_index].swe_addr_id, 2); } else if(swe_info.swe_type == RVM_SWE_TYPE_2) { rvf_free_sys_resources(rvm_swe_array[swe_index].swe_addr_id, 0); } /* Proceed to the next SWE */ cur_swe = cur_swe->next_swe; } return rvm_ret_value; } /******************************************************************************* ** ** Function rvm_launch_appli ** ** Description Called by the main RVM task to start a specified known application ** ** Parameters: T_RVM_MSG msg: containing the return path and the index of the ** application to start in the array of known SWEs. ** ** Returns None ** *******************************************************************************/ void rvm_launch_appli( T_RVM_MSG * msg_Ptr) { T_RVM_GROUP_DIRECTIVE GroupDirectives[MAX_GRPS]; UINT8 gdCount=0; T_RVM_PROCESSING_SWE * appli = NULL; /* pointer to the first element of the list */ T_RV_RETURN_PATH appli_return_path; UINT8 i,j=0; for(i=0; i<MAX_GRPS; i++) { GroupDirectives[i].group_directive=0; GroupDirectives[i].host_task_addr=0; GroupDirectives[i].stack_size=0; memset(&GroupDirectives[i].hosted_swe_db_index, 0, (sizeof(UINT8)*MAX_COMPOSITES)); } /* store the return path of the caller */ appli_return_path.callback_func = msg_Ptr->rp.callback_func; appli_return_path.addr_id = msg_Ptr->header.src_addr_id; /* recursively call all get_info functions and build the list of running swe */ if ( rvm_build_swe_list( &appli, msg_Ptr->swe_num, 0) != RVM_OK ) { /* Display error message error case: use the return_path to inform the caller that an error occurs*/ rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_INVALID_PARAMETER, msg_Ptr->swe_num, appli_return_path); RVM_TRACE_ERROR("RVM: SWE list built error"); return; } gdCount=_resolve_t2_grouping(appli, GroupDirectives); if(!appli) { // error case: use return_path to inform the caller about memory lack // Unlock state of SWE and free memory RVM_TRACE_WARNING_PARAM("RVM: ABORTED, Stand-alone ENTITY start request!", (UINT32)msg_Ptr->swe_num); rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_NOT_READY, msg_Ptr->swe_num, appli_return_path); rvm_delete_used_memory (appli); return; } RVM_TRACE_DEBUG_HIGH("RVM: SWE list built success"); RVM_TRACE_DEBUG_HIGH_PARAM("RVM: trying to launch SWE", rvm_swe_array[appli->swe_id].swe_use_id); /* check if there is enough available memory */ if ( rvm_verify_memory_requirement( appli, GroupDirectives, gdCount) != RVM_OK) { /* error case: use return_path to inform the caller about memory lack */ /* Unlock state of SWE and free memory */ RVM_TRACE_WARNING_PARAM("RVM: SWE not enough memory: unable to launch Appli nb", (UINT32)appli->swe_id); rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_MEMORY_ERR, msg_Ptr->swe_num, appli_return_path); rvm_delete_used_memory (appli); return; } /* allocates memory banks */ if ( rvm_allocate_mb( appli) != RVM_OK ) { /* error case: use return_path to inform the caller about memory lack */ rvm_delete_used_memory (appli); rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_MEMORY_ERR, msg_Ptr->swe_num, appli_return_path); RVM_TRACE_WARNING("RVM: SWE memory bank allocation error - launch aborted!"); return; } RVM_TRACE_DEBUG_LOW("RVM: SWE memory bank allocation success"); /* call set_info function for each SWE */ if ( rvm_set_swe_info( appli) != RVM_OK) { /* error case: use return_path to inform the caller that an error occurs */ RVM_TRACE_WARNING("RVM: SWE set info functions error"); _fatal(appli, 0); rvm_delete_created_mb(appli); rvm_delete_used_memory (appli); rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_INTERNAL_ERR, msg_Ptr->swe_num, appli_return_path); return; } RVM_TRACE_DEBUG_LOW("RVM: SWE set info functions called"); /* call the init and start functions */ if ( rvm_initialize_swe( appli, GroupDirectives, gdCount) != RVM_OK) { /* error case: use return_path to inform the caller that an error occurs */ RVM_TRACE_WARNING("RVM: SWE initialization error"); rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_INTERNAL_ERR, msg_Ptr->swe_num, appli_return_path); _fatal(appli, 2); rvm_delete_created_mb(appli); rvm_delete_used_memory (appli); return; } RVM_TRACE_DEBUG_LOW("RVM: SWE initialization success"); /* build a message and send the response to the caller */ /* send a result using the return_path */ rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_OK, msg_Ptr->swe_num, appli_return_path); /* and store the return_path */ rvm_swe_array[ msg_Ptr->swe_num ].mmi_return_path.callback_func = msg_Ptr->rp.callback_func; rvm_swe_array[ msg_Ptr->swe_num ].mmi_return_path.addr_id = msg_Ptr->header.src_addr_id; /* Once Everything is back in stand-by, release used memory */ rvm_delete_used_memory (appli); } /******************************************************************************* ** ** Function rvm_shut_down_appli ** ** Description Called by the main RVM task to stop a specified known application ** ** Parameters: T_RVM_MSG msg: containing the return path and the index of the ** application to stop in the array of known SWEs. ** ** Returns None ** *******************************************************************************/ void rvm_stop_appli( T_RVM_STOP_MSG* msg_Ptr) { T_RVM_PROCESSING_SWE * appli = NULL; /* pointer to the first element of the list */ T_RVM_RETURN ret_value; UINT8 swe_idx = 200; T_RV_RETURN_PATH appli_return_path; appli_return_path.callback_func = msg_Ptr->rp.callback_func; appli_return_path.addr_id = msg_Ptr->header.src_addr_id; RVM_TRACE_DEBUG_HIGH_PARAM("RVM: trying to stop Appli nb ", (UINT32)swe_idx); if (rvm_swe_array[msg_Ptr->swe_num].nb_using_appli > 1) { RVM_TRACE_WARNING_PARAM("RVM: SWE has dependencies, nb=", (UINT32)msg_Ptr->swe_num); return; } // ??? If nb_using_appli == 1 but using_appli != appli, SWE cannot be stopped if ((rvm_swe_array[msg_Ptr->swe_num].nb_using_appli == 1) && \ (rvm_swe_array[msg_Ptr->swe_num].using_appli[0] != msg_Ptr->swe_num)) { RVM_TRACE_WARNING_PARAM("RVM: SWE has dependencies, nb=", (UINT32)msg_Ptr->swe_num); return; } /* TO DO : REBUILD SWE LIST !!!! */ if ( rvm_build_swe_list( &appli, msg_Ptr->swe_num, 1) != RVM_OK ) { /* Display error message error case: use the return_path to inform the caller that an error occurs*/ rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_INVALID_PARAMETER, msg_Ptr->swe_num, appli_return_path); RVM_TRACE_ERROR("RVM: SWE list built error"); return; } /* Stop all swe in the list that are used only once */ if ((ret_value = rvm_stop_swe_list(appli, (T_RV_HDR*)msg_Ptr)) != RVM_OK ) { /* Display error message TO DO: error case: use the return_path to inform the caller that an error occurs */ RVM_TRACE_WARNING_PARAM("RVM: Error in SWE stop", (UINT32)ret_value); return; } rvm_delete_used_memory (appli); RVM_TRACE_DEBUG_LOW("RVM: SWE stop broadcast!"); } // NOTE: presently no timeout exists, if the ENT. fails to reply // to stop with rvm_swe_stopped() RVM doesn't kill it. void rvm_swe_has_stopped(T_RVM_STOP_MSG* msg) { T_RVM_STOP_MSG* p_msg=(T_RVM_STOP_MSG*)msg; T_RV_RETURN_PATH appli_return_path; appli_return_path.callback_func = msg->rp.callback_func; appli_return_path.addr_id = msg->header.src_addr_id; if(msg->status!=SWE_STOPPING) { // inform upper of problem rvm_snd_msg_to_upper(RVM_STOP_APPLI, RVM_INVALID_PARAMETER, msg->swe_num, appli_return_path); RVM_TRACE_ERROR("RVM: Entity declines STOP REQ"); rvf_free_msg((T_RV_HDR*)msg); return; } // cont. with shutdown - MUST DO ERROR CASE ! rvm_shutdown_swe(p_msg->swe_num); // set stopped status rvm_swe_array[p_msg->swe_num].swe_state=SWE_KILLED; //SWE_STOPPING; /* build a message and send the response to the caller */ /* send a result using the return_path */ if(rvm_get_mb_level(p_msg->swe_num) ){ rvm_snd_msg_to_upper(RVM_STOP_APPLI, RV_MEMORY_REMAINING, msg->swe_num, appli_return_path); } else { rvm_snd_msg_to_upper(RVM_STOP_APPLI, RVM_OK, msg->swe_num, appli_return_path); } /* and store the return_path */ rvm_swe_array[ msg->swe_num ].mmi_return_path.callback_func = msg->rp.callback_func; rvm_swe_array[ msg->swe_num ].mmi_return_path.addr_id = msg->header.src_addr_id; } void rvm_shutdown_swe(UINT8 index) { //should ret. ok or fail rvm_suspend_swe(index); rvm_kill_swe(index); } void rvm_suspend_swe(UINT8 swe_index) { volatile T_RVM_RETURN rvm_ret_value = RVM_OK; T_RVM_INFO_SWE swe_info; /* ??? If nb_using_appli > 1, SWE cannot be stopped if (rvm_swe_array[swe_index].nb_using_appli > 1) { RVM_TRACE_WARNING_PARAM("RVM-SUSPEND: SWE has dependencies, nb=", (UINT32)swe_index); } // ??? If nb_using_appli == 1 but using_appli != appli, SWE cannot be stopped if ((rvm_swe_array[swe_index].nb_using_appli == 1) && \ (rvm_swe_array[swe_index].using_appli[0] != swe_index)) { RVM_TRACE_WARNING_PARAM("RVM-SUSPEND: SWE has dependencies, nb=", (UINT32)swe_index); }*/ /* Retrieve task info with a get_info */ if (rvm_swe_array[swe_index].swe_get_info == NULL) { RVM_TRACE_WARNING_PARAM("RVM: SWE with no get info, cannot be stopped, nb=", (UINT32)swe_index); rvm_ret_value = RVM_INTERNAL_ERR; return; } rvm_swe_array[swe_index].swe_get_info( &swe_info); /* If SWE is not a task, continue */ /* TO DO: manage group member SWEs */ if ( (swe_info.swe_type == RVM_SWE_TYPE_1) || (swe_info.swe_type == RVM_SWE_TYPE_2) ) { return; } /* Suspend SWE task */ rvf_suspend_task( (UINT8)rvm_swe_array[swe_index].swe_return_path.addr_id); RVM_TRACE_DEBUG_LOW_PARAM("RVM: Suspended task nb ", (UINT32) (rvm_swe_array[swe_index].swe_return_path.addr_id & 0x000000FF) ); } T_RVM_RETURN rvm_kill_swe(UINT8 swe_index) { T_RVM_INFO_SWE swe_info; volatile T_RVM_RETURN rvm_ret_value = RVM_OK; UINT8 isVirtual=0; T_RVF_G_ADDR_ID gid=RVF_INVALID_ADDR_ID; UINT8 isIdle=0; UINT8 i=0; /* If nb_using_appli > 1, SWE cannot be killed if (rvm_swe_array[swe_index].nb_using_appli > 1) return rvm_ret_value; // If nb_using_appli == 1 but using_appli != appli, SWE cannot be killed if ((rvm_swe_array[swe_index].nb_using_appli == 1) && \ (rvm_swe_array[swe_index].using_appli[0] != swe_index)) { RVM_TRACE_WARNING_PARAM("RVM-KILL: SWE has dependencies, nb=", (UINT32)swe_index); return rvm_ret_value; }*/ /* Retrieve kill function with a get_info */ if (rvm_swe_array[swe_index].swe_get_info == NULL){ RVM_TRACE_WARNING_PARAM("RVM-KILL: SWE has no kill function defined, nb=", (UINT32)swe_index); rvm_ret_value = RVM_INTERNAL_ERR; } rvm_swe_array[swe_index].swe_get_info(&swe_info); switch( swe_info.swe_type) { case RVM_SWE_TYPE_1: // if(swe_info.type_info.type1.kill) swe_info.type_info.type1.kill() ; isVirtual=1; break; case RVM_SWE_TYPE_2: gid=resolveHostAddrId(rvm_swe_array[swe_index].swe_addr_id); rvf_unregisterFromHost(gid, rvm_swe_array[swe_index].swe_addr_id); rvf_isHostingTaskIdle(gid, &isIdle); if(isIdle) { // Defered suspend of hosting task: rvf_suspend_task(gid); rvf_exit_task(gid); rvf_free_sys_resources(gid, 2); } if(swe_info.type_info.type2.kill) swe_info.type_info.type2.kill(); isVirtual=1; break; case RVM_SWE_TYPE_3: if(swe_info.type_info.type3.kill) swe_info.type_info.type3.kill(); break; case RVM_SWE_TYPE_4: if(swe_info.type_info.type4.kill) swe_info.type_info.type4.kill(); break; default: RVM_TRACE_WARNING_PARAM("RVM: SWE with no kill function, cannot be killed, nb=", (UINT32)swe_index); } if(!isVirtual) { rvf_exit_task((UINT8)(rvm_swe_array[swe_index].swe_return_path.addr_id)); rvf_free_buf(rvm_swe_array[swe_index].stack_ptr); RVM_TRACE_DEBUG_LOW_PARAM("RVM: Deleted task nb ", (UINT32)(rvm_swe_array[swe_index].swe_return_path.addr_id & 0x000000FF)); rvf_free_sys_resources(rvm_swe_array[swe_index].swe_addr_id, 2); } else { rvf_free_sys_resources(rvm_swe_array[swe_index].swe_addr_id, 0); } return rvm_ret_value; } UINT8 rvm_get_mb_level(UINT8 swe_index) { T_RVM_INFO_SWE swe_info; INT8 i=0; UINT8 isUsed=0; rvm_swe_array[swe_index].swe_get_info(&swe_info); switch( swe_info.swe_type) { case RVM_SWE_TYPE_1: if(swe_info.type_info.type1.nb_mem_bank!=0) for(i=0; i<swe_info.type_info.type1.nb_mem_bank; i++) { rvf_mb_is_used(swe_info.type_info.type1.mem_bank[i].bank_name, &isUsed); if(isUsed) return isUsed; } return isUsed; case RVM_SWE_TYPE_2: if(swe_info.type_info.type2.nb_mem_bank!=0) for(i=0; i<swe_info.type_info.type2.nb_mem_bank; i++) { rvf_mb_is_used(swe_info.type_info.type2.mem_bank[i].bank_name, &isUsed); if(isUsed) return isUsed; } return isUsed; case RVM_SWE_TYPE_3: if(swe_info.type_info.type3.nb_mem_bank!=0) for(i=0; i<swe_info.type_info.type3.nb_mem_bank; i++) { rvf_mb_is_used(swe_info.type_info.type3.mem_bank[i].bank_name, &isUsed); if(isUsed) return isUsed; } return isUsed; case RVM_SWE_TYPE_4: if(swe_info.type_info.type4.nb_mem_bank!=0) for(i=0; i<swe_info.type_info.type4.nb_mem_bank; i++) { rvf_mb_is_used(swe_info.type_info.type4.mem_bank[i].bank_name, &isUsed); if(isUsed) return isUsed; } return isUsed; default: RVM_TRACE_DEBUG_LOW("RVM: Error rvm_get_mb_level()"); return isUsed; } } void rvm_shut_down_appli( T_RVM_MSG * msg_Ptr) { T_RVM_PROCESSING_SWE * appli = NULL; /* pointer to the first element of the list */ T_RVM_RETURN ret_value; UINT8 swe_idx = 200; T_RV_RETURN_PATH appli_return_path; appli_return_path.callback_func = msg_Ptr->rp.callback_func; appli_return_path.addr_id = msg_Ptr->header.src_addr_id; RVM_TRACE_DEBUG_HIGH_PARAM("RVM: trying to stop Appli nb ", (UINT32)swe_idx); /* TO DO : REBUILD SWE LIST !!!! */ if ( rvm_build_swe_list( &appli, msg_Ptr->swe_num, 1) != RVM_OK ) { /* Display error message error case: use the return_path to inform the caller that an error occurs*/ rvm_snd_msg_to_upper(RVM_START_APPLI, RVM_INVALID_PARAMETER, msg_Ptr->swe_num, appli_return_path); RVM_TRACE_ERROR("RVM: SWE list built error"); return; } /* Stop all swe in the list that are used only once */ if ((ret_value = rvm_stop_swe_list(appli, (T_RV_HDR*)msg_Ptr)) != RVM_OK ) { /* Display error message TO DO: error case: use the return_path to inform the caller that an error occurs */ RVM_TRACE_WARNING_PARAM("RVM: Error in SWE stop", (UINT32)ret_value); return; } RVM_TRACE_DEBUG_LOW("RVM: SWE stop success"); /* Suspend all swe that are tasks */ if ((ret_value = rvm_suspend_swe_tasks(appli)) != RVM_OK ) { /* Display error message TO DO: error case: use the return_path to inform the caller that an error occurs */ RVM_TRACE_WARNING_PARAM("RVM: Error in tasks suspension", (UINT32)ret_value); return; } RVM_TRACE_DEBUG_LOW("RVM: SWE task supsended"); /* Kill all SWEs */ if ((ret_value = rvm_kill_swe_list(appli)) != RVM_OK) { /* Display error message TO DO: error case: use the return_path to inform the caller that an error occurs */ RVM_TRACE_WARNING_PARAM("RVM: Error in SWE killing", (UINT32)ret_value); return; } RVM_TRACE_DEBUG_LOW("RVM: SWE kill success"); /* Delete the swe Memory Banks */ rvm_delete_created_mb(appli); /* Delete memory used and restore NOT_STARTED states */ if ((ret_value = rvm_clean_env(appli)) != RVM_OK) { /* Display error message TO DO: error case: use the return_path to inform the caller that an error occurs */ RVM_TRACE_WARNING_PARAM("RVM: Error in Memory cleaning", (UINT32)ret_value); return; } RVM_TRACE_DEBUG_LOW("RVM: Memory cleaning success"); /* build a message and send the response to the caller */ /* send a result using the return_path */ rvm_snd_msg_to_upper(RVM_STOP_APPLI, RVM_OK, msg_Ptr->swe_num, appli_return_path); /* and store the return_path */ rvm_swe_array[ msg_Ptr->swe_num ].mmi_return_path.callback_func = msg_Ptr->rp.callback_func; rvm_swe_array[ msg_Ptr->swe_num ].mmi_return_path.addr_id = msg_Ptr->header.src_addr_id; } T_RVM_RETURN _fatal( T_RVM_PROCESSING_SWE * appli, UINT8 rm) { T_RVM_PROCESSING_SWE * cur_swe = NULL; // T_RVM_INFO_SWE swe_info; RVM_TRACE_DEBUG_LOW("RVM: Fatality handler: reclaiming system resources!"); /* free all appli's system resources */ for (cur_swe = appli; cur_swe!=NULL; ) { if(rvm_swe_array[cur_swe->swe_id].swe_state!=SWE_RUNNING) rvf_free_sys_resources(rvm_swe_array[cur_swe->swe_id].swe_addr_id, rm); } return RVM_OK; } /******************************************************************************* ** ** Function rvm_generic_swe_core ** ** Description This is the main task core used for GROUP_MEMBER SWEs hosting ** and for SINGLE SWEs. ** ** Parameters: useless, may be for future evolutions if Nucleus really ** supports it. ** ** Returns None ** *******************************************************************************/ T_RVM_RETURN rvm_generic_swe_core(void) { return RVM_OK; }