Esempio n. 1
0
void processRebootCommand(RebootCommandPacket_t *p)
{
    PRINTF("process reboot command\n");

    if (p->doReprogram) {
        PRINTF("ext addr=0x%lx int addr=0x%x\n", p->extFlashAddress, p->intFlashAddress);

        BootParams_t bootParams;
        intFlashRead(BOOT_PARAMS_ADDRESS, &bootParams, sizeof(bootParams));
        bootParams.extFlashAddress = p->extFlashAddress;
        bootParams.intFlashAddress = p->intFlashAddress;
        bootParams.doReprogramming = 1;
        bootParams.bootRetryCount = 0;
        intFlashErase(BOOT_PARAMS_ADDRESS, sizeof(bootParams));
        intFlashWrite(BOOT_PARAMS_ADDRESS, &bootParams, sizeof(bootParams));
        (void) bootParams; // make compiler happy
    }

    // in any case, reboot the mote
    watchdogReboot();
}
Esempio n. 2
0
int main(void)
{
    // Make sure all interrupts are disabled.
    // This must be the first step, because in some cases interupt vectors are totally wrong
    // (e.g. when we get here after a soft reboot from another application)
    msp430ClearAllInterruptsNosave();

    msp430WatchdogStop();

    ledsInit();

    flashLeds(LEDS_BOOTLOADER_START);

    BootParams_t bootParams;
    intFlashRead(BOOT_PARAMS_ADDRESS, &bootParams, sizeof(bootParams));

    ++bootParams.bootRetryCount;
    if (bootParams.bootRetryCount > MAX_RETRY_COUNT) {
        bootParams.bootRetryCount = 0;
        bootParams.extFlashAddress = GOLDEN_IMAGE_ADDRESS;
        bootParams.doReprogramming = 1;
    }

    // make sure internal flash address is sane
    if (bootParams.intFlashAddress == 0xffff || bootParams.intFlashAddress < BOOTLOADER_END) {
        bootParams.intFlashAddress = SYSTEM_CODE_START;
    }

    // read voltage, and quit if not enough for writing in flash
    if (readVoltage() < THRESHOLD_VOLTAGE) {
        flashLeds(LEDS_LOW_BATTERY);
        goto exec;
    }

    // write the updated info back in flash
    intFlashErase(BOOT_PARAMS_ADDRESS, sizeof(bootParams));
    intFlashWrite(BOOT_PARAMS_ADDRESS, &bootParams, sizeof(bootParams));

    if (bootParams.doReprogramming) {
        redLedOn();

        // will be using external flash
        extFlashInit();
        extFlashWake();

        uint32_t extAddress = bootParams.extFlashAddress;

        // read number of blocks
        uint16_t imageBlockCount;
        extFlashRead(extAddress, &imageBlockCount, sizeof(uint16_t));
        extAddress += 2;

        while (imageBlockCount) {
            // read a block from external flash
            ExternalFlashBlock_t block;
            extFlashRead(extAddress, &block, sizeof(block));

            if (block.crc != crc16((uint8_t *)&block, sizeof(block) - 2)) {
                // the best we can do is to reboot now;
                // after a few tries the golden image will be loaded
                flashLeds(LEDS_CRC_ERROR);
                // no need to disable all of the interrupts (they already are),
                // just write in watchdog timer wihout password, it will generate reset.
                watchdogRebootSimple();
            }

            bool firstBlockInChunk = block.address & 0x1;
            block.address &= ~0x1;
            if (firstBlockInChunk) {
                // prepare internal flash to be written
                intFlashErase(block.address, INT_FLASH_SEGMENT_SIZE);
            }

            // program internal flash
            COMPILE_TIME_ASSERT(sizeof(block.data) == INT_FLASH_BLOCK_SIZE, ifs);
            intFlashWriteBlock(block.address, block.data, INT_FLASH_BLOCK_SIZE);

            --imageBlockCount;
            extAddress += sizeof(ExternalFlashBlock_t);
        }

        extFlashSleep();
        redLedOff();
    }

#if ENABLE_BOOT_DELAY
    // delay for a second or so to allow the user to interrupt booting (by pressing the reset button)
    flashLeds(LEDS_BOOTLOADER_END);
#endif

    // execute the program
  exec:
    ((ApplicationStartExec)bootParams.intFlashAddress)();
}