FreeCalypso > hg > fc-tourmaline
view src/cs/riviera/rvm/rvm_swe_hdlr.c @ 303:f76436d19a7a default tip
!GPRS config: fix long-standing AT+COPS chance hanging bug
There has been a long-standing bug in FreeCalypso going back years:
sometimes in the AT command bring-up sequence of an ACI-only MS,
the AT+COPS command would produce only a power scan followed by
cessation of protocol stack activity (only L1 ADC traces), instead
of the expected network search sequence. This behaviour was seen
in different FC firmware versions going back to Citrine, and seemed
to follow some law of chance, not reliably repeatable.
This bug has been tracked down and found to be specific to !GPRS
configuration, stemming from our TCS2/TCS3 hybrid and reconstruction
of !GPRS support that was bitrotten in TCS3.2/LoCosto version.
ACI module psa_mms.c, needed only for !GPRS, was missing in the TCS3
version and had to be pulled from TCS2 - but as it turns out,
there is a new field in the MMR_REG_REQ primitive that needs to be
set correctly, and that psa_mms.c module is the place where this
initialization needed to be added.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 08 Jun 2023 08:23:37 +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; }