OTA的bootloader编写

  1. 编写bootloader程序
/*
划分flash区域
*/
/* BootLoader macro and functions ------------------------------------------------------- */
//这次使用复旦微mcu其flash 128k
#define BootLoaderAddress	(0x0000)    //16K 编译后可以根据bin文件大小修改划分bootloader大小	
//根据不同MCU确认flash起始地址,像stm32是0x80000 
#define ApplicationAddress	(0x4000)    //54K   APP地址
#define Save_Updata_Address (ApplicationAddress + 1024*54)  //54K 存储升级APP地址
#define Ota_flag_Address            (Save_Updata_Address + 54*1024) //   存储Ota标志位地址
#define Ota_Bin_Size_Address            (Ota_flag_Address + 4)//存储bin文件大小地址
typedef void (*pFunction)( void );
#define PAGE_SIZE (0x200)                            /* 复旦微芯片512B 为一页 具体设置多少看数据手册修改 */
#define Read( address ) (*( (volatile unsigned long *) (address) ) )    //读取flash数据 address为地址
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
unsigned long OTA_flag = 0;	//ota标志位
unsigned long Bin_Size = 0;//bin文件大小
 * @brief  计算bin文件的页数
 * @param  Size: The image size
 * @retval 返回页数
 */
uint32_t FLASH_PagesMask( __IO uint32_t Size )
{
    uint32_t	pagenumber	= 0x0;
    uint32_t	size		= Size;

    if ( (size % PAGE_SIZE) != 0 )
    {
        pagenumber = (size / PAGE_SIZE) + 1;
    }
    else
    {
        pagenumber = size / PAGE_SIZE;
    }
    return (pagenumber);
}

//跳转程序,更新完跳转到APP区域
//这函数不需要改什么
void JumpToApplication( void )
{
    uint32_t	Stack_Addr;
    uint32_t	ResetVector;
    pFunction	Jump_To_Application;

    Stack_Addr	= *(__IO uint32_t *) ApplicationAddress;
    ResetVector = *(__IO uint32_t *) (ApplicationAddress + 4);
    /* Test if user code is programmed starting from address "ApplicationAddress" */
    if ( (Stack_Addr & 0x2FFC0000) == 0x20000000 )
    {
        /* Initialize user application's Stack Pointer */
        __set_MSP( Stack_Addr );
        /* Jump to user application */
        Jump_To_Application = (pFunction) ResetVector;
        Jump_To_Application();
    }
}


