static xme_status_t xme_core_loop_addToInitQueue ( xme_core_exec_componentDescriptor_t* componentDesc ) { if(!componentDesc->autoInit) return XME_STATUS_SUCCESS; /* look up the component descriptor in the startup queue */ XME_HAL_SINGLYLINKEDLIST_ITERATE_BEGIN(xme_core_loop_SchedulerData.initQueue, xme_core_exec_componentDescriptor_t, listComponent); if(listComponent->componentId == componentDesc->componentId) { return XME_STATUS_ALREADY_EXIST; } XME_HAL_SINGLYLINKEDLIST_ITERATE_END(); XME_CHECK(XME_STATUS_SUCCESS == XME_HAL_SINGLYLINKEDLIST_ADD_ITEM_SORTED( xme_core_loop_SchedulerData.initQueue, componentDesc, offsetof(xme_core_exec_componentDescriptor_t, initPriority), uint32_t), XME_STATUS_INTERNAL_ERROR); return XME_STATUS_SUCCESS; }
static xme_status_t xme_core_loop_completeInitialization( void ) { XME_HAL_SINGLYLINKEDLIST_ITERATE_BEGIN(xme_core_loop_SchedulerData.chunks, xme_core_loop_ChunkDescriptor_t, chunk); XME_CHECK( XME_STATUS_SUCCESS == xme_core_loop_completeChunkInit(chunk), XME_STATUS_INVALID_CONFIGURATION); XME_HAL_SINGLYLINKEDLIST_ITERATE_END(); return XME_STATUS_SUCCESS; }
extern xme_status_t xme_core_loop_init( void ) { XME_HAL_SINGLYLINKEDLIST_INIT(xme_core_loop_SchedulerData.initQueue); XME_HAL_SINGLYLINKEDLIST_INIT(xme_core_loop_SchedulerData.chunks); /* Registration of the RTE modules */ XME_CHECK_MSG( XME_STATUS_SUCCESS == xme_core_loop_RegisterModulesCallback(), XME_STATUS_INVALID_CONFIGURATION, XME_LOG_FATAL, MODULE_ACRONYM "Could not register RTE modules!\n"); /* A configuration routine to define RTE "chunks" - the basic blocks of RTE module execution on OS level */ XME_CHECK_MSG( XME_STATUS_SUCCESS == xme_core_loop_CreateChunksCallback(), XME_STATUS_INVALID_CONFIGURATION, XME_LOG_FATAL, MODULE_ACRONYM "Could not create RTE chunks!\n"); /* Check the chunks for plausibility and register in EM */ XME_CHECK_MSG( XME_STATUS_SUCCESS == xme_core_loop_completeInitialization(), XME_STATUS_INVALID_CONFIGURATION, XME_LOG_FATAL, MODULE_ACRONYM "Could not complete RTE initialization!\n"); XME_HAL_SINGLYLINKEDLIST_ITERATE_BEGIN(xme_core_loop_SchedulerData.initQueue, xme_core_exec_componentDescriptor_t, compToInit); if(compToInit->autoInit) { XME_LOG(XME_LOG_NOTE, MODULE_ACRONYM "RTE scheduler: initialize component %3d with priority %5d\n", compToInit->componentId, compToInit->initPriority); XME_CHECK_MSG(XME_STATUS_SUCCESS == compToInit->init(compToInit->initParam), XME_STATUS_INVALID_CONFIGURATION, XME_LOG_FATAL, MODULE_ACRONYM "Failure during initialization of the component %d\n", compToInit->componentId); } XME_HAL_SINGLYLINKEDLIST_ITERATE_END(); XME_CHECK( XME_STATUS_SUCCESS == xme_core_loop_ActivateScheduleCallback(), XME_STATUS_INTERNAL_ERROR); return XME_STATUS_SUCCESS; }
void xme_core_pnp_pnpClientSendLogoutRequestFunction_step ( xme_core_pnp_pnpClientComponent_config_t* const componentConfig ) { xme_status_t status[1]; xme_core_topic_pnp_logoutRequest_t* portOutLogoutRequestDataPtr = &portOutLogoutRequestData; { // PROTECTED REGION ID(XME_CORE_PNP_PNPCLIENTSENDLOGOUTREQUESTFUNCTION_STEP_C) ENABLED START xme_hal_singlyLinkedList_t(10) tmpList; XME_UNUSED_PARAMETER(componentConfig); XME_HAL_SINGLYLINKEDLIST_INIT(tmpList); status[0] = xme_core_pnp_pnpClient_getLoggedoutNodes(&tmpList); if (XME_STATUS_SUCCESS == status[0]) { XME_HAL_SINGLYLINKEDLIST_ITERATE_BEGIN(tmpList, void, tempNodeId); { portOutLogoutRequestData.nodeId = (xme_core_node_nodeId_t)(uintptr_t)tempNodeId; } XME_HAL_SINGLYLINKEDLIST_ITERATE_END(); } else { portOutLogoutRequestDataPtr = NULL; } // PROTECTED REGION END } status[0] = xme_core_pnp_pnpClientComponentWrapper_writePortOutLogoutRequest(portOutLogoutRequestDataPtr); { // PROTECTED REGION ID(XME_CORE_PNP_PNPCLIENTSENDLOGOUTREQUESTFUNCTION_STEP_2_C) ENABLED START // TODO: Check return values of writePort calls here // PROTECTED REGION END } }
static xme_status_t xme_core_loop_completeChunkInit ( xme_core_loop_ChunkDescriptor_t* const chunk ) { xme_core_exec_functionDescriptor_t* newFunctionDesc; /* Verify if the schedule does not contain intersections and compute wcet*/ XME_CHECK(XME_STATUS_SUCCESS == xme_core_loop_checkRteChunkSchedule(chunk), XME_STATUS_INVALID_CONFIGURATION); /* Create a function descriptor for an RTE chunk. * This will be the descriptor of our executable unit. */ newFunctionDesc = (xme_core_exec_functionDescriptor_t*) xme_hal_mem_alloc( sizeof(xme_core_exec_functionDescriptor_t) ); /* Ugly reassignments, thanks MS for C99 support */ newFunctionDesc->componentId = RTE_BASE_COMPONENT_ID; newFunctionDesc->functionId = chunk->id; newFunctionDesc->task = &xme_core_loop_execChunk; newFunctionDesc->taskArgs = (void*)newFunctionDesc; newFunctionDesc->wcet_ns = chunk->wcet_ns; newFunctionDesc->state = XME_CORE_EXEC_FUNCTION_STATE_INVALID_STATE; chunk->executionUnit = newFunctionDesc; /* Add the respective RTE components to the init queue */ XME_HAL_SINGLYLINKEDLIST_ITERATE_BEGIN( chunk->slots, // list to iterate over xme_core_loop_SlotDescriptor_t, slot ); // iterator variable // fixme: dear Lint, is it ok? if(XME_STATUS_SUCCESS != xme_core_loop_addToInitQueue(slot->componentDesc)) { XME_LOG(XME_LOG_NOTE, MODULE_ACRONYM "slot [%d|%d] has not been added to startup queue\n", slot->functionDesc->componentId, slot->functionDesc->functionId); } XME_HAL_SINGLYLINKEDLIST_ITERATE_END(); return XME_STATUS_SUCCESS; }
xme_core_exec_schedule_table_entry_t* xme_core_exec_scheduler_findEntryInTable ( xme_core_exec_schedule_table_t* table, xme_core_component_t cid, xme_core_component_functionId_t fid ) { XME_HAL_SINGLYLINKEDLIST_ITERATE_BEGIN(table->entries, xme_core_exec_schedule_table_entry_t, loopItem); if((cid==loopItem->componentId) && (fid==loopItem->functionId)) return loopItem; XME_HAL_SINGLYLINKEDLIST_ITERATE_END(); return NULL; }
extern xme_status_t xme_core_loop_fini( void ) { XME_LOG(XME_LOG_ERROR, "[cid|fid] exCnt avgRuntime us confWcet us\n"); XME_HAL_SINGLYLINKEDLIST_ITERATE_BEGIN(xme_core_loop_SchedulerData.chunks, xme_core_loop_ChunkDescriptor_t, chunkDesc ); { if(XME_STATUS_SUCCESS != xme_core_loop_finiChunk(chunkDesc)) { XME_LOG(XME_LOG_WARNING, "error finalizing chunk %d\n", chunkDesc->id); } } XME_HAL_SINGLYLINKEDLIST_ITERATE_END(); XME_HAL_SINGLYLINKEDLIST_FINI(xme_core_loop_SchedulerData.chunks); XME_HAL_SINGLYLINKEDLIST_FINI(xme_core_loop_SchedulerData.initQueue); return XME_STATUS_SUCCESS; }
xme_status_t copyBetweenMemoryRegionCopies ( xme_core_dataManager_dataStoreID_t dataStoreID, uint16_t sourceDatabaseIndex, uint16_t targetDatabaseIndex ) { uintptr_t sourceDataAddress; uintptr_t sinkDataAddress; xme_core_dataHandler_database_dataStore_t* dataStore; uint32_t transferSizeInBytes; uint32_t totalOffset; void* returnAddress; void* sourceDatabaseAddress; void* sinkDatabaseAddress; XME_ASSERT(NULL != xme_core_dataHandler_database); // Get the data packet information. XME_CHECK(XME_STATUS_SUCCESS == getDataStore(dataStoreID, &dataStore), XME_STATUS_INVALID_HANDLE); // Calculate the total offsets to add. totalOffset = dataStore->topicOffset; // Calculate the position in the queue for the source and sink address. if (dataStore->queueSize > 1) { totalOffset += dataStore->dataStoreSize * dataStore->currentCBWritePosition; } // Get the number of bytes to use in the transfer operation. transferSizeInBytes = getBytesToCopy(dataStore->topicSize, dataStore->topicSize, 0U); // Get source database address from the source database copy. sourceDatabaseAddress = getAddressFromMemoryCopy(dataStore->memoryRegion, sourceDatabaseIndex - 1U); // Get source database address from the source database copy. sinkDatabaseAddress = getAddressFromMemoryCopy(dataStore->memoryRegion, targetDatabaseIndex - 1U); // Check that the database addresses contain correct values. XME_CHECK(0U != sourceDatabaseAddress, XME_STATUS_NOT_FOUND); XME_CHECK(0U != sinkDatabaseAddress, XME_STATUS_NOT_FOUND); if (dataStore->dataAvailable) { // Add the offset corresponding to the source and sink addresses. sourceDataAddress = ((uintptr_t) sourceDatabaseAddress + totalOffset); sinkDataAddress = ((uintptr_t) sinkDatabaseAddress + totalOffset); // Do the transfer for the current copy of the database-> returnAddress = xme_hal_mem_copy((void*) sinkDataAddress, (void*) sourceDataAddress, transferSizeInBytes); XME_CHECK(returnAddress == (void*) sinkDataAddress, XME_STATUS_INTERNAL_ERROR); } // Try the transfer for all attributes as well. XME_HAL_SINGLYLINKEDLIST_ITERATE_BEGIN(dataStore->attributes, xme_core_dataHandler_database_attribute_t, attribute); { if (attribute->dataAvailable == true) { // If the attribute exists in the target data packet. uint32_t totalAttributeOffset; uintptr_t sourceAttributeAddress; uintptr_t sinkAttributeAddress; uint32_t totalAttributeSizeInBytes; // Calculate the total offsets to add. totalAttributeOffset = attribute->attributeOffset; // Calculate the position in the queue for the source and sink address. if (dataStore->queueSize > 1) { totalAttributeOffset += dataStore->dataStoreSize * dataStore->currentCBWritePosition; } // Get trasnfer bytes to copy. totalAttributeSizeInBytes = getBytesToCopy(attribute->attributeValueSize, attribute->attributeValueSize, 0U); // Add the offset corresponding to the source and sink addresses. sourceAttributeAddress = ((uintptr_t) sourceDatabaseAddress + totalAttributeOffset); sinkAttributeAddress = ((uintptr_t) sinkDatabaseAddress + totalAttributeOffset); // Do the transfer for the current copy of the database-> returnAddress = xme_hal_mem_copy((void*) sinkAttributeAddress, (void*) sourceAttributeAddress, totalAttributeSizeInBytes); XME_CHECK(returnAddress == (void*) sinkAttributeAddress, XME_STATUS_INTERNAL_ERROR); } } XME_HAL_SINGLYLINKEDLIST_ITERATE_END(); return XME_STATUS_SUCCESS; }