- 2024-03-24
-
发表了主题帖:
【极海APM32F407 Tiny Board】 5.基于LWIP的IAP升级
# 1 LWIP
## 1.1 LWIP简介
LwIP 是一款轻量化的 TCP/IP 协议,是瑞典计算机科学院(SICS)的 AdamDunkels 开发的一个小型开源的 TCP/IP 协议栈。在保持 TCP 协议主要功能的基础上减少对资源的占用。此外 LwIP 既可以移植到操作系统上运行,也可以在无操作系统的情况下独立运行。 可以在网页http://savannah.nongnu.org/projects/lwip/, 下载获取到 LwIP 的各个版本的源代码包和对应的contrib 包。
本次计划基于上一篇LWIP移植的基础上实现LWIP网络传输固件进行升级。
## 1.2 硬件设计
开发板使用 APM32F407 控制器通过 RMII 接口和 SMI 接口与 LAN8720A 以太网 PHY 进行连接。通过接下拉电阻把 nINTSEL 引脚设置为低电平,从而使能 nINT/REFCLKO 引脚的输出功能为RMII 接口中 REF_CLK 信号线提供时钟信号, 硬件上 XTAL1 与 XTAL2 之间接入提供 25MHz时钟,经过 LAN8720A 内部 PLL 电路陪频后使得 nINT/REFCLKO 引脚的输出的时钟信号为50MHz 时钟。
# 2 移植步骤
## 2.1 Bootloader配置
本次由于在bootloader程序中添加了lwip的代码,需要将bootloader的大小调整一下,初步编译了一下,大概占用30k左右的样子,这里进行试验就调整大一点,200k
应用程序配置,只需要调整APP的起始地址即可。
同时应用APP程序中只需要一个简单的例子即可,2s闪烁一次LED
接下来在bootloader建立TcpServer服务器,端口设置为80,代码基于lwip移植和串口IAP升级的工程合并而成。
Lwip接收数据回调函数,连接收向服务器发送消息证明建立通讯
接下来就是接收数据后的回调函数,先将接收的数据返回发送到服务器
实现Tcpserver这个功能后在实现代码升级的部分,然后初始化函数放在主函数中初始化。
打开网络测试工具,先ping一下,ping正常
接下来点击打开TCP,可以发现lwip Tcpserver connect 这串字符上传,这是代码里面写的,说明成功,接下来向服务器发送数据11,返回11。说明功能已正常使用
## 2.2 网络固件传输调整
由于最开始使用的串口升级的的方式,现在需要使用lwip实现,从串口IAP升级中将串口接收的数据固定存放在一个区域就可以,lwip升级同样也是。通过对lwip接收到的数据存放在我们的app段地址,通过按键去启动。
可以同样使用串口的缓冲,将lwip接收的数据存放在串口升级的缓冲区,首先找到lwip接收数据的接口tatic err_t tcp1_server_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *tcp_recv_pbuf, err_t err)。其lwip接收到的数据存放在tcp_recv_pbuf这个结构体中。
将接收到数据指针指向我们的串口接收缓冲区,同时拿出接收的长度
串口缓冲区数据存放地址
在主循环中通过检测按键进行代码升级和运行APP。检测到lwip接收的数据不为0,将接收的数据写入到指定区域。
# 3 验证
打开网络工具,本次使用野火的上位机,可以发文件,点击网络助手,配置协议类型为TCP Client,以及开发板的地址,端口,点击建立连接
接下来点击右下角的加载文件,选择APP代码生成的bin文件,如下所示
点击发送数据,接下来就可以通过串口看到输出消息,按下按键,执行用户程序。
正确执行升级后的代码,LED灯按APP的代码执行。
- 2024-03-17
-
发表了主题帖:
【极海APM32F407 Tiny Board】 4.LWIP移植
# 1 LWIP
## 1.1 LWIP简介
LwIP 是一款轻量化的 TCP/IP 协议,是瑞典计算机科学院(SICS)的 AdamDunkels 开发的一个小型开源的 TCP/IP 协议栈。在保持 TCP 协议主要功能的基础上减少对资源的占用。此外 LwIP 既可以移植到操作系统上运行,也可以在无操作系统的情况下独立运行。 可以在网页http://savannah.nongnu.org/projects/lwip/, 下载获取到 LwIP 的各个版本的源代码包和对应的contrib 包。
本次的移植目的是为了实现LWIP进行代码升级,因此本篇文章先实现底层功能,方便后续操作。
## 1.2 硬件设计
开发板使用 APM32F407 控制器通过 RMII 接口和 SMI 接口与 LAN8720A 以太网 PHY 进行连接。通过接下拉电阻把 nINTSEL 引脚设置为低电平,从而使能 nINT/REFCLKO 引脚的输出功能为RMII 接口中 REF_CLK 信号线提供时钟信号, 硬件上 XTAL1 与 XTAL2 之间接入提供 25MHz时钟,经过 LAN8720A 内部 PLL 电路陪频后使得 nINT/REFCLKO 引脚的输出的时钟信号为50MHz 时钟。
# 2 移植步骤
## 2.1 底层驱动添加
这是官方提供的ETH驱动库,标准库中没有添加
添加完如下所示:
添加LAN8720外设驱动,完成以太网的GPIO,时钟等配置,也相当于一个外设驱动文件。
## 2.2 添加Lwip源码
找到lwip-1.4.1\src\api文件,全部添加
lwip-1.4.1\src\core\ipv4下文件全部添加:
lwip-1.4.1\src\core下除了ipv6以及snmp文件夹,其他源码全部添加:
lwip-1.4.1\src\netif下添加,etharp.c文件:
添加头文件路径,当然中间步骤太多,因此部分省略
中间配置网卡等步骤省略,主要说明部分配置文件及实现逻辑,网络配置:
Lwip初始化,主要设置设置的IP地址,网关等
主程序,网络配置初始化,通过串口打印网络配置信息:
程序验证lwip是否移植成功,主要通过电脑进行ping
接下来配置电脑网络的相关配置:
# 3 验证
接下来打开电脑的CMD,ping一下开发板的ip,如下所示,lwip移植成功,文章是移植完后才写的,中间很多步骤省略。
- 2024-03-16
-
发表了主题帖:
【极海APM32F407 Tiny Board】 3.IAP升级
# 1 IAP
## 1.1 IAP简介
IAP(In Application Programming)即在应用编程。是用户自己的程序在运行过程中对User Flash的部分区域进行烧写。实现代码升级,可通过UART、SPI、IIC、USB等等传递需要升级的固件。实现即将flash或者其他存储器分成多个段,存储升级的代码,一般设计分为两个部分,第一部分用于实现通讯升级代码,叫bootloader,第二部分为应用程序,即正常运行的代码。
## 1.2 启动流程
程序启动后,先从 0x08000004 处取出复位中断向量地址,执行完复位中断函数后跳转到IAP 程序 main 函数中执行[①]。
当发生中断请求后,程序跳转到中断向量表中取出中断函数入口地址,再跳转到中断服务函数中执行[②],执行完中断函数后返回 main 函数中[③],然后执行 IAP 过程,成功后跳转到 APP程序[④]。
从偏移后的中断向量表得到相应中断函数地址,执行相应新的中断服务函数后,回到 APP的 main 函数中[⑤]。后面[⑥⑦⑧]的过程和前述一致。
## 1.3 中断向量表设置
APM32F4xxSDK 的 system_apm32f4xx.c 文件中可以找到 VECT_TAB_OFFSET 这个向量表偏移量宏定义来重新设置中断向量表的地址,也即是修改 SCB->VTOR 向量表偏移量寄存器。
# 2 移植步骤
## 2.1 Bootlaoder设计
Flash IAP BootLoader的起始地址为0x08000000,通过串口1接收升级固件,使用64k的空间用于存储bootloader,因此应用程序的地址为0x0801000。
首先是bootloader程序,配置按键,led,串口等相关外设
设置工程文件的ROM的起始地址为0x8000000,大小为64k
代码中初始化串口1用来进行应用程序的接收,同时打印状态信息。
## 2.2 App程序设计
APP 是主用户程序,在完成 IAP 程序的设计后,就要把 APP 的更新文件生成,然后通过一定的协议传输给 IAP 程序来进行 APP 固件的更新。 一般来说 APP 更新文件的文件类型为.bin 文件,该文件可以直接拷贝到 flash 中运行。
设置工程文件的起始地址为0X8010000
在 Keil MDK Option 配置的 User 选项卡中配置以下命令, 即可使用 fromelf.exe 生成 bin 文件,默认生成在工程目录。
准备好APP应用程序,这里使用之前的工程文件,把其他外设都关了,就留一个LED灯进行验证,2s闪烁进行区分。
# 3 验证
接下来打开终端,使用串口工具选择APP程序的bin文件
加载然后进行发送:
应用程序开始执行,LED灯2s的周期开始闪烁。