```c
/**
 ******************************************************************************
 * @file    Templates_LL/Src/main.c
 * @author  FMSH AS Embedded Software Team
 * @brief   Main program body through the LL API
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; COPYRIGHT(c) 2020 FMSH Microelectronics</center></h2>
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *   3. Neither the name of FMSH Microelectronics nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "main.h"	
#include "bsp.h"	//硬件
#include "flash.h"


/** @addtogroup FM15L0XX_LL_Examples
 * @{
 */


/** @addtogroup Templates_LL
 * @{
 */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* Constants used by Serial Command Line Mode */
#define CMD_STRING_SIZE 128		

/* BootLoader macro and functions ------------------------------------------------------- */
#define BootLoaderAddress	(0x0000)    //16K
#define ApplicationAddress	(0x4000)    //54K   APP地址
#define Save_Updata_Address (ApplicationAddress + 1024*54)  //54K 存储升级APP地址
#define Ota_flag_Address            (Save_Updata_Address + 54*1024) //   存储Ota标志位地址
#define Ota_Bin_Size_Address            (Ota_flag_Address + 4)//存储bin文件大小地址
typedef void (*pFunction)( void );

#define PAGE_SIZE (0x200)                            /* 512 byte */
#define Read( address ) (*( (volatile unsigned long *) (address) ) )    //读取flash数据 address为地址
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
unsigned long OTA_flag = 0;
unsigned long Bin_Size = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
uint32_t FlashDestination,RamSource;

/**
 * @brief  Initialize the IAP: Configure RCC, USART and GPIOs.
 * @param  None
 * @retval None
 */
void IAP_Init( void )
{
    uart_init( EVAL_COM0 );
}
void NVIC_init( void )
{
    NVIC_EnableIRQ( FLASH_IRQn );
}

/**
 * @brief  Main program
 * @param  None
 * @retval None
 */
/**
 * @brief  Calculate the number of pages
 * @param  Size: The image size
 * @retval The number of pages
 */
uint32_t FLASH_PagesMask( __IO uint32_t Size )
{
    uint32_t	pagenumber	= 0x0;
    uint32_t	size		= Size;

    if ( (size % PAGE_SIZE) != 0 )
    {
        pagenumber = (size / PAGE_SIZE) + 1;
    }
    else
    {
        pagenumber = size / PAGE_SIZE;
    }
    return (pagenumber);
}

int main( void )
{
    /* 功能说明:IAP boot功能
     * 硬件配置:无
     * 测试流程:无
     */
    uint32_t iap_size = 0;
	uint32_t erase_page = 0;
    /*UART Init and Key Button Init*/
    bsp_init();	//初始化串口和flash的GPIO
    NVIC_init();//初始化flash的中断源
    IAP_Init();//初始化串口
    OTA_flag = Read( Ota_flag_Address );    //读取OTA标志
    iap_size = Read( Ota_Bin_Size_Address);//读取bin大小
    if ( OTA_flag )//判断到OTA标志
    {
       
        /* Execute the IAP driver in order to re-program the Flash */
        Bin_Size = Read( Ota_Bin_Size_Address );//读取Bin的大小
        
        printf( "\r\n======================================================================" );
        printf( "\r\n=              COPYRIGHT(c) 2021 FMSH Microelectronics               =" );
        printf( "\r\n=                                                                    =" );
        printf( "\r\n=     In-Application Programming Application                         =" );
        printf( "\r\n=                                                                    =" );
        printf( "\r\n=                                   By AS Embedded Software Team     =" );
        printf( "\r\n======================================================================" );
        printf( "\r\n\r\n" );
        
        FlashDestination = ApplicationAddress;	//应用程序地址
		RamSource = Save_Updata_Address;		//存储升级程序地址
        erase_page = FLASH_PagesMask( iap_size );   //计算bin文件所占页的个数
         for (uint32_t EraseI = 0; EraseI < erase_page; EraseI++ )
        {//flash要先擦才能写, 把app区域全都擦掉
            flash_erase( LL_FLASH_ERTYPE_SECTOR, FlashDestination + (PAGE_SIZE * EraseI) );
        }
								
        for (uint32_t j = 0; (j < iap_size) && (FlashDestination < Save_Updata_Address + iap_size); j += 4 )
		{
			/* Program the data received into FM15L02x Flash */
			//将存储升级数据的区域 一一写到应用区
			flash_program( FlashDestination, *(uint32_t *) RamSource );

			if ( *(uint32_t *) FlashDestination != *(uint32_t *) RamSource )
			{
				printf("ota data write err\r\n");
				//return;
			}
			FlashDestination	+= 4;	//地址+4(四个字节) 因为复旦微mcu一次只能写入32位
			RamSource			+= 4;
		}
	//升级完毕 清除标志位
		OTA_flag = 0;
		flash_erase(LL_FLASH_ERTYPE_PAGE, Ota_flag_Address);
	    flash_program(Ota_flag_Address, OTA_flag);

		JumpToApplication();//跳转到应用区
    
    }
    else//没有更新跳转应用区
    {
        JumpToApplication();
    }

    /* Infinite loop */
    while ( 1 )
    {
    }
}


/**
 * @}
 */


/**
 * @}
 */

/************************ (C) COPYRIGHT FMSH Microelectronics *****END OF FILE****/


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值