1)實驗平臺:正點原子APM32F407最小系統板
2)平臺購買地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套實驗源碼+手冊+視頻下載地址: http://www.openedv.com/thread-340252-1-1.html##
第六十章 串口IAP實驗
本章將介紹在APM32F407上使用串口進行IAP,以實現簡單的IAP功能。通過本章的學習,讀者將學習到IAP的使用。
本章分為如下幾個小節:
60.1 硬件設計
60.2 程序設計
60.3 下載驗證
60.1 硬件設計
60.1.1 例程功能
- 程序運行后進入等待接收APP的bin數據的狀態
- 接收到APP的bin數據后,先后按下KEY0按鍵和KEY_UP按鍵,可分別進行將APP的bin數據加載到Flash和跳轉到APP的位置執行APP的操作
- LED0閃爍,指示程序正在運行
60.1.2 硬件資源 - LED
LED0 - PF9 - 按鍵
KEY0 - PE4
KEY_UP - PA0 - USART1(PA9、PA10連接至板載USB轉串口芯片上)
- 正點原子 2.8/3.5/4.3/7/10寸TFTLCD模塊(僅限MCU屏,16位8080并口驅動)
60.1.3 原理圖
本章實驗使用的IAP為軟件算法,因此沒有對應的連接原理圖。
60.2 程序設計
60.2.1 IAP的實現
本章實驗提供了用于IAP的驅動代碼,如下圖所示:
圖60.2.1.1 IAP驅動代碼
IAP的實現最主要分為兩個步驟,分別為加載APP固件至Flash和跳轉到APP中運行,為此本實驗實現了以上兩個函數,如下所示:
void iap_write_appbin(uint32_t appxaddr,uint8_t *appbuf,uint32_t applen);
void iap_load_app(uint32_t appxaddr);
以上兩個函數就分別實現了加載APP固件至Flash和跳轉到APP運行的功能,這兩個函數的使用示例,如下所示:
#include "apm32f4xx.h"
#include "./IAP/iap.h"#define FLASH_APP_ADDR (0x08010000)
#define APP_MAX_SIZE (120*1024)static uint8_t appbin[APP_MAX_SIZE];void example_fun(void)
{uint32_t appsize;/* 通過串口等方式獲取APP的二進制數據 */appsize = get_app_bin(appbin);/* 將APP的二進制數據寫入Flash的指定地址中 */iap_write_appbin(FLASH_APP_ADDR, appbin, appsize);/* 跳轉到APP在Flash中的起始地址運行 */iap_load_app(FLASH_APP_ADDR);
}
60.2.2 APP工程修改
APP程序要能夠在指定的Flash起始地址運行,需要編譯器在編譯APP的時候知道APP將被保存在Flash的那個位置,對于MDK軟件,可以在Options for Target窗口中設置,如下圖所示:
圖60.2.2.1 配置MDK中的Flash空間
上圖中將APP程序保存在Flash中的空間配置為0x8010000~(0x8010000+0xF0000),通過這樣的配置便可以使APP被保存在指定Flash位置中執行。讀者可以自行配置“Start”和“Size”參數,但要注意不能超過Flash的范圍,并且也不要覆蓋IAP程序(Bootloader)。
上一小節中將APP保存到Flash中的操作操作的是二進制數據,因此APP也應當被編譯為二進制文件,然后MDK軟件中并沒有直接編譯出二進制文件的選項,因此需要配置MDK在編譯完成后執行指定的命令,如下圖所示:
圖60.2.2.2 配置MDK生成二進制文件
完成以上配置后,便可在APP程序編譯完成后在工程的Output目錄下得到正確的二進制文件。
60.2.3 實驗應用代碼
本章實驗的應用代碼,如下所示:
int main(void)
{/* 僅保留關鍵代碼,其余代碼省略 *//* 初始化串口 */usart_init(115200);while (1){/* 串口已接收到數據 */if (g_usart_rx_cnt != 0){/* 新的一次循環串口還沒有接收到新數據,* 則斷定串口接收完畢*/if (lastcount == g_usart_rx_cnt){/* 記錄APP固件大小 */applenth = g_usart_rx_cnt;lastcount = 0;g_usart_rx_cnt = 0;}else{lastcount = g_usart_rx_cnt;}}key = key_scan(0);switch (key){case KEY0_PRES:{/* 將串口接收到的APP二進制數據寫入Flash中的指定位置 */iap_write_appbin(FLASH_APP1_ADDR, g_usart_rx_buf, applenth);break;}case WKUP_PRES:{/* 跳轉到Flash的指定位置執行APP程序 */iap_load_app(FLASH_APP1_ADDR);break;}}delay_ms(100);}
}
從上面的代碼中可以看出,程序是通過串口接收APP的二進制數據的,因此串口驅動中的串口接收緩存因該設置的足夠大,以能夠容納APP的二進制數據,本實驗中串口接收緩存的配置如下所示:
/* 定義最大接收120KB數據 */
#define USART_REC_LEN (120 * 1024)
在判斷APP二進制數據接收完畢后,便可通過KEY0按鍵調用函數iap_write_appbin()將APP的二進制數據寫入Flash中的FLASH_APP1_ADDR位置中,FLASH_APP1_ADDR是一個宏,該宏的定義如下所示:
#define FLASH_APP1_ADDR 0x08010000
需要注意的是,APP寫入的位置應當與上一小節中配置MDK軟件的指定Flash位置相同。
將APP的二進制數據寫入到Flash中后,此時運行的依舊是IAP(Bootloader)程序,此時可以按下KEY_UP按鍵來跳轉到Flash中APP的位置執行APP程序。
60.3 下載驗證
在完成編譯和燒錄操作后,可以看到LCD上顯示了本實驗的相關實驗信息,此時程序正在等待串口接收APP的二進制數據,此時便可通過串口調試助手將實現編譯生成的APP二進制文件發送給MCU,待發送完畢后按下KEY0按鍵,將APP的二進制數據寫入到Flash中,若寫入成功,LCD上將會有相應的提示,此時便可按下KEY_UP按鍵將程序跳轉到APP的保存位置中運行,若指定的Flash位置保存了正確的APP固件,那么便可看到MCU正在運行APP程序,而非IAP(Bootloader)程序。