コード例 #1
0
ファイル: bootloader.c プロジェクト: AndreMiras/EFM32-Library
/******************************************************************************
 * This function waits for commands over UART
 *****************************************************************************/
void commandLoop(void)
{
  uint8_t command = 0;
  
  sendWelcomeMessage();
  
  while(1) {
    
    /* Wait for command */
    command = BLUART_receive();
    
    switch(command)
    {
    case 'h':
      sendWelcomeMessage();
      break;
    case 'u':
      enterDownloadMode();
      break;
    case 'v':
      BLUART_sendString("Verifying firmware...");
      if ( verifyActiveFirmware() ) {
        BLUART_sendString("OK\r\n");
      } else {
        BLUART_sendString("INVALID\r\n");
      }
      break;
    case 'l':
      BLUART_sendString("Locking debug access...\r\n");
      enableDebugLock();
      break;
    case 'r':
      BLUART_sendString("Reset\r\n");
      NVIC_SystemReset();
      break;
    }
  }
}
コード例 #2
0
/**************************************************************************//**
 * @brief Starts a XMODEM download.
 *****************************************************************************/
RAMFUNC bool XMODEM_download(void)
{
    XMODEM_packet *pkt;
    uint32_t      i;
    uint32_t      byte;
    uint32_t      sequenceNumber = 1;
    uint32_t writeAddress, endAddress;

    uint8_t *decryptedBuffer;

    if ( USE_TEMP_STORAGE ) {
        writeAddress = TEMP_START_ADDRESS;
        endAddress = TEMP_END_ADDRESS;
    } else {
        writeAddress = FIRMWARE_START_ADDRESS;
        endAddress = FIRMWARE_END_ADDRESS;
    }

    /* Initialize AES for decryption */
    startDecryptCBC256();

    /* Send one start transmission packet. Wait for a response. If there is no
     * response, we resend the start transmission packet. */
    while (1)
    {
        BLUART_send(XMODEM_NCG);

        i = 10000000;

        /* Wait until we receive a packet */
        while ( !(UART->STATUS & USART_STATUS_RXDATAV) ) {

            /* Time out */
            if ( --i == 0 )
                break;
        }

        /* We have received a packet */
        if ( UART->STATUS & USART_STATUS_RXDATAV ) {
            break;
        }
    }

    /* Start receiving XMODEM packets */
    while (1)
    {

        /* Swap buffer for packet buffer */
        pkt = (XMODEM_packet *) rawPacket[sequenceNumber & 1];
        decryptedBuffer = rawBuffer[sequenceNumber & 1];

        /* Fetch the first byte of the packet explicitly, as it defines the
         * rest of the packet */
        pkt->header = BLUART_receive();


        /* Check for end of transfer */
        if (pkt->header == XMODEM_EOT)
        {
            /* Acknowledge End of transfer */
            BLUART_send(XMODEM_ACK);
            break;
        }

        /* If header is cancel message, then cancel the transfer */
        if (pkt->header == XMODEM_CAN)
        {
            return false;
        }

        /* If the header is not a start of header (SOH), then cancel *
         * the transfer. */
        if (pkt->header != XMODEM_SOH)
        {
            BLUART_send(XMODEM_CAN);
            return false;
        }

        /* If the received file is larger than the allocated memory
         * for the firmware, cancel the transfer. */
        if ( writeAddress > endAddress ) {
            BLUART_send(XMODEM_CAN);
            return false;
        }

        /* Fill the remaining bytes packet */
        /* Byte 0 is padding, byte 1 is header */
        for (byte = 2; byte < sizeof(XMODEM_packet); byte++)
        {
            *((uint8_t *)pkt + byte) = BLUART_receive();
        }

        /* Verify that the packet is valid */
        if (XMODEM_verifyPacketChecksum(pkt, sequenceNumber) != 0)
        {
            /* On a malformed packet, send a NAK and start over */
            BLUART_send(XMODEM_NAK);
            continue;
        }

        /* If we have reached a new page, first erase it */
        if ( writeAddress % FLASH_PAGE_SIZE == 0 ) {
            FLASH_erasePage(writeAddress);
        }

        /* Decrypt one XMODEM packet(32 words) */
        for ( i=0; i<XMODEM_DATA_SIZE/AES_BLOCKSIZE; i++ ) {

            /* Decrypt one AES block (4 words) */
            decryptBlockCBC256(&(pkt->data[i * AES_BLOCKSIZE]), &(decryptedBuffer[i * AES_BLOCKSIZE]));
        }

        /* Check if this is the header packet */
        if ( sequenceNumber == 1 ) {

            /* Get the header */
            FirmwareHeader *header = (FirmwareHeader *)decryptedBuffer;

            /* Set the state to not verified initially */
            header->verified = FW_NOT_VERIFIED;

            /* Write the header to flash */
            FLASH_write((uint32_t *)writeAddress, (uint32_t *)header, sizeof(FirmwareHeader) / 4);

            /* Start at the boot address for the next packet */
            writeAddress = writeAddress + FIRMWARE_HEADER_SIZE;
        } else {

            /* Write decrypted packet to flash */
            FLASH_write((uint32_t *)writeAddress, (uint32_t *)decryptedBuffer, XMODEM_DATA_SIZE / 4);
            writeAddress += XMODEM_DATA_SIZE;
        }

        sequenceNumber++;

        /* Send ACK */
        BLUART_send(XMODEM_ACK);
    }

    endDecryptCBC256();

    /* Wait for the last DMA transfer to finish. */
    while (DMA->CHENS & DMA_CHENS_CH0ENS) ;

    /* Return success */
    return true;
}