📄 bl_main.c
字号:
//
// Check for a valid starting address and image size.
//
if((
#ifdef ENABLE_BL_UPDATE
(g_ulTransferAddress != 0) &&
#endif
#ifdef FLASH_RSVD_SPACE
(g_ulTransferAddress !=
(ulFlashSize - FLASH_RSVD_SPACE)) &&
#endif
(g_ulTransferAddress != APP_START_ADDRESS)) ||
((g_ulTransferAddress + g_ulTransferSize) >
ulFlashSize) ||
((g_ulTransferAddress & 3) != 0))
{
//
// Set the code to an error to indicate that the last
// command failed. This informs the updater program
// that the download command failed.
//
g_ucStatus = COMMAND_RET_INVALID_ADR;
//
// This packet has been handled.
//
break;
}
//
// Only erase the space that we need if we are not
// protecting the code.
//
#ifndef FLASH_CODE_PROTECTION
ulFlashSize = g_ulTransferAddress + g_ulTransferSize;
#endif
//
// Clear the flash access interrupt.
//
HWREG(FLASH_FCMISC) = FLASH_FCMISC_AMISC;
//
// Leave the boot loader present until we start getting an
// image.
//
for(ulTemp = g_ulTransferAddress; ulTemp < ulFlashSize;
ulTemp += 0x400)
{
//
// Erase this block.
//
HWREG(FLASH_FMA) = ulTemp;
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;
//
// Wait until this block has been erased.
//
while(HWREG(FLASH_FMC) & FLASH_FMC_ERASE)
{
}
}
//
// Return an error if an access violation occurred.
//
if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ARIS)
{
g_ucStatus = COMMAND_RET_FLASH_FAIL;
}
}
while(0);
//
// See if the command was successful.
//
if(g_ucStatus != COMMAND_RET_SUCCESS)
{
//
// Setting g_ulTransferSize to zero makes COMMAND_SEND_DATA
// fail to accept any data.
//
g_ulTransferSize = 0;
}
//
// Acknowledge that this command was received correctly. This
// does not indicate success, just that the command was
// received.
//
AckPacket();
//
// Go back and wait for a new command.
//
break;
}
//
// This command indicates that control should be transferred to
// the specified address.
//
case COMMAND_RUN:
{
//
// Acknowledge that this command was received correctly. This
// does not indicate success, just that the command was
// received.
//
AckPacket();
//
// See if a full packet was received.
//
if(ulSize != 5)
{
//
// Indicate that an invalid command was received.
//
g_ucStatus = COMMAND_RET_INVALID_CMD;
//
// This packet has been handled.
//
break;
}
//
// Get the address to which control should be transferred.
//
g_ulTransferAddress = SwapWord(g_pulDataBuffer[1]);
//
// This determines the size of the flash available on the
// device in use.
//
ulFlashSize = (((HWREG(SYSCTL_DC0) &
SYSCTL_DC0_FLASHSZ_M) + 1) << 11);
//
// Test if the transfer address is valid for this device.
//
if(g_ulTransferAddress >= ulFlashSize)
{
//
// Indicate that an invalid address was specified.
//
g_ucStatus = COMMAND_RET_INVALID_ADR;
//
// This packet has been handled.
//
break;
}
//
// Make sure that the ACK packet has been sent.
//
FlushData();
//
// Reset and disable the peripherals used by the boot loader.
//
HWREG(SYSCTL_RCGC1) = 0;
HWREG(SYSCTL_RCGC2) = 0;
HWREG(SYSCTL_SRCR1) = (SYSCTL_SRCR1_I2C0 | SYSCTL_SRCR1_SSI0 |
SYSCTL_SRCR1_UART0);
HWREG(SYSCTL_SRCR2) = SYSCTL_SRCR2_GPIOA | SYSCTL_SRCR2_GPIOB;
HWREG(SYSCTL_SRCR1) = 0;
HWREG(SYSCTL_SRCR2) = 0;
//
// Branch to the specified address. This should never return.
// If it does, very bad things will likely happen since it is
// likely that the copy of the boot loader in SRAM will have
// been overwritten.
//
((void (*)(void))g_ulTransferAddress)();
//
// In case this ever does return and the boot loader is still
// intact, simply reset the device.
//
HWREG(NVIC_APINT) = (NVIC_APINT_VECTKEY |
NVIC_APINT_SYSRESETREQ);
//
// The microcontroller should have reset, so this should
// never be reached. Just in case, loop forever.
//
while(1)
{
}
}
//
// This command just returns the status of the last command that
// was sent.
//
case COMMAND_GET_STATUS:
{
//
// Acknowledge that this command was received correctly. This
// does not indicate success, just that the command was
// received.
//
AckPacket();
//
// Return the status to the updater.
//
SendPacket(&g_ucStatus, 1);
//
// Go back and wait for a new command.
//
break;
}
//
// This command is sent to transfer data to the device following
// a download command.
//
case COMMAND_SEND_DATA:
{
//
// Until determined otherwise, the command status is success.
//
g_ucStatus = COMMAND_RET_SUCCESS;
//
// If this is overwriting the boot loader then the application
// has already been erased so now erase the boot loader.
//
if(g_ulTransferAddress == 0)
{
//
// Clear the flash access interrupt.
//
HWREG(FLASH_FCMISC) = FLASH_FCMISC_AMISC;
//
// Erase the application before the boot loader.
//
for(ulTemp = 0; ulTemp < APP_START_ADDRESS;
ulTemp += 0x400)
{
//
// Erase this block.
//
HWREG(FLASH_FMA) = ulTemp;
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;
//
// Wait until this block has been erased.
//
while(HWREG(FLASH_FMC) & FLASH_FMC_ERASE)
{
}
}
//
// Return an error if an access violation occurred.
//
if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ARIS)
{
//
// Setting g_ulTransferSize to zero makes
// COMMAND_SEND_DATA fail to accept any more data.
//
g_ulTransferSize = 0;
//
// Indicate that the flash erase failed.
//
g_ucStatus = COMMAND_RET_FLASH_FAIL;
}
}
//
// Take one byte off for the command.
//
ulSize = ulSize - 1;
//
// Check if there are any more bytes to receive.
//
if(g_ulTransferSize >= ulSize)
{
//
// This function is a stub to show where to insert a
// function to decrypt the data as it is received.
//
#ifdef ENABLE_DECRYPTION
DecryptData(g_pucDataBuffer + 1, ulSize);
#endif
//
// Clear the flash access interrupt.
//
HWREG(FLASH_FCMISC) = FLASH_FCMISC_AMISC;
//
// Loop over the words to program.
//
for(ulTemp = 0; ulTemp < ((ulSize + 3) & ~3); ulTemp += 4)
{
//
// Program the next word.
//
HWREG(FLASH_FMA) = g_ulTransferAddress + ulTemp;
HWREG(FLASH_FMD) = g_pulDataBuffer[(ulTemp >> 2) + 1];
HWREG(FLASH_FMC) = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;
//
// Wait until the word has been programmed.
//
while(HWREG(FLASH_FMC) & FLASH_FMC_WRITE)
{
}
}
//
// Return an error if an access violation occurred.
//
if(HWREG(FLASH_FCRIS) & FLASH_FCRIS_ARIS)
{
//
// Indicate that the flash programming failed.
//
g_ucStatus = COMMAND_RET_FLASH_FAIL;
}
else
{
//
// Now update the address to program.
//
g_ulTransferSize -= ulSize;
g_ulTransferAddress += ulSize;
}
}
else
{
//
// This indicates that too much data is being sent to the
// device.
//
g_ucStatus = COMMAND_RET_INVALID_ADR;
}
//
// Acknowledge that this command was received correctly. This
// does not indicate success, just that the command was
// received.
//
AckPacket();
//
// Go back and wait for a new command.
//
break;
}
//
// This command is used to reset the device.
//
case COMMAND_RESET:
{
//
// Send out a one-byte ACK to ensure the byte goes back to the
// host before we reset everything.
//
AckPacket();
//
// Make sure that the ACK packet has been sent.
//
FlushData();
//
// Perform a software reset request. This will cause the
// microcontroller to reset; no further code will be executed.
//
HWREG(NVIC_APINT) = (NVIC_APINT_VECTKEY |
NVIC_APINT_SYSRESETREQ);
//
// The microcontroller should have reset, so this should never
// be reached. Just in case, loop forever.
//
while(1)
{
}
}
//
// Just acknowledge the command and set the error to indicate that
// a bad command was sent.
//
default:
{
//
// Acknowledge that this command was received correctly. This
// does not indicate success, just that the command was
// received.
//
AckPacket();
//
// Indicate that a bad comand was sent.
//
g_ucStatus = COMMAND_RET_UNKNOWN_CMD;
//
// Go back and wait for a new command.
//
break;
}
}
}
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -