失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > STM32F407开发板的HTTP模式IAP远程升级之官方例程移植

STM32F407开发板的HTTP模式IAP远程升级之官方例程移植

时间:2021-05-11 12:42:44

相关推荐

STM32F407开发板的HTTP模式IAP远程升级之官方例程移植

版权声明:本文为博主原创文章,转载请注明出处:/wbdxz/article/details/82859237

关于远程升级的模板建立,可以参考下面的博文

STM32F407开发板的HTTP模式IAP远程升级之新建模板STM32F407开发板的HTTP模式IAP远程升级之官方例程移植

接上文为止,已经建立好了一个可以ping通的以太网工程模板,接下来进行官方例程LWIP_IAP中的iap_http模式的移植

官方例程位置

D:\STM32Cube\Repository\STM32Cube_FW_F4_V1.21.0\Projects\STM324xG_EVAL\Applications\LwIP\LwIP_IAP

一.移植步骤

1.将官方例程中的Src文件夹下的flash_if.c,fsdata.c,httpserver.c复制到我们自己建立的工程文件夹的Src文件夹下

将flash_if.c和httpserver.c添加到keil工程中的Gourps中

2.将官方例程中的Inc文件夹下的flash_if.h,fsdata.h,httpserver.h复制到我们自己建立的工程文件夹的Inc文件夹下

3.在app.c中添加如下代码

4.此时编译,出现了以下错误

*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'd:\Keil_v5\ARM\ARMCC\Bin'Build target 'teach_http_iap'compiling flash_if.c.....\Src\flash_if.c(57): error: #20: identifier "USER_FLASH_LAST_PAGE_ADDRESS" is undefinedif (FlashAddress <= (uint32_t) USER_FLASH_LAST_PAGE_ADDRESS)..\Src\flash_if.c(91): error: #20: identifier "USER_FLASH_END_ADDRESS" is undefinedfor (i = 0; (i < DataLength) && (*FlashAddress <= (USER_FLASH_END_ADDRESS-4)); i++)..\Src\flash_if.c: 0 warnings, 2 errorscompiling httpserver.c.....\Src\httpserver.c(40): error: #5: cannot open source input file "lcd_log.h": No such file or directory#include "lcd_log.h"..\Src\httpserver.c: 0 warnings, 1 errorcompiling app.c.....\user\app\app.c(28): warning: #223-D: function "IAP_httpd_init" declared implicitlyIAP_httpd_init();..\user\app\app.c: 1 warning, 0 errors"teach_http_iap\teach_http_iap.axf" - 3 Error(s), 1 Warning(s).Target not created.Build Time Elapsed: 00:00:02

解决方法:

1.在flash_if.h中添加

//起始地址#define USER_FLASH_FIRST_PAGE_ADDRESS 0x08020000 /* Only as example see comment */#define USER_FLASH_LAST_PAGE_ADDRESS 0x080E0000//结束地址#define USER_FLASH_END_ADDRESS FLASH_END

2.注释掉httpserver.c中的如下代码

再次编译,出现错误

*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'd:\Keil_v5\ARM\ARMCC\Bin'Build target 'teach_http_iap'compiling httpserver.c...linking...teach_http_iap\teach_http_iap.axf: Error: L6218E: Undefined symbol IAP_httpd_init (referred from app.o).Not enough information to list image symbols.Not enough information to list load addresses in the image map.Finished: 2 information, 0 warning and 1 error messages."teach_http_iap\teach_http_iap.axf" - 1 Error(s), 0 Warning(s).Target not created.Build Time Elapsed: 00:00:02

解决方法:在main.h的76行添加如下代码

#define USE_IAP_HTTP /* enable IAP using HTTP */

再次编译,出现错误

*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'd:\Keil_v5\ARM\ARMCC\Bin'Build target 'teach_http_iap'compiling httpserver.c.....\Src\httpserver.c(210): error: #20: identifier "LOGIN_SIZE" is undefinedchar *data, *ptr, filename[40], login[LOGIN_SIZE];..\Src\httpserver.c(273): error: #20: identifier "USERID" is undefinedsprintf((char *)login,"username=%s&password=%s",USERID,PASSWORD);..\Src\httpserver.c(273): error: #20: identifier "PASSWORD" is undefinedsprintf((char *)login,"username=%s&password=%s",USERID,PASSWORD);..\Src\httpserver.c(210): warning: #550-D: variable "filename" was set but never usedchar *data, *ptr, filename[40], login[LOGIN_SIZE];..\Src\httpserver.c: 1 warning, 3 errors"teach_http_iap\teach_http_iap.axf" - 3 Error(s), 1 Warning(s).Target not created.Build Time Elapsed: 00:00:02

解决方法:

在main.h的第77行添加如下代码

#define USERID "user"#define PASSWORD"stm32"#define LOGIN_SIZE (15+ sizeof(USERID) + sizeof(PASSWORD))

在app.c的第19行添加

#include "httpserver.h"

再次编译运行,没有错误。将程序下载到开发板,断电重启(如果在下载时选择Reset and run,download to flash则不需要)

二.程序测试

打开IE浏览器(必须使用IE),输入192.168.1.120,出现下面的页面

输入用户名user,密码stm32,点击login

上传bin文件即可升级成功。

到上面为止,HTTP模式的IAP升级已经完成,但值得注意的是,我们每一次复位开发板或者开发板重新上电的时候,都自动进入了IAP模式,也就是说无法进入正常的app工作状态,这是不合乎常理的。我们希望设备在正常使用的时候直接运行app代码,当我们需要IAP升级的时候才进入升级模式。

该问题的解决方案:添加另外一个普通按键(以下称为升级按键BUTTON_WAKEUP),与PA0相连接

进入IAP模式:

保持BUTTON_WAKEUP按下不松开按下复位按键,等2秒即可进入

进入普通app运行模式:

只要复位或者重新上电时,BUTTON_WAKEUP不被按下即可

具体代码实现步骤如下:

将main.c中的以下代码

/* USER CODE BEGIN 2 */App_init();/* USER CODE END 2 */

改写成如下代码

/* USER CODE BEGIN 2 *//*设置BUTTON_WAKEUP按键KEY_UP,默认是低电平,按下为高电平*/if (HAL_GPIO_ReadPin(BUTTON_WAKEUP_GPIO_Port,BUTTON_WAKEUP_Pin) == 0x00){ /* Key push-button not pressed: jump to user application *//* 如果KEY_UP没有按下,则跳转至app *//* Check if valid stack address (RAM address) then jump to user application *//* 检查栈顶地址信息是否合法,合法则跳转至app */if (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000){/* Jump to user application */JumpAddress = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);Jump_To_Application = (pFunction) JumpAddress;/* Initialize user application's Stack Pointer */__set_MSP(*(__IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);Jump_To_Application();/* do nothing */while(1);}//如果flash栈信息中没有app代码,则打印反馈信息else{printf("FLASH中没有app程序! \r\n");while(1);}}else{App_init();/* USER CODE END 2 */

再将

/* USER CODE BEGIN WHILE */while (1){MX_LWIP_Process();App_process();/* USER CODE END WHILE */

改写成以下形式,多加了一个" } ",这是为了满足上个代码块中的else的书写形式

/* USER CODE BEGIN WHILE */while (1){MX_LWIP_Process();App_process();}/* USER CODE END WHILE */

编译代码,出现以下错误:

*** Using Compiler 'V5.06 update 6 (build 750)', folder: 'd:\Keil_v5\ARM\ARMCC\Bin'Build target 'teach_http_iap'compiling main.c...../Src/main.c(120): error: #20: identifier "USER_FLASH_FIRST_PAGE_ADDRESS" is undefinedif (((*(__IO uint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000)../Src/main.c(123): error: #20: identifier "JumpAddress" is undefinedJumpAddress = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);../Src/main.c(124): error: #20: identifier "Jump_To_Application" is undefinedJump_To_Application = (pFunction) JumpAddress;../Src/main.c(124): error: #20: identifier "pFunction" is undefinedJump_To_Application = (pFunction) JumpAddress;../Src/main.c(124): error: #65: expected a ";"Jump_To_Application = (pFunction) JumpAddress;../Src/main.c: 0 warnings, 5 errors"teach_http_iap\teach_http_iap.axf" - 5 Error(s), 0 Warning(s).Target not created.Build Time Elapsed: 00:00:08

解决方法:

在main.c的

/* USER CODE BEGIN Includes */#include "app.h"/* USER CODE END Includes */

加入一行新的头文件

/* USER CODE BEGIN Includes */#include "app.h"#include "flash_if.h"/* USER CODE END Includes */

在main.c的第65行,加入

//满足按键检测升级功能/app跳转的定义typedef void (*pFunction)(void);pFunction Jump_To_Application;uint32_t JumpAddress;

再次编译,没有错误提示。

下载到开发板运行,尝试进入IAP模式,正常运行模式。

在本Bootloader程序中,我为它在flash中偏移了0x20000的大小,即128KB的空间。这就需要我们在生成app程序的时候,将起始地址改成0x8020000,Size改成E0000。用计算器可以计算0x100000-0x20000 = 0xE0000。

在app程序的main函数中,需要添加一条中断向量表偏移20000的代码

SCB->VTOR = FLASH_BASE | 0x20000;//设置偏移量

至此,HTTP模式的IAP远程升级最终完成。

如果我的文字帮助到了你,欢迎打赏哈。

如果觉得《STM32F407开发板的HTTP模式IAP远程升级之官方例程移植》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。