OTA远程升级之bootloader无法跳转解决方法:

前言:

        最近项目开发需要用到OTA远程升级,网上也有很多OTA升级的文章,但感觉没有一个是有用的,其中一个简单的bootloader程序可能都会有很多的问题,本次文章会先讲解bootloader升级跳转遇到的问题和解决方法,后续会开源OTA升级的部分功能代码,供大家参考。

        OTA(Over-The-Air)升级是一种通过无线网络对设备进行固件或软件升级的方法。它允许远程更新设备上的固件或应用程序,无需直接连接到设备,一般用于后期远程对程序进行升级迭代。

        Bootloader 跳转是指设备启动时加载的程序,其作用是初始化设备的硬件并引导操作系统。Bootloader 负责启动设备并加载操作系统,还可以提供一些基本的调试和维护功能。


1.bootloader跳转流程:

        Bootloader(引导加载程序)是计算机或设备启动时首先运行的程序,其主要功能是启动系统并准备加载操作系统或其他必要的程序。Bootloader 位于系统上电后执行的第一个程序,负责引导加载操作系统内核或其他应用程序。每个设备都有自己的bootloader,而我们也可以根据实际项目需求编写自己的bootloader。

        

跳转流程:
    1.首先对程序flash进行分区,一般都会分成bootloader区,用来存放bootloader程序,
一般划分为16kb大小,(可根据自己实际需求划分,一般16kb已经足够)其次是APP1主程序区,
一般这是设备的主程序区(根据实际需求划分大小),还有个APP2程序区,一般会用于存放升级
的代码(一般和APP1一样大)。如果不知道如何给flash划分区域,接下来会进行详细说明。

    2.对程序flash分区完毕后,就是设置程序起始地址和程序偏移地址,然后进行对应外设初始化,
编写跳转代码,然后烧写设备里面验证即可。

    3.下面是OTA中bootloader跳转的流程,对于需要在bootloader里面进行条件判断,然后跳转的
程序可供参考。
    


2.bootloader跳转实现代码和步骤

        1.首先创建一个bootloader工程,其次创建APP1工程,可根据实际需求判断是否需要创建APP2。本次演示功能只实现从bootloader跳转到APP1,所以只创建两个keil工程即可。创建需要的两个keil工程后,接下来对flash进行分区,下面是分区步骤:

       bootloader

        1.设置bootloader分区

        在keil5工程界面选择画笔,然后点击c/c++选项,在里面设置bootloader程序占据的大小,这里我们设置为16kb,0x8000000是程序默认起始地址,不用修改,16kb=16x1024byte,转换成十六进制就是0x4000,从起始位置偏移0x4000就可以了,所以size填写0x4000。同理如果想给bootloader分区为其他大小根据需求设置即可。

        2.初始化对应外设

        这里我们就只进行普通的初始化即可,初始化hal库,系统时钟,gpio,usart1,usart2,后续可根据实际项目需求,进行对应的初始化。

        3.编写跳转函数

        在这里我们需要编写程序跳转函数,在编写跳转函数前,需要定义一个函数指针类型,一个用于跳转的函数指针,一个用于存储跳转地址的变量,(三个都定义在全局)代码如下:

typedef  void (*pFunction)(void);     /*创建了一个类型别名 pFunction,它是一个指向无返回值且不                                                                        
                                       带参数的函数指针类型*/
pFunction Jump_To_Application;        /*定义了一个名为 Jump_To_Application 的变量,它是一个函 
                                      数指针,可以指向满足 pFunction 类型签名的函数。*/
uint32_t JumpAddress;                //用来装需要跳转的地址

在编写函数前,必须先定义上面三个

