/*${AOs::FlashMgr::SM::Active::BusyFlash} ..................................*/ static QState FlashMgr_BusyFlash(FlashMgr * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* ${AOs::FlashMgr::SM::Active::BusyFlash} */ case Q_ENTRY_SIG: { /* Arm the timer so if the message can't be processed for some reason, we can get * back to idle state. This timer may be re-armed if some messages require more * time to process than others. */ QTimeEvt_rearm( /* Re-arm timer on entry */ &me->flashTimerEvt, SEC_TO_TICKS( HL_MAX_TOUT_SEC_FLASH_FW ) ); FLASH_Unlock();/* Always unlock the flash on entry since we'll be doing stuff to it */ /* Reset all the variables that keep track of FW upgrades on entry so they are * guaranteed to be cleared when we start any new operation */ memset( me->flashSectorsToErase, 0, sizeof(me->flashSectorsToErase) ); me->flashSectorsToEraseIndex = 0; me->flashSectorsToEraseNum = 0; me->fwPacketCurr = 0; me->fwPacketExp = 0; me->retryCurr = 0; status_ = Q_HANDLED(); break; } /* ${AOs::FlashMgr::SM::Active::BusyFlash} */ case Q_EXIT_SIG: { QTimeEvt_disarm(&me->flashTimerEvt); /* Disarm timer on exit */ FLASH_Lock(); /* Always lock the flash on exit */ /* Always send a flash status event to the CommMgr AO with the current error code */ FlashStatusEvt *evt = Q_NEW(FlashStatusEvt, FLASH_OP_DONE_SIG); evt->errorCode = me->errorCode; QACTIVE_POST(AO_CommMgr, (QEvt *)(evt), AO_FlashMgr); status_ = Q_HANDLED(); break; } /* ${AOs::FlashMgr::SM::Active::BusyFlash::FLASH_TIMEOUT} */ case FLASH_TIMEOUT_SIG: { ERR_printf("Timeout trying to process flash request, error: 0x%08x\n", me->errorCode); status_ = Q_TRAN(&FlashMgr_Idle); break; } /* ${AOs::FlashMgr::SM::Active::BusyFlash::FLASH_ERROR} */ case FLASH_ERROR_SIG: { ERR_printf("Unable to to process flash request. Error: 0x%08x\n", me->errorCode); status_ = Q_TRAN(&FlashMgr_Idle); break; } default: { status_ = Q_SUPER(&FlashMgr_Active); break; } } return status_; }
/*${AOs::SerialMgr::SM::Active::Busy} ......................................*/ static QState SerialMgr_Busy(SerialMgr * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* ${AOs::SerialMgr::SM::Active::Busy} */ case Q_ENTRY_SIG: { /* Post a timer on entry */ QTimeEvt_rearm( &me->serialTimerEvt, SEC_TO_TICKS( LL_MAX_TIMEOUT_SERIAL_DMA_BUSY_SEC ) ); /* Start the DMA transfer over serial */ Serial_DMAStartXfer( SERIAL_UART1 ); status_ = Q_HANDLED(); break; } /* ${AOs::SerialMgr::SM::Active::Busy} */ case Q_EXIT_SIG: { QTimeEvt_disarm( &me->serialTimerEvt ); /* Disarm timer on exit */ status_ = Q_HANDLED(); break; } /* ${AOs::SerialMgr::SM::Active::Busy::UART_DMA_DONE} */ case UART_DMA_DONE_SIG: { status_ = Q_TRAN(&SerialMgr_Idle); break; } /* ${AOs::SerialMgr::SM::Active::Busy::UART_DMA_TIMEOUT} */ case UART_DMA_TIMEOUT_SIG: { err_slow_printf("UART DMA timeout occurred\n"); status_ = Q_TRAN(&SerialMgr_Idle); break; } /* ${AOs::SerialMgr::SM::Active::Busy::UART_DMA_START, ~} */ case UART_DMA_START_SIG: /* intentionally fall through */ case DBG_LOG_SIG: /* intentionally fall through */ case DBG_MENU_SIG: /* intentionally fall through */ case CLI_SEND_DATA_SIG: { if (QEQueue_getNFree(&me->deferredEvtQueue) > 0) { /* defer the request - this event will be handled * when the state machine goes back to Idle state */ QActive_defer((QActive *)me, &me->deferredEvtQueue, e); } else { /* notify the request sender that the request was ignored.. */ err_slow_printf("Unable to defer UART_DMA_START request\n"); } status_ = Q_HANDLED(); break; } default: { status_ = Q_SUPER(&SerialMgr_Active); break; } } return status_; }
/*${AOs::FlashMgr::SM::Active} .............................................*/ static QState FlashMgr_Active(FlashMgr * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* ${AOs::FlashMgr::SM::Active} */ case Q_ENTRY_SIG: { /* Arm and disarm*/ QTimeEvt_postIn( &me->flashTimerEvt, (QActive *)me, SEC_TO_TICKS( HL_MAX_TOUT_SEC_FLASH_FW ) ); QTimeEvt_disarm(&me->flashTimerEvt); QTimeEvt_postIn( &me->flashOpTimerEvt, (QActive *)me, SEC_TO_TICKS( HL_MAX_TOUT_SEC_FLASH_FW ) ); QTimeEvt_disarm(&me->flashOpTimerEvt); QTimeEvt_postIn( &me->ramTimerEvt, (QActive *)me, SEC_TO_TICKS( HL_MAX_TOUT_SEC_FLASH_FW ) ); QTimeEvt_disarm(&me->ramTimerEvt); status_ = Q_HANDLED(); break; } default: { status_ = Q_SUPER(&QHsm_top); break; } } return status_; }
static void* flush_thread_main(void *in) { hlld_config *config; hlld_setmgr *mgr; int *should_run; UNPACK_ARGS(); // Perform the initial checkpoint with the manager setmgr_client_checkpoint(mgr); syslog(LOG_INFO, "Flush thread started. Interval: %d seconds.", config->flush_interval); unsigned int ticks = 0; while (*should_run) { usleep(PERIODIC_TIME_USEC); setmgr_client_checkpoint(mgr); if ((++ticks % SEC_TO_TICKS(config->flush_interval)) == 0 && *should_run) { // Time how long this takes struct timeval start, end; gettimeofday(&start, NULL); // List all the sets syslog(LOG_INFO, "Scheduled flush started."); hlld_set_list_head *head; int res = setmgr_list_sets(mgr, NULL, &head); if (res != 0) { syslog(LOG_WARNING, "Failed to list sets for flushing!"); continue; } // Flush all, ignore errors since // sets might get deleted in the process hlld_set_list *node = head->head; unsigned int cmds = 0; while (node) { setmgr_flush_set(mgr, node->set_name); if (!(++cmds % PERIODIC_CHECKPOINT)) setmgr_client_checkpoint(mgr); node = node->next; } // Compute the elapsed time gettimeofday(&end, NULL); syslog(LOG_INFO, "Flushed %d sets in %d msecs", head->size, timediff_msec(&start, &end)); // Cleanup setmgr_cleanup_list(head); } } return NULL; }
static void* unmap_thread_main(void *in) { hlld_config *config; hlld_setmgr *mgr; int *should_run; UNPACK_ARGS(); // Perform the initial checkpoint with the manager setmgr_client_checkpoint(mgr); syslog(LOG_INFO, "Cold unmap thread started. Interval: %d seconds.", config->cold_interval); unsigned int ticks = 0; while (*should_run) { usleep(PERIODIC_TIME_USEC); setmgr_client_checkpoint(mgr); if ((++ticks % SEC_TO_TICKS(config->cold_interval)) == 0 && *should_run) { // Time how long this takes struct timeval start, end; gettimeofday(&start, NULL); // List the cold sets syslog(LOG_INFO, "Cold unmap started."); hlld_set_list_head *head; int res = setmgr_list_cold_sets(mgr, &head); if (res != 0) { continue; } // Close the sets, save memory hlld_set_list *node = head->head; unsigned int cmds = 0; while (node) { syslog(LOG_DEBUG, "Unmapping set '%s' for being cold.", node->set_name); setmgr_unmap_set(mgr, node->set_name); if (!(++cmds % PERIODIC_CHECKPOINT)) setmgr_client_checkpoint(mgr); node = node->next; } // Compute the elapsed time gettimeofday(&end, NULL); syslog(LOG_INFO, "Unmapped %d sets in %d msecs", head->size, timediff_msec(&start, &end)); // Cleanup setmgr_cleanup_list(head); } } return NULL; }
/*${AOs::FlashMgr::SM::Active::BusyRam} ....................................*/ static QState FlashMgr_BusyRam(FlashMgr * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* ${AOs::FlashMgr::SM::Active::BusyRam} */ case Q_ENTRY_SIG: { /* Arm the timer so if the message can't be processed for some reason, we can get * back to idle state. This timer may be re-armed if some messages require more * time to process than others. */ QTimeEvt_rearm( /* Re-arm timer on entry */ &me->ramTimerEvt, SEC_TO_TICKS( HL_MAX_TOUT_SEC_CLI_WAIT_FOR_RAM_TEST ) ); status_ = Q_HANDLED(); break; } /* ${AOs::FlashMgr::SM::Active::BusyRam} */ case Q_EXIT_SIG: { QTimeEvt_disarm(&me->ramTimerEvt); /* Disarm timer on exit */ /* Always send a flash status event to the CommMgr AO with the current error code */ RamStatusEvt *evt = Q_NEW(RamStatusEvt, RAM_TEST_DONE_SIG); evt->errorCode = me->errorCode; evt->test = me->currRamTest; evt->addr = me->currRamAddr; QACTIVE_POST(AO_CommMgr, (QEvt *)(evt), AO_FlashMgr); status_ = Q_HANDLED(); break; } /* ${AOs::FlashMgr::SM::Active::BusyRam::RAM_TIMEOUT} */ case RAM_TIMEOUT_SIG: { ERR_printf( "Timeout trying to process RAM test request during RAM test %d, error: 0x%08x\n", me->currRamTest, me->errorCode ); status_ = Q_TRAN(&FlashMgr_Idle); break; } default: { status_ = Q_SUPER(&FlashMgr_Active); break; } } return status_; }
/*${AOs::SerialMgr::SM::Active} ............................................*/ static QState SerialMgr_Active(SerialMgr * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* ${AOs::SerialMgr::SM::Active} */ case Q_ENTRY_SIG: { /* Post a timer and disarm it right away so it can be * rearmed at any point */ QTimeEvt_postIn( &me->serialTimerEvt, (QActive *)me, SEC_TO_TICKS( LL_MAX_TIMEOUT_SERIAL_DMA_BUSY_SEC ) ); QTimeEvt_disarm(&me->serialTimerEvt); status_ = Q_HANDLED(); break; } default: { status_ = Q_SUPER(&QHsm_top); break; } } return status_; }
/*${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash} ....................*/ static QState FlashMgr_WritingFlash(FlashMgr * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash} */ case Q_ENTRY_SIG: { me->errorCode = ERR_FLASH_WRITE_TIMEOUT; /* Set the timeout error code*/ if ( (me->fwPacketCurr + 1) % 100 == 0 ) { DBG_printf("Writing FW data packet %d of %d total.\n", me->fwPacketCurr + 1, me->fwFlashMetadata._imageNumPackets); } QTimeEvt_rearm( /* Re-arm timer on entry */ &me->flashOpTimerEvt, SEC_TO_TICKS( LL_MAX_TOUT_SEC_FLASH_DATA_WRITE ) ); uint16_t bytesWritten = 0; DC3Error_t err = FLASH_writeBuffer( me->flashAddrCurr, me->fwDataToFlash, me->fwDataToFlashLen, &bytesWritten ); me->errorCode = err; if( ERR_NONE != err || bytesWritten != me->fwDataToFlashLen) { /* Error occurred */ WRN_printf("Error flashing data: 0x%08x\n", me->errorCode); QEvt *evt = Q_NEW(QEvt, FLASH_ERROR_SIG); QACTIVE_POST(AO_FlashMgr, (QEvt *)(evt), AO_FlashMgr); } else { /* No errors */ /* Increment addr and counters */ me->flashAddrCurr += bytesWritten; me->fwPacketCurr += 1; QEvt *evt = Q_NEW(QEvt, FLASH_DONE_SIG); QACTIVE_POST(AO_FlashMgr, (QEvt *)(evt), AO_FlashMgr); } status_ = Q_HANDLED(); break; } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE} */ case FLASH_DONE_SIG: { /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[MorePackets?]} */ if (me->fwPacketCurr != me->fwPacketExp) { status_ = Q_TRAN(&FlashMgr_WaitingForFWData); } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]} */ else { DBG_printf("No more fw packets expected\n"); /* Do a check of the FW image and compare all the CRCs and sizes */ CRC_ResetDR(); uint32_t crcCheck = CRC32_Calc( (uint8_t *)FLASH_APPL_START_ADDR, me->fwFlashMetadata._imageSize ); /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[CRCMatch?]} */ if (me->fwFlashMetadata._imageCrc == crcCheck) { DBG_printf("CRCs of the FW image match, writing metadata...\n"); me->errorCode = FLASH_writeApplSize( me->fwFlashMetadata._imageSize ); /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[CRCMatch?]::[NoError?]} */ if (ERR_NONE == me->errorCode) { me->errorCode = FLASH_writeApplCRC( me->fwFlashMetadata._imageCrc ); /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[CRCMatch?]::[NoError?]::[NoError?]} */ if (ERR_NONE == me->errorCode) { me->errorCode = FLASH_writeApplMajVer( me->fwFlashMetadata._imageMaj ); /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[CRCMatch?]::[NoError?]::[NoError?]::[NoError?]} */ if (ERR_NONE == me->errorCode) { me->errorCode = FLASH_writeApplMinVer( me->fwFlashMetadata._imageMin ); /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[CRCMatch?]::[NoError?]::[NoError?]::[NoError?]::[NoError?]} */ if (ERR_NONE == me->errorCode) { me->errorCode = FLASH_writeApplBuildDatetime( (uint8_t *)me->fwFlashMetadata._imageDatetime, me->fwFlashMetadata._imageDatetime_len ); /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[CRCMatch?]::[NoError?]::[NoError?]::[NoError?]::[NoError?]::[NoError?]} */ if (ERR_NONE == me->errorCode) { LOG_printf("Successfully finished upgrading FW!\n"); status_ = Q_TRAN(&FlashMgr_Idle); } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[CRCMatch?]::[NoError?]::[NoError?]::[NoError?]::[NoError?]::[else]} */ else { ERR_printf("Unable to write image build datetime after flashing. Error: 0x%08x.\n", me->errorCode); status_ = Q_TRAN(&FlashMgr_Idle); } } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[CRCMatch?]::[NoError?]::[NoError?]::[NoError?]::[else]} */ else { ERR_printf("Unable to write image Minor Version after flashing. Error: 0x%08x.\n", me->errorCode); status_ = Q_TRAN(&FlashMgr_Idle); } } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[CRCMatch?]::[NoError?]::[NoError?]::[else]} */ else { ERR_printf("Unable to write image Major Version after flashing. Error: 0x%08x.\n", me->errorCode); status_ = Q_TRAN(&FlashMgr_Idle); } } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[CRCMatch?]::[NoError?]::[else]} */ else { ERR_printf("Unable to write image CRC after flashing. Error: 0x%08x.\n", me->errorCode); status_ = Q_TRAN(&FlashMgr_Idle); } } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[CRCMatch?]::[else]} */ else { ERR_printf("Unable to write image size after flashing. Error: 0x%08x.\n", me->errorCode); status_ = Q_TRAN(&FlashMgr_Idle); } } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_DONE::[else]::[else]} */ else { me->errorCode = ERR_FLASH_INVALID_IMAGE_CRC_AFTER_FLASH; ERR_printf("CRC check failed after flash. Error: 0x%08x.\n", me->errorCode); ERR_printf("Expected : 0x%08x\n", me->fwFlashMetadata._imageCrc); ERR_printf("Calculated: 0x%08x\n", crcCheck); status_ = Q_TRAN(&FlashMgr_Idle); } } break; } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_ERROR} */ case FLASH_ERROR_SIG: { WRN_printf("FLASH_ERROR\n"); /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_ERROR::[RetriesLeft?]} */ if (me->retryCurr < MAX_FLASH_RETRIES) { LOG_printf("Retrying to flash packet, retry %d out of %d max\n", me->retryCurr, MAX_FLASH_RETRIES); status_ = Q_TRAN(&FlashMgr_WritingFlash); } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WritingFlash::FLASH_ERROR::[else]} */ else { ERR_printf("No more retries\n"); status_ = Q_TRAN(&FlashMgr_Idle); } break; } default: { status_ = Q_SUPER(&FlashMgr_BusyFlash); break; } } return status_; }
/*${AOs::FlashMgr::SM::Active::BusyFlash::WaitingForFWData} ................*/ static QState FlashMgr_WaitingForFWData(FlashMgr * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* ${AOs::FlashMgr::SM::Active::BusyFlash::WaitingForFWData} */ case Q_ENTRY_SIG: { /* Ok, we are ready to receive FW data and start flashing. Post an event letting * CommMgr know we are ready for a data packet. */ FlashStatusEvt *evt = Q_NEW(FlashStatusEvt, FLASH_OP_DONE_SIG); evt->errorCode = me->errorCode; QACTIVE_POST(AO_CommMgr, (QEvt *)(evt), AO_FlashMgr); me->errorCode = ERR_FLASH_WAIT_FOR_DATA_TIMEOUT; /* Set the timeout error code*/ QTimeEvt_rearm( /* Re-arm timer on entry */ &me->flashOpTimerEvt, SEC_TO_TICKS( LL_MAX_TOUT_SEC_FLASH_WAIT_FOR_DATA ) ); status_ = Q_HANDLED(); break; } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WaitingForFWData} */ case Q_EXIT_SIG: { QTimeEvt_disarm(&me->flashOpTimerEvt); /* Disarm timer on exit */ status_ = Q_HANDLED(); break; } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WaitingForFWData::FLASH_DATA} */ case FLASH_DATA_SIG: { /* ${AOs::FlashMgr::SM::Active::BusyFlash::WaitingForFWData::FLASH_DATA::[ValidSeq?]} */ if (me->fwPacketCurr + 1 == ((FWDataEvt const *)e)->seqCurr) { /* Calculate packet data CRC and make sure it matches the one sent over */ CRC_ResetDR(); uint32_t CRCValue = CRC32_Calc(((FWDataEvt const *)e)->dataBuf, ((FWDataEvt const *)e)->dataLen); /* ${AOs::FlashMgr::SM::Active::BusyFlash::WaitingForFWData::FLASH_DATA::[ValidSeq?]::[ValidCRC?]} */ if (CRCValue == ((FWDataEvt const *)e)->dataCRC) { me->fwDataToFlashLen = ((FWDataEvt const *)e)->dataLen; MEMCPY( me->fwDataToFlash, ((FWDataEvt const *)e)->dataBuf, me->fwDataToFlashLen ); status_ = Q_TRAN(&FlashMgr_WritingFlash); } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WaitingForFWData::FLASH_DATA::[ValidSeq?]::[else]} */ else { me->errorCode = ERR_FLASH_INVALID_FW_PACKET_CRC; ERR_printf( "Sent CRC (0x%08x) doesn't match calculated (0x%08x) for fw packet: %d. Error: 0x%08x\n", CRCValue, ((FWDataEvt const *)e)->dataCRC, ((FWDataEvt const *)e)->seqCurr, me->errorCode); status_ = Q_TRAN(&FlashMgr_Idle); } } /* ${AOs::FlashMgr::SM::Active::BusyFlash::WaitingForFWData::FLASH_DATA::[else]} */ else { ERR_printf("Invalid fw packet sequence number. Expecting: %d, got %d\n", me->fwPacketCurr + 1, ((FWDataEvt const *)e)->seqCurr); status_ = Q_TRAN(&FlashMgr_Idle); } break; } default: { status_ = Q_SUPER(&FlashMgr_BusyFlash); break; } } return status_; }
/*${AOs::FlashMgr::SM::Active::BusyFlash::PrepFlash::ErasingSector} ........*/ static QState FlashMgr_ErasingSector(FlashMgr * const me, QEvt const * const e) { QState status_; switch (e->sig) { /* ${AOs::FlashMgr::SM::Active::BusyFlash::PrepFlash::ErasingSector} */ case Q_ENTRY_SIG: { QTimeEvt_rearm( /* Re-arm timer on entry */ &me->flashOpTimerEvt, SEC_TO_TICKS( LL_MAX_TOUT_SEC_FLASH_SECTOR_ERASE ) ); DBG_printf("Attempting to erase sector addr 0x%08x\n", me->flashSectorsToErase[ me->flashSectorsToEraseIndex ]); /* Use a separate status variable so if a timeout occurs, the timeout error won't get * overwritten */ me->errorCode = FLASH_eraseSector( me->flashSectorsToErase[ me->flashSectorsToEraseIndex ] ); /* Post event to move to the next step only AFTER the blocking call to * FLASH_eraseSector() returns */ QEvt *evt = Q_NEW(QEvt, FLASH_NEXT_STEP_SIG); QACTIVE_POST(AO_FlashMgr, (QEvt *)(evt), AO_FlashMgr); status_ = Q_HANDLED(); break; } /* ${AOs::FlashMgr::SM::Active::BusyFlash::PrepFlash::ErasingSector} */ case Q_EXIT_SIG: { QTimeEvt_disarm(&me->flashOpTimerEvt); /* Disarm timer on exit */ status_ = Q_HANDLED(); break; } /* ${AOs::FlashMgr::SM::Active::BusyFlash::PrepFlash::ErasingSector::FLASH_NEXT_STEP} */ case FLASH_NEXT_STEP_SIG: { /* ${AOs::FlashMgr::SM::Active::BusyFlash::PrepFlash::ErasingSector::FLASH_NEXT_STEP::[EraseOK?]} */ if (ERR_NONE == me->errorCode) { DBG_printf("Successfully erased sector addr 0x%08x\n", me->flashSectorsToErase[ me->flashSectorsToEraseIndex ]); me->flashSectorsToEraseIndex += 1; /* increment the index into the erase array */ /* ${AOs::FlashMgr::SM::Active::BusyFlash::PrepFlash::ErasingSector::FLASH_NEXT_STEP::[EraseOK?]::[MoreToErase?]} */ if (me->flashSectorsToEraseIndex < me->flashSectorsToEraseNum) { status_ = Q_TRAN(&FlashMgr_ErasingSector); } /* ${AOs::FlashMgr::SM::Active::BusyFlash::PrepFlash::ErasingSector::FLASH_NEXT_STEP::[EraseOK?]::[else]} */ else { status_ = Q_TRAN(&FlashMgr_WaitingForFWData); } } /* ${AOs::FlashMgr::SM::Active::BusyFlash::PrepFlash::ErasingSector::FLASH_NEXT_STEP::[else]} */ else { WRN_printf("Failed to erase flash sector 0x%08x\n", me->flashSectorsToErase[ me->flashSectorsToEraseIndex ]); /* ${AOs::FlashMgr::SM::Active::BusyFlash::PrepFlash::ErasingSector::FLASH_NEXT_STEP::[else]::[retry?]} */ if (me->retryCurr < MAX_FLASH_RETRIES) { me->retryCurr += 1; /* Increment retry counter */ WRN_printf("Attempting operation again (retry %d out of %d)...\n", me->retryCurr, MAX_FLASH_RETRIES); status_ = Q_TRAN(&FlashMgr_ErasingSector); } /* ${AOs::FlashMgr::SM::Active::BusyFlash::PrepFlash::ErasingSector::FLASH_NEXT_STEP::[else]::[else]} */ else { ERR_printf("No more retries, aborting with error: 0x%08x\n", me->errorCode); status_ = Q_TRAN(&FlashMgr_Idle); } } break; } default: { status_ = Q_SUPER(&FlashMgr_PrepFlash); break; } } return status_; }