Index: firmware/App/Services/NVMgmtDD.c =================================================================== diff -u -re17e1dc97bf8878056f1f7e4aa861c2448db52bc -r9a14f69c0f0de343b5664b20753142b50bc4e093 --- firmware/App/Services/NVMgmtDD.c (.../NVMgmtDD.c) (revision e17e1dc97bf8878056f1f7e4aa861c2448db52bc) +++ firmware/App/Services/NVMgmtDD.c (.../NVMgmtDD.c) (revision 9a14f69c0f0de343b5664b20753142b50bc4e093) @@ -29,54 +29,64 @@ /// EEPROM functions use the buffer length as the size of U32. So before send the length to any of FAPI functions, it should be divided by 4. #define EEPROM_OPS_SIZE_OF_CONVERTER 4 -#define COMMAND_TIME_OUT (1 * MS_PER_SECOND) ///< Timeout for an EEPROM or RTC command in ms. +#define COMMAND_TIME_OUT (1 * MS_PER_SECOND) ///< Timeout for an EEPROM in ms. /// NVM Exec states enumeration. typedef enum NVM_Exec_State { - NVM_EXEC_STATE_IDLE = 0, ///< Exec state Idle. - NVM_EXEC_STATE_WRITE_TO_EEPROM, ///< Exec state write to EEPROM. - NVM_EXEC_STATE_VERIFY_EEPROM_WRITE, ///< Exec state verify EEPROM write. - NVM_EXEC_STATE_READ_FROM_EEPROM, ///< Exec state read from EEPROM. - NVM_EXEC_STATE_ERASE_EEPROM, ///< Exec state erase EEPROM. - NUM_OF_NVM_EXEC_STATES ///< Total number of exec states. + NVM_EXEC_STATE_IDLE = 0, ///< Exec state Idle. + NVM_EXEC_STATE_WRITE, ///< Exec state write to EEPROM. + NVM_EXEC_STATE_VERIFY_WRITE, ///< Exec state verify EEPROM write. + NVM_EXEC_STATE_READ, ///< Exec state read from EEPROM. + NVM_EXEC_STATE_ERASE, ///< Exec state erase EEPROM. + NUM_OF_NVM_EXEC_STATES ///< Total number of exec states. } NVM_EXEC_STATE_T; /// NVM write record validity check states typedef enum NVM_Write_Record_Validity_Check { - NVM_RECORD_NOT_CHECKED = 0, ///< NVM (written) record not checked. - NVM_RECORD_VALID, ///< NVM record is valid. - NVM_RECORD_NOT_VALID, ///< NVM record is not valid. - NUM_OF_NVM_RECORD_VALIDITY_CHECK ///< Number of NVM validity check states. + NVM_RECORD_NOT_CHECKED = 0, ///< NVM (written) record not checked. + NVM_RECORD_VALID, ///< NVM record is valid. + NVM_RECORD_NOT_VALID, ///< NVM record is not valid. + NUM_OF_NVM_RECORD_VALIDITY_CHECK ///< Number of NVM validity check states. } NVM_RECORD_VALIDITY_CHECK_T; // ********** private data ********** -static NVM_EXEC_STATE_T nvmExecState; ///< NVM exec state variable. -static volatile BOOL powerOffIsImminent; ///< Power off warning has been signaled. Non-volatile memory operations should be completed ASAP and then ceased. -static NVM_RECORD_VALIDITY_CHECK_T writtenRecordStatus; ///< Record data write validity check. -static U32 currentTime; ///< Current time. -static U32 recordAddressOffset; ///< Record address offset. -static U08 writtenRecordCheckBuffer[ MAX_EEPROM_WRITE_BUFFER_BYTES ]; ///< Written record validity check buffer. +static NVM_EXEC_STATE_T nvmExecState; ///< NVM exec state variable. +static volatile BOOL powerOffIsImminent; ///< Power off warning has been signaled. Non-volatile memory operations should be completed ASAP and then ceased. +static NVM_RECORD_VALIDITY_CHECK_T writtenRecordStatus; ///< Record data write validity check. +static U32 currentTime; ///< Current time. +static U32 recordAddressOffset; ///< Record address offset. +static U08 writtenRecordCheckBuffer[ MAX_EEPROM_WRITE_BUFFER_BYTES ]; ///< Written record validity check buffer. // ********** private function prototypes ********** // Exec functions static NVM_EXEC_STATE_T handleExecIdleState( void ); static NVM_EXEC_STATE_T handleExecEraseState( void ); -static NVM_EXEC_STATE_T handleExecWriteToEEPROMState( void ); -static NVM_EXEC_STATE_T handleExecReadFromEEPROMState( void ); -static NVM_EXEC_STATE_T handleExecVerifyEEPROMWriteState( void ); +static NVM_EXEC_STATE_T handleExecWriteState( void ); +static NVM_EXEC_STATE_T handleExecReadState( void ); +static NVM_EXEC_STATE_T handleExecVerifyWriteState( void ); // Helper functions static BOOL didCommandTimeout( NVM_EXEC_STATE_T state ); +/*********************************************************************//** + * @brief + * The initNVMgmtDD function initializes the NV management module. + * It resets internal state variables, initializes driver, + * message queue, records, and enqueues read operations. + * @details \b Inputs: none + * @details \b Outputs: nvmExecState, powerOffIsImminent, + * currentTime, writtenRecordStatus, + * recordAddressOffset + * @return none + *************************************************************************/ void initNVMgmtDD( void ) { - nvmExecState = NVM_EXEC_STATE_IDLE; + nvmExecState = NVM_EXEC_STATE_IDLE; powerOffIsImminent = FALSE; - currentTime = 0; writtenRecordStatus = NVM_RECORD_NOT_CHECKED; recordAddressOffset = 0; @@ -92,7 +102,7 @@ * The signalPowerOffWarning signals this module that system power off is * imminent and any non-volatile data writes in progress should be wrapped * up quickly and any pending non-volatile data writes should not be started. - * @details Inputs: powerOffIsImminent + * @details Inputs: none * @details Outputs: powerOffIsImminent * @return none *************************************************************************/ @@ -103,9 +113,11 @@ /*********************************************************************//** * @brief - * The execNVM runs the NVM main tasks. - * @details Inputs: nvmExecState - * @details Outputs: nvmExecState + * The execNVM function executes the main NV management state machine. + * It handles different execution states for erase, write, read, and + * verification of NV memory operations. + * @details \b Inputs: nvmExecState + * @details \b Outputs: nvmExecState * @return none *************************************************************************/ void execNVM( void ) @@ -116,20 +128,20 @@ nvmExecState = handleExecIdleState(); break; - case NVM_EXEC_STATE_ERASE_EEPROM: + case NVM_EXEC_STATE_ERASE: nvmExecState = handleExecEraseState(); break; - case NVM_EXEC_STATE_WRITE_TO_EEPROM: - nvmExecState = handleExecWriteToEEPROMState(); + case NVM_EXEC_STATE_WRITE: + nvmExecState = handleExecWriteState(); break; - case NVM_EXEC_STATE_READ_FROM_EEPROM: - nvmExecState = handleExecReadFromEEPROMState(); + case NVM_EXEC_STATE_READ: + nvmExecState = handleExecReadState(); break; - case NVM_EXEC_STATE_VERIFY_EEPROM_WRITE: - nvmExecState = handleExecVerifyEEPROMWriteState(); + case NVM_EXEC_STATE_VERIFY_WRITE: + nvmExecState = handleExecVerifyWriteState(); break; default: @@ -140,22 +152,25 @@ } /*********************************************************************//** - * @brief - * The handleExecIdleState checks if the queue is empty and if it is not - * empty, it sets the state of the job. - * @details Inputs: powerOffIsImminent - * @details Outputs: none - * @return next state - *************************************************************************/ -static NVM_EXEC_STATE_T handleExecIdleState ( void ) +* @brief +* The handleExecIdleState function processes the idle state of the +* NVM execution state machine. It checks for pending record jobs and +* initiates erase, write, or read operations. +* @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT if invalid operation +* is encountered +* @details \b Inputs: powerOffIsImminent +* @details \b Outputs: recordAddressOffset, currentTime +* @return state next state of the state machine +*************************************************************************/ +static NVM_EXEC_STATE_T handleExecIdleState( void ) { NVM_EXEC_STATE_T state = NVM_EXEC_STATE_IDLE; - BOOL areQueuesNotEmpty = FALSE; + BOOL areQueuesNotEmpty = FALSE; NVM_OPERATION_T ops; U32 recordFlashAddress; U08* bufferAddress; PROCESS_RECORD_JOB_T recordCurrentJob; - NVM_RECORD_TYPE_T job; + NVM_RECORD_TYPE_T job; PROCESS_RECORD_SPECS_T jobSpecs; // If power off command has been issued, do not process any new jobs @@ -165,15 +180,15 @@ if ( ( FALSE == isRecordQueueEmpty() ) && ( TRUE == isFlashReady() ) ) { dequeueRecordJob(); - recordCurrentJob = getCurrentProcessRecordJob(); - job = recordCurrentJob.recordJob; + recordCurrentJob = getCurrentProcessRecordJob(); + job = recordCurrentJob.recordJob; jobSpecs = getProcessRecord( job ); // Set the record address offset to 0 since a job will just be started recordAddressOffset = 0; areQueuesNotEmpty = TRUE; ops = recordCurrentJob.memoryOperation; currentTime = getMSTimerCount(); - recordFlashAddress = jobSpecs.recordFlashAddress + recordAddressOffset; + recordFlashAddress = jobSpecs.recordFlashAddress + recordAddressOffset; bufferAddress = jobSpecs.structAddressPtr + recordAddressOffset; } } @@ -185,19 +200,19 @@ { case NVM_OPERATION_ERASE: eraseSector( (U32*)recordFlashAddress ); - state = NVM_EXEC_STATE_ERASE_EEPROM; + state = NVM_EXEC_STATE_ERASE; break; case NVM_OPERATION_WRITE: writeSector( (U32*)recordFlashAddress, (U08*)bufferAddress, MAX_EEPROM_WRITE_BUFFER_BYTES ); currentTime = getMSTimerCount(); - state = NVM_EXEC_STATE_WRITE_TO_EEPROM; + state = NVM_EXEC_STATE_WRITE; break; case NVM_OPERATION_READ: readSector( (U32*)recordFlashAddress, (U32*)bufferAddress, ( jobSpecs.sizeofRecord / EEPROM_OPS_SIZE_OF_CONVERTER ) ); currentTime = getMSTimerCount(); - state = NVM_EXEC_STATE_READ_FROM_EEPROM; + state = NVM_EXEC_STATE_READ; break; default: @@ -221,16 +236,18 @@ /*********************************************************************//** * @brief - * The handleExecEraseState issues an erase command to EEPROM on entry - * and if the erase was successful, it sets the state to Idle. - * @details Inputs: none - * @details Outputs: none - * @return next state + * The handleExecEraseState function handles the erase state of the + * NVM execution state machine. It issues an erase command to EEPROM on entry, + * waits for erase completion and if the erase was successful, + * it transitions back to idle when done or on timeout. + * @details \b Inputs: none + * @details \b Outputs: none + * @return state next state of the state machine *************************************************************************/ -static NVM_EXEC_STATE_T handleExecEraseState ( void ) +static NVM_EXEC_STATE_T handleExecEraseState( void ) { - NVM_EXEC_STATE_T state = NVM_EXEC_STATE_ERASE_EEPROM; - BOOL timeoutStatus = didCommandTimeout( state ); + NVM_EXEC_STATE_T state = NVM_EXEC_STATE_ERASE; + BOOL timeoutStatus = didCommandTimeout( state ); if ( TRUE == isFlashReady() || timeoutStatus == TRUE ) { @@ -242,39 +259,44 @@ /*********************************************************************//** * @brief - * The handleExecWriteToEEPROMState issues a write command to EEPROM and - * if the write was successful, it sets the state to Idle. - * @details Inputs: recordAddressOffset, writtenRecordCheckBuffer, + * The handleExecWriteState function handles the write state of + * the NVM execution state machine. It verifies written data and + * continues writing remaining data. if the write was successful, + * it sets the state to Idle. + * @details \b Inputs: recordAddressOffset, * writtenRecordStatus - * @details Outputs: recordAddressOffset, writtenRecordCheckBuffer, - * writtenRecordStatus - * @return next state of the state machine + * @details \b Outputs: recordAddressOffset, currentTime, + * writtenRecordCheckBuffer, writtenRecordStatus + * @return state next state of the state machine *************************************************************************/ -static NVM_EXEC_STATE_T handleExecWriteToEEPROMState ( void ) +static NVM_EXEC_STATE_T handleExecWriteState( void ) { - NVM_EXEC_STATE_T state = NVM_EXEC_STATE_WRITE_TO_EEPROM; - BOOL timeoutStatus = didCommandTimeout( state ); + NVM_EXEC_STATE_T state = NVM_EXEC_STATE_WRITE; + BOOL timeoutStatus = didCommandTimeout( state ); PROCESS_RECORD_JOB_T recordCurrentJob = getCurrentProcessRecordJob(); - NVM_RECORD_TYPE_T job = recordCurrentJob.recordJob; - PROCESS_RECORD_SPECS_T jobSpecs = getProcessRecord ( job ); + NVM_RECORD_TYPE_T job = recordCurrentJob.recordJob; + PROCESS_RECORD_SPECS_T jobSpecs = getProcessRecord( job ); // Check if the fapi has finished if ( TRUE == isFlashReady() ) { - // Check the integrity of data (the 16 bytes that were written to EEPROM should be read and be checked for each byte) + // Check the integrity of data (the 16 bytes that were written to + // EEPROM should be read and be checked for each byte) if ( writtenRecordStatus == NVM_RECORD_NOT_CHECKED ) { - currentTime = getMSTimerCount(); + currentTime = getMSTimerCount(); U32 recordFlashAddress = jobSpecs.recordFlashAddress + recordAddressOffset; - U32 maxBufferLength = MAX_EEPROM_WRITE_BUFFER_BYTES / EEPROM_OPS_SIZE_OF_CONVERTER; + U32 maxBufferLength = MAX_EEPROM_WRITE_BUFFER_BYTES / EEPROM_OPS_SIZE_OF_CONVERTER; // Clear the buffer from the previous content memset( writtenRecordCheckBuffer, 0, sizeof( writtenRecordCheckBuffer ) ); // Issue a FAPI read command but only the bytes that were written, so use maxBufferLength - readSector( (U32*)recordFlashAddress, (U32*)writtenRecordCheckBuffer, maxBufferLength ); + readSector( (U32*)recordFlashAddress, + (U32*)writtenRecordCheckBuffer, + maxBufferLength ); - state = NVM_EXEC_STATE_VERIFY_EEPROM_WRITE; + state = NVM_EXEC_STATE_VERIFY_WRITE; } else if ( writtenRecordStatus == NVM_RECORD_VALID ) { @@ -286,13 +308,12 @@ else { // Update the variables and issue the next write command - currentTime = getMSTimerCount(); + currentTime = getMSTimerCount(); recordAddressOffset += MAX_EEPROM_WRITE_BUFFER_BYTES; - U32 memoryPtr = jobSpecs.recordFlashAddress + recordAddressOffset; - U08* structPtr = jobSpecs.structAddressPtr + recordAddressOffset; + U32 memoryPtr = jobSpecs.recordFlashAddress + recordAddressOffset; + U08* structPtr = jobSpecs.structAddressPtr + recordAddressOffset; + writtenRecordStatus = NVM_RECORD_NOT_CHECKED; - writtenRecordStatus = NVM_RECORD_NOT_CHECKED; - // Issue the write command writeSector( (U32*)memoryPtr, structPtr, MAX_EEPROM_WRITE_BUFFER_BYTES ); } @@ -310,16 +331,17 @@ /*********************************************************************//** * @brief - * The handleExecReadFromEEPROMState issues a read command to EEPROM on entry - * and if the read was successful, it sets the state to Idle. - * @details Inputs: None - * @details Outputs: None - * @return next state + * The handleExecReadState function handles the read state of the NVM + * execution state machine. It waits for read completion and transitions + * to idle when done or on timeout. + * @details \b Inputs: none + * @details \b Outputs: none + * @return state next state of the state machine *************************************************************************/ -static NVM_EXEC_STATE_T handleExecReadFromEEPROMState ( void ) +static NVM_EXEC_STATE_T handleExecReadState( void ) { - NVM_EXEC_STATE_T state = NVM_EXEC_STATE_READ_FROM_EEPROM; - BOOL timeoutStatus = didCommandTimeout( state ); + NVM_EXEC_STATE_T state = NVM_EXEC_STATE_READ; + BOOL timeoutStatus = didCommandTimeout( state ); if ( ( TRUE == isFlashReady() ) || ( TRUE == timeoutStatus ) ) { @@ -331,21 +353,20 @@ /*********************************************************************//** * @brief - * The handleExecVerifyEEPROMWriteState checks all the bytes that were - * written to EEPROM to ensure they match the data in the NV memory. - * @details Inputs: recordAddressOffset, writtenRecordCheckBuffer, - * writtenRecordStatus - * @details Outputs: recordAddressOffset, writtenRecordCheckBuffer, - * writtenRecordStatus - * @return next state of the state machine + * The handleExecVerifyWriteState function verifies the data written to + * EEPROM by comparing it with the source data. It schedules a rewrite + * if mismatch is detected or continues the write process if valid. + * @details \b Inputs: recordAddressOffset,writtenRecordCheckBuffer + * @details \b Outputs: writtenRecordStatus + * @return state next state of the state machine *************************************************************************/ -static NVM_EXEC_STATE_T handleExecVerifyEEPROMWriteState ( void ) +static NVM_EXEC_STATE_T handleExecVerifyWriteState( void ) { - NVM_EXEC_STATE_T state = NVM_EXEC_STATE_VERIFY_EEPROM_WRITE; - BOOL timeoutStatus = didCommandTimeout( state ); + NVM_EXEC_STATE_T state = NVM_EXEC_STATE_VERIFY_WRITE; + BOOL timeoutStatus = didCommandTimeout( state ); PROCESS_RECORD_JOB_T recordCurrentJob = getCurrentProcessRecordJob(); - NVM_RECORD_TYPE_T job = recordCurrentJob.recordJob; - PROCESS_RECORD_SPECS_T jobSpecs = getProcessRecord ( job ); + NVM_RECORD_TYPE_T job = recordCurrentJob.recordJob; + PROCESS_RECORD_SPECS_T jobSpecs = getProcessRecord( job ); // Check if the flash is ready if ( TRUE == isFlashReady() ) @@ -374,7 +395,7 @@ // Record data is valid so far writtenRecordStatus = NVM_RECORD_VALID; // Go back write to EEPROM state to continue writing the record data - state = NVM_EXEC_STATE_WRITE_TO_EEPROM; + state = NVM_EXEC_STATE_WRITE; } } } @@ -385,11 +406,12 @@ /*********************************************************************//** * @brief * The resetNVMPOSTState function resets the NV data management POST - * state and enqueues all the NV records to be read again from the NV memory. - * @details Inputs: none - * @details Outputs: nvDataMgmtSelfTestState, nvDataMgmtSelfTestResult + * state and sets the self-test to start reading all the records. + * @details \b Inputs: none + * @details \b Outputs: none * @return none *************************************************************************/ + void resetNVMPOSTState( void ) { updateNVSelfTestResult( SELF_TEST_STATUS_IN_PROGRESS ); @@ -398,21 +420,79 @@ /*********************************************************************//** * @brief - * The didCommandTimedout checks whether the a command whether RTC RAM or - * EEPROM has timedout. If it has timedout, it sets the alarm and turns - * flag to TRUE. - * @details Inputs: none - * @details Outputs: alarm if command timed out - * @param state the state that the command timed out - * @return TRUE if a command timed out + * The execNVMProcessRecord function executes the NVM process record + * handler. + * @details \b Inputs: none + * @details \b Outputs: none + * @return none *************************************************************************/ -static BOOL didCommandTimeout ( NVM_EXEC_STATE_T state ) +void execNVMProcessRecord( void ) { + execNVMPSendReceiveRecord(); +} + +/*********************************************************************//** + * @brief + * The execNVMSelfTest function executes the NV management self-test + * handler. + * @details \b Inputs: none + * @details \b Outputs: none + * @return SELF_TEST_STATUS_T self-test result + *************************************************************************/ +SELF_TEST_STATUS_T execNVMSelfTest( void ) +{ + execNVMRecordsSelfTest(); +} + +/*********************************************************************//** + * @brief + * The getNVRecord2Driver function retrieves NV data by calling the + * record handler after validating input parameters. + * @details \b Inputs: none + * @details \b Outputs: none + * @param nvData The non-volatile data identifier + * @param bufferAddress Pointer to the buffer where data will be copied + * @param bufferLength Length of the provided buffer + * @param numOfSnsrs2Check Number of sensors to check + * @param nvAlarm Alarm to raise if data is invalid + * @return TRUE if the operation is successful otherwise FALSE + *************************************************************************/ +BOOL getNVRecord2Driver( NV_DATA_T nvData, U08* bufferAddress, U32 bufferLength, + U08 numOfSnsrs2Check, ALARM_ID_T nvAlarm ) +{ BOOL status = FALSE; + if ( ( nvData < NUM_OF_NV_DD_DATA ) && + ( NULL != bufferAddress ) && + ( bufferLength > 0U ) ) + { + status = getNVMRecord(nvData, bufferAddress, + bufferLength, numOfSnsrs2Check, nvAlarm); + } + + return status; +} + +/*********************************************************************//** + * @brief + * The didCommandTimeout function checks whether the command has timed + * out. If a timeout occurs, it sets an alarm and returns TRUE. + * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT if command timeout + * occurs + * @details \b Inputs: currentTime + * @details \b Outputs: none + * @param state The state in which the command timed out + * @return TRUE if a command timed out otherwise FALSE + *************************************************************************/ +static BOOL didCommandTimeout( NVM_EXEC_STATE_T state ) +{ + BOOL status = FALSE; + if ( TRUE == didTimeout( currentTime, COMMAND_TIME_OUT ) ) { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_NVM_OPS_TIMEOUT, ( U32 )state ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, + SW_FAULT_ID_NVM_OPS_TIMEOUT, + ( U32 )state ) status = TRUE; }