Beispiel #1
0
/*${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_;
}
Beispiel #2
0
/*${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_;
}
Beispiel #3
0
/*${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_;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
/*${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_;
}
Beispiel #7
0
/*${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_;
}
Beispiel #8
0
/*${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_;
}
Beispiel #9
0
/*${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_;
}
Beispiel #10
0
/*${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_;
}