void Jump2App(uint32_t appxaddr)     //跳转函数,用于跳转到用户应用程序,uint32_t appxaddr传参为需要跳转的程序地址。
{

//这一行首先检查用户代码是否已经被烧录到指定的地址(Application1Address)。
    if (((*(__IO uint32_t*)appxaddr) & 0x2FFE0000 ) == 0x20000000)  
    { 
        JumpAddress = *(__IO uint32_t*) (appxaddr + 4);
        Jump_To_Application = (pFunction) JumpAddress;
        __set_MSP(*(__IO uint32_t*) appxaddr);
        Jump_To_Application();   //跳转到用户应用程序的入口点
       
    }
}

4.bootloader跳转程序main函数

        如图,执行上面步骤后,调用跳转函数,跳转对应的程序地址即可。

APP1

        1.APP1程序分区

        在keil5工程界面选择画笔,然后点击c/c++选项,在里面设置APP1程序占据的大小,这里我们设置为256kb,因为bootloader已经在flash里面占用了16kb大小,bootloader结束位置为0x8004000,。所以0x8004000也是App1程序起始地址,256kb=256x1024byte,转换成十六进制就是0x40000,从APP1程序起始位置偏移0x40000就可以了,所以size填写0x40000。同理如果想给APP1分区为其他大小根据需求设置即可。

2.设置中断向量表

这里在APP1需要设置中断向量表进行偏移,不然程序无法执行跳转,该代码需要放在APP1main函数最开始的地方,或者可能会无法跳转。


 /*FLASH_BASE是hal库自带的宏为程序起始地址,默认为0x8000000
或上0x4000是因为我们bootloader的大小为0x4000,后续根据实际需
求填写需要或上的大小*/

SCB->VTOR=(FLASH_BASE | 0x4000); 

3.bootloader跳转会遇到的问题

按照以上步骤全部设置完毕后,先将bootloader程序烧写到设备上,然后再将APP1烧写到设备上,可以在APP1加一些printf提示,即可实现bootloader跳转的功能。如果说按照以上情况还是无法实现跳转,则可能是以下原因导致:

1.偏移地址可能偏移错误,需要检查APP1flash的起始地址和main函数里面的偏移地址;

APP1偏移代码:SCB->VTOR=(FLASH_BASE | 0x4000); 
目前STM32f103系列都可支持该宏定义进行偏移,如果编
译无法识别该宏定义,需要根据具体芯片型号进行修改宏
然后设置偏移地址

2.可能在跳转前产生了中断,此时需要关闭设置的全部中断和定时器等,关闭函数如下:可根据项目配置进行关闭

void clear_remove_devs(void)
{
	__HAL_RCC_TIM1_CLK_DISABLE();  //关闭定时器1时钟
	HAL_NVIC_DisableIRQ(TIM1_UP_TIM10_IRQn);  //关闭中断
	HAL_TIM_Base_DeInit(&htim1);   //关闭定时器1
	HAL_TIM_Base_DeInit(&htim2);   //关闭定时器2
	HAL_UART_DeInit(&huart1);     //关闭串口1
	HAL_UART_DeInit(&huart2);
	__HAL_RCC_GPIOD_CLK_DISABLE();  //关闭时钟
	__HAL_RCC_GPIOA_CLK_DISABLE();
}

3.可能芯片不支持该方式跳转,如果说按照以上方法进行设置,并且检查都无问题还是无法跳转,需要考虑芯片是否支持该方式跳转,可查看芯片手册或者百度查询。


