⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bl_main.c

📁 ARM-CORTEX LM3S系列远程下载更新程序
💻 C
📖 第 1 页 / 共 2 页
字号:

                    //
                    // 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 + -