STM32
直播中

张丽

7年用户 1461经验值
私信 关注
[问答]

怎样去实现STM32F103C8T6的串口进行IAP呢

怎样去实现STM32F103C8T6的串口进行IAP呢?有哪些操作步骤?

回帖(1)

王文娥

2021-12-6 14:32:39
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地址执行。即应用程序复位执行的地方。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分