1、首先要知道103C8T6是 64K flash的
2、要知道每页是1K, 0x400表示1K, 0x1000表示4K, 0x4000表示16K,0x10000表示64K
3、下载官方AN4657-STM32Cube_IAP_using_UART程序,STM3210C_EVAL工程
4、修改flash_if.h文件
#define USER_FLASH_END_ADDRESS 0x08010000 //定义总flash为0x1000
/* Define the user application size */
#define USER_FLASH_SIZE ((uint32_t)0x0000C000) /* 用户程序为乘下的48K */
修改写程序的页,16–63K为用户程序,需要写保护
#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES16TO19| OB_WRP_PAGES20TO23 | OB_WRP_PAGES24TO27 | OB_WRP_PAGES28TO31 |
OB_WRP_PAGES32TO35 | OB_WRP_PAGES36TO39 | OB_WRP_PAGES40TO43 | OB_WRP_PAGES44TO47 |
OB_WRP_PAGES48TO51 | OB_WRP_PAGES52TO55 | OB_WRP_PAGES56TO59 | OB_WRP_PAGES60TO63 )
5、用STM32CubeMX生成一个带1个按键,和串口的 基本程序,把串口变量huart1改为UartHandle,方便其它地方不用修改。并在main.h中声明为外部变量。
6、加入.s文件,编译OK
7、复制官网下载的这4个文件和对应的.h文件到自己的工程中
8、在main.c中加入#include “menu.h”,把程序改成如下
int main(void)
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
// printf("systems is start.....");
if(HAL_GPIO_ReadPin(KEY4_GPIO_Port,KEY4_Pin)==GPIO_PIN_RESET)
{
FLASH_If_Init();
Main_Menu ();
}
else
{
//printf("start to running APP");
/* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
JumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
JumpToApplication();
}
}
while (1);
}
9、把4个.c文件加入工程,并在main.c开头声明以下外部变量
extern pFunction JumpToApplication;
extern uint32_t JumpAddress;
10、删除以下头文件
//#include “stm3210c_eval.h”
11、在使用到串口的.c文件中都加入extern UART_HandleTypeDef UartHandle;
12、编译OK,下载,电脑上打开SecureCRT 8.1,按住按键,可以出来菜单了
13、按 键盘 1 ,
选择send ymodem 发送APP的bin文件
第二步:
写APP程序
1、改变flash地址,这个要根据上面IAP设定的来改
2、生成bin文件
C:Keil_v5ARMARMCCbinfromelf.exe --bin --output "E:projAPP_LED_testMDK-ARMAPP_LED_testAPP_LED.bin" "E:projAPP_LED_testMDK-ARMAPP_LED_testAPP_LED_test.axf"
或者更简单
C:Keil_v5ARMARMCCbinfromelf.exe --bin --output "$L@L.bin" "#L"
3、APP的程序里要重新定位向量表。查了网上都是调用NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000);
这个函数,但调用这个函数又要#include “misc.h",include “misc.h"这个后又会出现找不到stm32f10x.h
找了好久,用HAL库的,直接调用下面的操作寄存器
int main(void)
{
HAL_Init();
SCB->VTOR=FLASH_BASE|0x4000;
........
其它:
1、IAP里有一个判断语句
if ((((__IO uint32_t)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)//
应用地址被定义为0x08004000, (__IO uint32_t)APPLICATION_ADDRESS)即取0x08004000-0x08004003这四个字节中存的值,如果下载了应用程序,这个值应该是0x2000 0000. 或 0x2000 0001 或0x2000 0002…或0x2001 FFFF中的一个。因为应用程序下载到0x08004000开始的地址里,第一个字是堆栈指针,应该是指向内存中的一个地址。如果不是这些地址,说明没有下载应用程序。
严格地说103C8T6只有20K SRAM,所以
if ((((__IO uint32_t)APPLICATION_ADDRESS) & 0x2FFFA000 ) == 0x20000000) 更严格。
jumpAddress = (__IO uint32_t) (ApplicationAddress + 4);
应用程序的第二个字,存放的是复位指针,即复位后,程序会从ApplicationAddress + 4中取出地址执行。现在把这个地址取出来,放入变量jumpAddress 。把它变成函数指针后赋给JumpToApplication。
JumpToApplication();即是跳转到JumpToApplication地址执行。即应用程序复位执行的地方。
1、首先要知道103C8T6是 64K flash的
2、要知道每页是1K, 0x400表示1K, 0x1000表示4K, 0x4000表示16K,0x10000表示64K
3、下载官方AN4657-STM32Cube_IAP_using_UART程序,STM3210C_EVAL工程
4、修改flash_if.h文件
#define USER_FLASH_END_ADDRESS 0x08010000 //定义总flash为0x1000
/* Define the user application size */
#define USER_FLASH_SIZE ((uint32_t)0x0000C000) /* 用户程序为乘下的48K */
修改写程序的页,16–63K为用户程序,需要写保护
#define FLASH_PAGE_TO_BE_PROTECTED (OB_WRP_PAGES16TO19| OB_WRP_PAGES20TO23 | OB_WRP_PAGES24TO27 | OB_WRP_PAGES28TO31 |
OB_WRP_PAGES32TO35 | OB_WRP_PAGES36TO39 | OB_WRP_PAGES40TO43 | OB_WRP_PAGES44TO47 |
OB_WRP_PAGES48TO51 | OB_WRP_PAGES52TO55 | OB_WRP_PAGES56TO59 | OB_WRP_PAGES60TO63 )
5、用STM32CubeMX生成一个带1个按键,和串口的 基本程序,把串口变量huart1改为UartHandle,方便其它地方不用修改。并在main.h中声明为外部变量。
6、加入.s文件,编译OK
7、复制官网下载的这4个文件和对应的.h文件到自己的工程中
8、在main.c中加入#include “menu.h”,把程序改成如下
int main(void)
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
// printf("systems is start.....");
if(HAL_GPIO_ReadPin(KEY4_GPIO_Port,KEY4_Pin)==GPIO_PIN_RESET)
{
FLASH_If_Init();
Main_Menu ();
}
else
{
//printf("start to running APP");
/* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
JumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
JumpToApplication();
}
}
while (1);
}
9、把4个.c文件加入工程,并在main.c开头声明以下外部变量
extern pFunction JumpToApplication;
extern uint32_t JumpAddress;
10、删除以下头文件
//#include “stm3210c_eval.h”
11、在使用到串口的.c文件中都加入extern UART_HandleTypeDef UartHandle;
12、编译OK,下载,电脑上打开SecureCRT 8.1,按住按键,可以出来菜单了
13、按 键盘 1 ,
选择send ymodem 发送APP的bin文件
第二步:
写APP程序
1、改变flash地址,这个要根据上面IAP设定的来改
2、生成bin文件
C:Keil_v5ARMARMCCbinfromelf.exe --bin --output "E:projAPP_LED_testMDK-ARMAPP_LED_testAPP_LED.bin" "E:projAPP_LED_testMDK-ARMAPP_LED_testAPP_LED_test.axf"
或者更简单
C:Keil_v5ARMARMCCbinfromelf.exe --bin --output "$L@L.bin" "#L"
3、APP的程序里要重新定位向量表。查了网上都是调用NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000);
这个函数,但调用这个函数又要#include “misc.h",include “misc.h"这个后又会出现找不到stm32f10x.h
找了好久,用HAL库的,直接调用下面的操作寄存器
int main(void)
{
HAL_Init();
SCB->VTOR=FLASH_BASE|0x4000;
........
其它:
1、IAP里有一个判断语句
if ((((__IO uint32_t)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)//
应用地址被定义为0x08004000, (__IO uint32_t)APPLICATION_ADDRESS)即取0x08004000-0x08004003这四个字节中存的值,如果下载了应用程序,这个值应该是0x2000 0000. 或 0x2000 0001 或0x2000 0002…或0x2001 FFFF中的一个。因为应用程序下载到0x08004000开始的地址里,第一个字是堆栈指针,应该是指向内存中的一个地址。如果不是这些地址,说明没有下载应用程序。
严格地说103C8T6只有20K SRAM,所以
if ((((__IO uint32_t)APPLICATION_ADDRESS) & 0x2FFFA000 ) == 0x20000000) 更严格。
jumpAddress = (__IO uint32_t) (ApplicationAddress + 4);
应用程序的第二个字,存放的是复位指针,即复位后,程序会从ApplicationAddress + 4中取出地址执行。现在把这个地址取出来,放入变量jumpAddress 。把它变成函数指针后赋给JumpToApplication。
JumpToApplication();即是跳转到JumpToApplication地址执行。即应用程序复位执行的地方。
举报