Index: firmware/App/Services/NVMsgQ.c =================================================================== diff -u -rb878faee61a0800b767d053ab3f65afb3790dacb -rf525d2be1e7038cacbe2bb34b8db3505cf26a350 --- firmware/App/Services/NVMsgQ.c (.../NVMsgQ.c) (revision b878faee61a0800b767d053ab3f65afb3790dacb) +++ firmware/App/Services/NVMsgQ.c (.../NVMsgQ.c) (revision f525d2be1e7038cacbe2bb34b8db3505cf26a350) @@ -82,7 +82,6 @@ F32 minInletWaterCondAlarmLimitUSPCM; ///< Min inlet water conductivity alarm limit in uS/cm. } DD_INSTITUTIONAL_VALUES_T; - /// Process records job structure typedef struct { @@ -105,9 +104,10 @@ static BOOL isNewNVRecordAvailable; ///< Signal to indicate whether a new NVM data is available. static RECORD_JOBS_STATE_T recordToPublish; ///< Record to publish (i.e. calibration, system) +static RECORD_JOBS_STATE_T nvPublishRecordType; static SEND_RECORD_STATE_T nvMExecSendRecordState; ///< NVDataMgmt exec process record state. static RECEIVE_RECORD_STATE_T nvmExecReceiveRecordState; ///< NVDataMgmt exec receive record state. -static RECORD_JOBS_STATE_T nvPublishRecordType; +static RECORD_JOBS_STATE_T currentRxRecordType; static BOOL isPublishRecordRequested[ NUM_OF_NVDATMGMT_RECORDS_JOBS ]; ///< Record state machine publish request flag. static U32 recordPublishMsgCount; ///< Record data publish message counter. static U32 recordPublishTotalMsgs; ///< Record data total number of messages to be sent. @@ -117,50 +117,17 @@ static U32 recordReceiveStartTime; ///< Time stamp the calibration/service was received. static U32 newRecordStartTimer; ///< New record availability start timer. -/// Process records specifications structure -typedef struct -{ - U32 sizeofRecord; ///< Jobs spec size of job. - U08* structAddressPtr; ///< Jobs structure address pointer. - U08* structCRCPtr; ///< Jobs structure CRC pointer. -} RECEIVE_RECORD_SPECS_T; -// Temporary Record variable used only for receiving record before crc verification -static DD_SYSTEM_GROUP_T ddTempReceivedSystemGrp; ///< DD system group structure (including padding and final CRC). -static DD_SERVICE_GROUP_T ddTempReceivedServiceGrp; ///< DD service group structure (including padding and final CRC). -static DD_CALIBRATION_RECORD_T ddTempReceivedCalRecord; ///< DD calibration record structure (including padding and final CRC). -static DD_INSTITUTIONAL_GROUP_T ddTempReceivedInstitGrp; ///< DD institutional group structure (including padding and final CRC). -static DD_USAGE_INFO_GROUP_T ddTempReceivedUsageGrp; ///< DD usage info structure (including padding and final CRC). -// Temporary Process records specifications -const RECEIVE_RECORD_SPECS_T receivedRecords[ NUM_OF_NVDATMGMT_RECORDS_JOBS ] = { - //Size of the job Max read bytes per job Record structure pointer Record CRC pointer Event calibration record update - sizeof(DD_SYSTEM_GROUP_T), sizeof(DD_SYSTEM_GROUP_T), (U08*)&ddTempRxSystemGrp, (U08*)&ddTempReceivedSystemGrp.crc, }, // NVDATAMGMT_SYSTEM_RECORD - sizeof(DD_SERVICE_GROUP_T), sizeof(DD_SERVICE_GROUP_T), (U08*)&ddTempRxServiceGrp, (U08*)&ddTempReceivedServiceGrp.crc, }, // NVDATAMGMT_SERVICE_RECORD - sizeof(DD_CALIBRATION_RECORD_T), sizeof(DD_CALIBRATION_RECORD_T), (U08*)&ddTempRxCalRecord, (U08*)&ddTempReceivedCalRecord.crc, }, // NVDATAMGMT_CALIBRATION_RECORD - sizeof(DD_INSTITUTIONAL_GROUP_T), sizeof(DD_INSTITUTIONAL_GROUP_T), (U08*)&ddTempRxInstitGrp, (U08*)&ddTempReceivedInstitGrp.crc, }, // NVDATAMGMT_INSTITUTIONAL_RECORD - sizeof(DD_USAGE_INFO_GROUP_T), sizeof(DD_USAGE_INFO_GROUP_T), (U08*)&ddTempRxUsageGrp, (U08*)&ddTempReceivedUsageGrp.crc, }, // NVDATAMGMT_USAGE_INFO_RECORD -}; - -// Process records specifications -static PROCESS_RECORD_SPECS_T receivedRecords[ NUM_OF_NVDATMGMT_RECORDS_JOBS ] - // Start address Size of the job Record structure pointer Record CRC pointer Event calibration record update - {SYSTEM_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SYSTEM_GROUP_T), (U08*)&ddTempRxSystemGrp, (U08*)&ddTempRxSystemGrp.crc, DD_EVENT_SYSTEM_RECORD_UPDATE }, // NVDATAMGMT_SYSTEM_RECORD - {SERVICE_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_SERVICE_GROUP_T), (U08*)&ddTempRxServiceGrp, (U08*)&ddTempRxServiceGrp.crc, DD_EVENT_SERVICE_UPDATE }, // NVDATAMGMT_SERVICE_RECORD - {CAL_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_CALIBRATION_RECORD_T), (U08*)&ddTempRxCalRecord, (U08*)&ddTempRxCalRecord.crc, DD_EVENT_CAL_RECORD_UPDATE }, // NVDATAMGMT_CALIBRATION_RECORD - {INSTIT_RECORD_NV_MEM_START_ADDRESS, sizeof(DD_INSTITUTIONAL_GROUP_T), (U08*)&ddTempRxInstitGrp, (U08*)&ddTempRxInstitGrp.crc, DD_EVENT_INSTIT_RECORD_UPDATE }, // NVDATAMGMT_INSTITUTIONAL_RECORD - {USAGE_INFO_START_ADDRESS, sizeof(DD_USAGE_INFO_GROUP_T), (U08*)&ddTempRxUsageGrp, (U08*)&ddTempRxUsageGrp.crc, DD_EVENT_USAGE_INFO_UPDATE }, // NVDATAMGMT_USAGE_INFO_RECORD -}; - // ********** private function prototypes ********** // Process record functions static SEND_RECORD_STATE_T handleExecSendRecordIdleState( void ); static SEND_RECORD_STATE_T handleExecSendRecordSendState( void ); -static void sendInstitutionalRecordToUI( DD_INSTITUTIONAL_LOCAL_RECORD_T* instit ); -static void handleDGRequestInstitutionalValues( MESSAGE_T* message ); static BOOL sendDDRecord( MSG_ID_T msgId, U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* calRcrdAddress ); +static BOOL receiveDDRecord( MESSAGE_T *message ); +static BOOL verifyAndSaveReceivedRecord( RECORD_JOBS_STATE_T job, U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ); static RECORD_JOBS_STATE_T getNVMRecordJobState( MSG_ID_T msgID ); static MSG_ID_T getNVMRecordResponseMsgId (RECORD_JOBS_STATE_T job ); static void monitorNewCalSignal( void ); @@ -177,10 +144,11 @@ nvMExecSendRecordState = NVM_SEND_RECORD_STATE_IDLE; nvmExecReceiveRecordState = NVM_RECEIVE_RECORD_STATE_IDLE; - nvPublishRecordType = NVDATAMGMT_CALIBRATION_RECORD; - isPublishRecordRequested[ NVDATAMGMT_CALIBRATION_RECORD ] = FALSE; + nvPublishRecordType = NVDATAMGMT_SYSTEM_RECORD; isPublishRecordRequested[ NVDATAMGMT_SYSTEM_RECORD ] = FALSE; isPublishRecordRequested[ NVDATAMGMT_SERVICE_RECORD ] = FALSE; + isPublishRecordRequested[ NVDATAMGMT_CALIBRATION_RECORD ] = FALSE; + isPublishRecordRequested[ NVDATAMGMT_INSTITUTIONAL_RECORD ] = FALSE; isPublishRecordRequested[ NVDATAMGMT_USAGE_INFO_RECORD ] = FALSE; newRecordStartTimer = 0; @@ -230,7 +198,7 @@ if ( TRUE == didTimeout( recordReceiveStartTime, RECORD_DATA_RECEIVE_TIMEOUT_MS ) ) { // Exec receive state machine timed out. Schedule a read to update the structure - enqueueRecordJob( NVDATAMGMT_READ, NVDATAMGMT_CALIBRATION_RECORD ); + enqueueRecordJob( NVDATAMGMT_READ, currentRxRecordType ); nvmExecReceiveRecordState = NVM_RECEIVE_RECORD_STATE_IDLE; } } @@ -278,7 +246,7 @@ nvPublishRecordType = ( RECORD_JOBS_STATE_T )( nvPublishRecordType + 1 ); if(nvPublishRecordType >= NUM_OF_NVDATMGMT_RECORDS_JOBS) { - nvPublishRecordType = NVDATAMGMT_CALIBRATION_RECORD; + nvPublishRecordType = NVDATAMGMT_SYSTEM_RECORD; } return state; @@ -432,29 +400,24 @@ return QUEUE_MAX_SIZE - recordQueueCount; } -/*********************************************************************//** - * @brief - * The enqueueSector0Records checks whether there are enough jobs available - * to be able to enqueue to the records. - * @details Inputs: none - * @details Outputs: none - * @return TRUE if the job were successfully enqueued otherwise, FLASE - *************************************************************************/ -BOOL enqueueSector0Records( void ) +BOOL enqueueEraseAndWriteSector( RECORD_JOBS_STATE_T job ) { BOOL status = FALSE; - if ( getAvailableRecordQueueCount() >= MIN_JOBS_NEEDED_FOR_ALL_RECORDS ) + if ( getAvailableRecordQueueCount() >= MIN_JOBS_NEEDED_FOR_A_RECORD ) { - RECORD_JOBS_STATE_T record; - - // It is sector 0 of bank 7 so the sector must be erased first - enqueueRecordJob( NVDATAMGMT_ERASE_SECTOR, NVDATAMGMT_CALIBRATION_RECORD ); - - for ( record = NVDATAMGMT_CALIBRATION_RECORD; record < NUM_OF_NVDATMGMT_RECORDS_JOBS; record++ ) + // Service and Calibration record are stored in the same sector. + if( ( job == NVDATAMGMT_SERVICE_RECORD ) || ( job == NVDATAMGMT_CALIBRATION_RECORD ) ) { - enqueueRecordJob( NVDATAMGMT_WRITE, record ); + enqueueRecordJob( NVDATAMGMT_ERASE_SECTOR, NVDATAMGMT_SERVICE_RECORD ); + enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_SERVICE_RECORD ); + enqueueRecordJob( NVDATAMGMT_WRITE, NVDATAMGMT_CALIBRATION_RECORD ); } + else + { + enqueueRecordJob( NVDATAMGMT_ERASE_SECTOR, job ); + enqueueRecordJob( NVDATAMGMT_WRITE, job ); + } status = TRUE; } @@ -499,7 +462,7 @@ { RECORD_JOBS_STATE_T record; - for ( record = NVDATAMGMT_CALIBRATION_RECORD; record < NUM_OF_NVDATMGMT_RECORDS_JOBS; record++ ) + for ( record = NVDATAMGMT_SYSTEM_RECORD; record < NUM_OF_NVDATMGMT_RECORDS_JOBS; record++ ) { enqueueRecordJob( NVDATAMGMT_READ, record ); } @@ -545,16 +508,37 @@ } /*********************************************************************//** -* @brief -* The handleSetDGSystemRecord function handles a request to set the DG -* system data record. -* @details Inputs: none -* @details Outputs: message handled -* @param message a pointer to the message to handle -* @return none -*************************************************************************/ -BOOL testDDSetNVRecord( MESSAGE_T *message ) + * @brief + * The sendDDCalibrationRecord function sends out the DD calibration + * record. + * @details Inputs: none + * @details Outputs: DG calibration record msg constructed and queued + * @param msgId : Message Id for response record + * @param msgCurrNum: current payload number + * @param msgTotalNum: total number of payloads + * @param length: buffer length to be written + * @param recordAddress: start address of the calibration record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +static BOOL sendDDRecord( MSG_ID_T msgId, U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* recordAddress ) { + BOOL result = FALSE; + U08 payloadLen = 0; + DD_NVM_RECORD_PAYLOAD_T payload; + + payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; + payload.payloadCurrNum = payloadCurrNum; + payload.payloadTotalNum = payloadTotalNum; + payload.length = length; + memcpy( payload.data, recordAddress, length ); + result = sendMessage( msgId, COMM_BUFFER_OUT_DD_CAN_PC, (U08 *)&payload, payloadLen ); + + return result; +} + + +static BOOL receiveDDRecord( MESSAGE_T *message ) +{ BOOL status = FALSE; U32 currentMessage; U32 totalMessages; @@ -567,9 +551,9 @@ BOOL isValidPayloadLen = ( message->hdr.payloadLen >= minPayloadLen); - BOOL isServiceJob = ( ( job == NVDATAMGMT_CALIBRATION_RECORD ) || - ( job == NVDATAMGMT_SYSTEM_RECORD ) || - ( job == NVDATAMGMT_SERVICE_RECORD ) ); + BOOL isServiceJob = ( ( job == NVDATAMGMT_SYSTEM_RECORD ) || + ( job == NVDATAMGMT_SERVICE_RECORD ) || + ( job == NVDATAMGMT_CALIBRATION_RECORD ) ); BOOL isServiceMode = ( DD_MODE_SERV == getCurrentOperationMode() ); @@ -585,103 +569,15 @@ memcpy(&payloadLength, payloadPtr, sizeof(U32)); payloadPtr += sizeof(U32); - status = receiveRecordFromDialin( job, currentMessage, totalMessages, payloadLength, payloadPtr ); + status = verifyAndSaveReceivedRecord( job, currentMessage, totalMessages, payloadLength, payloadPtr ); } return status; } /*********************************************************************//** * @brief - * The handleSendInstitutionalRecordToUI function sends the institutional record to UI - * @details Inputs: none - * @details Outputs: none - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -void handleSendInstitutionalRecordToUI( MESSAGE_T* message ) -{ - if ( 0 == message->hdr.payloadLen ) - { - DD_INSTITUTIONAL_RECORD_T ddInstitutionalRecord; - DD_INSTITUTIONAL_LOCAL_RECORD_T ddInstitutionalLocalRecord; - - getNVRecord2Driver( GET_INSTITUTIONAL_RECORD, (U08*)&ddInstitutionalRecord, sizeof( DD_INSTITUTIONAL_RECORD_T ), 0, ALARM_ID_NO_ALARM ); - - memcpy( &ddInstitutionalLocalRecord, &ddInstitutionalRecord, sizeof( DD_INSTITUTIONAL_LOCAL_RECORD_T ) ); - - sendInstitutionalRecordToUI( &ddInstitutionalLocalRecord ); - } -} - -/*********************************************************************//** - * @brief - * The sendInstitutionalRecordToUI function sends the institutional record to UI - * @details Inputs: none - * @details Outputs: none - * @param instit a pointer to the local institutional recored in the system - * messages that is without calibration time and crc - * @return none - *************************************************************************/ -static void sendInstitutionalRecordToUI( DD_INSTITUTIONAL_LOCAL_RECORD_T* instit ) -{ - MESSAGE_T msg; - - U08 *payloadPtr = msg.payload; - U32 accept = 1; - U32 reason = 0; - - // Create a message record - blankMessage( &msg ); -// msg.hdr.msgID = MSG_ID_HD_INSTITUTIONAL_RECORD_RESPONSE; - msg.hdr.payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( DD_INSTITUTIONAL_LOCAL_RECORD_T ); - - memcpy( payloadPtr, &accept, sizeof( U32 ) ); - payloadPtr += sizeof( U32 ); - memcpy( payloadPtr, &reason, sizeof( U32 ) ); - payloadPtr += sizeof( U32 ); - memcpy( payloadPtr, instit, sizeof( DD_INSTITUTIONAL_LOCAL_RECORD_T ) ); - - // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer -// serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); -} - -/*********************************************************************//** - * @brief - * The handleDGRequestInstitutionalValues function handles the DG request - * to receive the DG institutional values from HD institutional record. - * @details Inputs: none - * @details Outputs: none - * @param message a pointer to the message to handle - * @return none - *************************************************************************/ -static void handleDGRequestInstitutionalValues( MESSAGE_T* message ) -{ - if ( 0 == message->hdr.payloadLen ) - { - MESSAGE_T msg; - DD_INSTITUTIONAL_VALUES_T ddInstitValues; - - ddInstitValues.minRORejectionRatioPCT = getMinRORejectionRatioInInstitRecordPCT(); - ddInstitValues.minInletWaterCondAlarmLimitUSPCM = getMinInletWaterConductivityLimitInstitRecordUSPCM(); - - // Create a message record - blankMessage( &msg ); -// msg.hdr.msgID = MSG_ID_DG_INSTIT_VALUES_FROM_HD_INSTIT_RECORD_RESPONSE; - msg.hdr.payloadLen = sizeof( DD_INSTITUTIONAL_VALUES_T ); - - memcpy( msg.payload, &ddInstitValues, sizeof( DD_INSTITUTIONAL_VALUES_T ) ); - - // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer -// serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_DG, ACK_REQUIRED ); - } -} - - - -/*********************************************************************//** - * @brief - * The receiveRecordFromDialin function receives the record that has been sent + * The verifyAndSaveReceivedRecord function receives the record that has been sent * from Dialin and if the CRCs passed, it schedules a write to the NV data. * @details Inputs: currentMessage, nvmExecReceiveRecordState, * previousRecordMessageNum, totalMessages, previousRecordMessageNum, @@ -694,14 +590,15 @@ * @param *addressPtr: address to the beginning of the calibration data from Dialin * @return TRUE if the request was successfully registered *************************************************************************/ -BOOL receiveRecordFromDialin( RECORD_JOBS_STATE_T job, U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ) +BOOL verifyAndSaveReceivedRecord( RECORD_JOBS_STATE_T job, U32 currentMessage, U32 totalMessages, U32 length, U08 *addressPtr ) { BOOL status = TRUE; // If the calibration message number is the first message number and receive exec state is idle, switch to idle if ( ( RECORD_DATA_FIRST_RECEIVING_MSG_NUM == currentMessage ) && ( NVM_RECEIVE_RECORD_STATE_IDLE == nvmExecReceiveRecordState ) ) { nvmExecReceiveRecordState = NVM_RECEIVE_RECORD_STATE_RECEIVE; + currentRxRecordType = job; recordReceiveStartTime = getMSTimerCount(); previousRecordMessageNum = 0; recordUpdateAddress = 0; @@ -713,57 +610,35 @@ // Check if the current message is different from the previous message by 1 if ( RECORD_DATA_MAX_MESSAGE_DFFIRENCE == ( currentMessage - previousRecordMessageNum ) ) { - // Define a pointer that points to the DD nvm record + // Define a pointer that points to the temporary receive record + PROCESS_RECORD_SPECS_T tempRxSpec = getTemporaryRxRecord( job ); + U08* tempRxPtr = tempRxSpec.structAddressPtr; + + // Get the DD main nvm record PROCESS_RECORD_SPECS_T recordSpec = getProcessRecord( job ); - U08* ptr = recordSpec.structAddressPtr; // Offset the pointer to length that we should start writing from - ptr += recordUpdateAddress; + tempRxPtr += recordUpdateAddress; - memcpy( ptr, addressPtr, length ); + memcpy( tempRxPtr, addressPtr, length ); // Check if the current message is total messages // and 0 everything out since we are done writing if ( currentMessage == totalMessages ) { - // Assume the institutional record is fine unless the record is really the institutional record - BOOL isInstRcrdValid = TRUE; - U16 calcCRC = crc16 ( recordSpec.structAddressPtr, recordSpec.sizeofRecord - sizeof(U16) ); + U16 calcCRC = crc16 ( tempRxSpec.structAddressPtr, tempRxSpec.sizeofRecord - sizeof(U16) ); // Get the CRC of the structure without the last 16 bits which is the CRC as well as the padding values - U16 recordCRC = *(U16*)recordSpec.structCRCPtr; + U16 recordCRC = *(U16*)tempRxSpec.structCRCPtr; - if ( NVDATAMGMT_INSTITUTIONAL_RECORD == job ) + // Check if calculated CRC matches the Stored CRC + if ( ( calcCRC == recordCRC ) ) { -// isInstRcrdValid = isNVInstitutionalRecordInRange( &ddInstitutionalGroup.ddInstitutionalRecord ); - status = isInstRcrdValid; - } + // Copy the valid temporary record into the main record spec + memcpy(recordSpec.structAddressPtr, tempRxSpec.structAddressPtr, tempRxSpec.sizeofRecord); - if ( ( calcCRC != recordCRC ) || ( FALSE == isInstRcrdValid ) ) - { - // Institutional record has failed so do not write it into the NV memory and read back what was in the NV memory - // CRC failed, request a read to read the data back from NV memory and update the structure - enqueueRecordJob( NVDATAMGMT_READ, job ); + // Enqueue an erase and write of the nvm record + status = enqueueEraseAndWriteSector( job ); - nvmExecReceiveRecordState = NVM_RECEIVE_RECORD_STATE_IDLE; - status = FALSE; - } - else - { - // CRC passed, enqueue an erase, a write of calibration data and a write of service record - BOOL scheduleStatus = enqueueSector0Records(); - - MESSAGE_T institMsg; - // Got new data for the EEPROM records, set the latest institutional record to treatment parameters to make sure - // the treatment parameters have the record available all the time -// setNVInstitutionalRecordToTxParamsRecord( &ddInstitutionalGroup.ddInstitutionalRecord ); - - // Received new institutional record and it is valid, send it to the UI to be up to date - institMsg.hdr.msgID = 0; - institMsg.hdr.payloadLen = 0; - handleSendInstitutionalRecordToUI( &institMsg ); - // Received new institutional record and it is valid, send it to the DG to be up to date - handleDGRequestInstitutionalValues( &institMsg ); - // Signal that there is a new calibration record available. // NOTE: as of now, this signal will be sent even after the system record is sent newRecordStartTimer = getMSTimerCount(); @@ -775,6 +650,12 @@ // Done with receiving data, go back to idle nvmExecReceiveRecordState = NVM_RECEIVE_RECORD_STATE_IDLE; } + else + { + // CRC match failed, go to idle + nvmExecReceiveRecordState = NVM_RECEIVE_RECORD_STATE_IDLE; + status = FALSE; + } } else { @@ -790,35 +671,6 @@ return status; } -/*********************************************************************//** - * @brief - * The sendDDCalibrationRecord function sends out the DD calibration - * record. - * @details Inputs: none - * @details Outputs: DG calibration record msg constructed and queued - * @param msgId : Message Id for response record - * @param msgCurrNum: current payload number - * @param msgTotalNum: total number of payloads - * @param length: buffer length to be written - * @param recordAddress: start address of the calibration record - * @return TRUE if msg successfully queued for transmit, FALSE if not - *************************************************************************/ -static BOOL sendDDRecord( MSG_ID_T msgId, U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* recordAddress ) -{ - BOOL result = FALSE; - U08 payloadLen = 0; - DD_NVM_RECORD_PAYLOAD_T payload; - - payloadLen = sizeof( U32 ) + sizeof( U32 ) + sizeof( U32 ) + length; - payload.payloadCurrNum = payloadCurrNum; - payload.payloadTotalNum = payloadTotalNum; - payload.length = length; - memcpy( payload.data, recordAddress, length ); - result = sendMessage( msgId, COMM_BUFFER_OUT_DD_CAN_PC, (U08 *)&payload, payloadLen ); - - return result; -} - static RECORD_JOBS_STATE_T getNVMRecordJobState( MSG_ID_T msgID ) { RECORD_JOBS_STATE_T job;