最后祝各位大佬编译成功,如果对各位大佬有帮助,记得三连~~

  • 20
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: OTA(Over-The-Air)远程升级是指通过无线网络实现对硬件设备进行固件升级的一种技术。对于C语言开发的设备,OTA远程升级可以通过以下步骤实现: 1. 设计OTA升级协议:首先需要设计一套OTA升级协议,用于规定设备与服务器之间的通信规则。协议应包含设备发起升级请求、服务器验证设备身份、传输固件数据、更新设备固件等重要步骤。 2. 实现OTA升级功能:在设备端,需要编写代码实现OTA升级功能。首先设备需能够通过无线网络连接到服务器,并提供识别和验证设备身份的机制。然后设备需能够从服务器下载升级固件,并将固件写入设备存储空间。最后,设备需能够在固件下载完成后自动进行固件更新操作。 3. 配置OTA服务器:配置OTA服务器,用于接收设备的升级请求、验证设备身份、提供固件下载和管理功能。服务器也应提供固件更新的验证机制,以确保升级的安全性和完整性。 4. 测试和部署:在实际环境中,需要进行充分的测试和验证,确保OTA升级功能的稳定性和可靠性。一旦测试通过,就可以将OTA升级功能部署到设备中。 OTA远程升级可以极大地简化设备固件的更新和维护工作,减少设备厂商和用户的工作量。通过OTA远程升级,设备可以及时获得最新的固件功能和安全补丁,提高设备的性能和稳定性。同时,OTA远程升级也为设备厂商提供了更好的产品支持和服务机制,能够及时响应用户需求和反馈。 ### 回答2: OTA(Over-The-Air,即远程升级)是一种通过无线网络更新设备固件或软件的技术。在C语言中实现OTA远程升级需要以下步骤: 1. 建立网络连接:首先,使用C语言中的网络库(如socket库)建立设备与服务器之间的网络连接。可以使用TCP或UDP协议进行数据传输。 2. 下载升级文件:设备与服务器连接成功后,使用C语言中的文件操作函数(如fopen、fread等)从服务器下载升级文件。服务器会提供一个URL或者文件路径供设备下载。 3. 验证升级文件:下载完成后,使用C语言中的哈希算法(如MD5、SHA1等)对下载的文件进行验证,以确保文件完整和准确。 4. 备份当前固件:在升级之前,应该先备份当前设备的固件,以防升级失败时能够恢复到之前的状态。可以使用C语言中的文件操作函数将当前固件保存到另一个位置。 5. 执行升级:使用C语言中的文件操作函数将下载的升级文件写入设备的存储空间,覆盖掉原有的固件。在写入之前,应该校验文件完整性。写入完成后,设备会自动重启以加载新的固件。 6. 升级结果反馈:设备在重启后,可以使用C语言中的网络库向服务器发送升级结果,例如升级成功或失败服务器根据结果可以作出相应的处理,如记录设备的升级状态,或者提醒用户重新操作。 需要注意的是,OTA远程升级的实现方式和详细步骤可能因设备和协议的不同而有所差异。以上步骤仅作为一般性的示例,具体实现需要根据实际情况进行调整。 ### 回答3: OTA(Over-The-Air)远程升级是一种通过无线网络方式对设备进行升级的技术,通过OTA远程升级可实现对设备的固件、软件等进行更新和升级C语言是一种广泛应用于嵌入式系统开发的高级程序设计语言。下面是关于如何使用C语言实现OTA远程升级的思路: 首先,我们需要使用C语言编写底层的网络通信模块。此模块需要实现设备与远程服务器之间的连接和通信,包括建立TCP/IP连接、发送和接收数据等功能。可以使用套接字(socket)编程方式来实现网络通信模块。 其次,我们需要编写OTA升级模块,该模块负责接收远程服务器发送的升级文件,并将文件写入设备的存储器中。在C语言中,可以使用文件操作函数(如fopen、fwrite等)来实现将升级文件写入设备存储器的功能。 在设备端,我们可以编写一个主循环,循环中不断接收远程服务器发送的命令和数据,然后根据不同的命令进行相应的操作。例如,当收到远程服务器发送的升级命令时,我们调用OTA升级模块进行升级操作。 最后,为了确保OTA升级的安全性和可靠性,我们可以引入校验机制和回退机制。例如,在OTA升级模块中,可以对接收的升级文件进行校验,确保数据的完整性和正确性。并且在升级过程中,备份设备原有的固件或软件,以便在升级失败时能够回退到之前的版本。 综上所述,使用C语言实现OTA远程升级需要编写底层网络通信模块、OTA升级模块,以及引入校验机制和回退机制等。这些模块和机制的实现有助于实现设备的远程升级功能,提升设备的智能化和灵活性。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值