USART_IAP

实现USART_IAP升级功能

IAP目的实现远程升级或者用其他方式升级

IAP_Bootloader程序逻辑

这次用STM32F407VET6

1.配置串口接受数据
2.擦写APP区域数据
3.写入完毕跳转APP运行区域

 

 HAL库随便配置配只,只要一个串口

keil勾选Use MicroLIB弱函数库

只需编写两个文件

BootLoader引入程序部分

BootLoader.h

/**
  ******************************************************************************

  *
  ******************************************************************************
  */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BOOTLOADER_H__
#define __BOOTLOADER_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */



/* USER CODE BEGIN Private defines */
#define UART_BUF_SIZE 16*1024
#define APPLICATION_ADDRESS   ((uint32_t)0x08008000)
/* USER CODE END Private defines */



/* USER CODE BEGIN Prototypes */
void test(void);
void jumpl_application(void);
/* USER CODE END Prototypes */

#ifdef __cplusplus
}
#endif

#endif /* __USART_H__ */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

BootLoader.c

#include "Bootloader.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "usart.h"
#include "Flash.h"
/* Configer */

/* Bootloader */

typedef void (*pFunction)(void);
pFunction JumpToApplication;
uint32_t JumpAddress;

uint8_t buf[UART_BUF_SIZE];


void jumpl_application(void){
	/* 接收处理 */
	printf("Bootloader wait\r\n");
  	memset(buf, 0, 200);
	HAL_UART_Receive(&huart1, buf, 4, 5000);  //等待5S指令

	if(buf[0]=='D'&&buf[1]=='O'&&buf[2]=='W'&&buf[3]=='N')
	{
		printf("Dowm readly\r\n");

		memset(buf, 0, UART_BUF_SIZE);
		HAL_UART_Receive(&huart1, buf, UART_BUF_SIZE, 15000);

		uint32_t len=strlen((const char *)buf);
		if(len==0) 
			printf("File timeout, please resend\r\n");
		else
		{
			printf("Data length:%d\r\n",len);
			printf("Please waitting latter\r\n");

			Flash_clear();
			STMFLASH_Write(APPLICATION_ADDRESS,buf,sizeof(buf)/sizeof(buf[0]));
		}
	}

    /* JUMP APPLICATION*/

    if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000){//判读堆栈
 
			printf("APP CREAT OK\r\n");
			HAL_UART_DeInit(&huart1);
    HAL_SuspendTick();
    /* execute the new program */
    JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
    /* Jump to user application */
    JumpToApplication = (pFunction) JumpAddress;
    /* Initialize user application's Stack Pointer */
    __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
    JumpToApplication();
	}
    else
    {
        printf("no down app \r\n");
           
    }
}

Flash.h

/**

  *
  ******************************************************************************
  */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __FLASH_H__
#define __FLASH_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */



/* USER CODE BEGIN Private defines */
/* Base address of the Flash sectors */ 
#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base address of Sector 0, 16 Kbytes   */
#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08004000) /* Base address of Sector 1, 16 Kbytes   */
#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08008000) /* Base address of Sector 2, 16 Kbytes   */
#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x0800C000) /* Base address of Sector 3, 16 Kbytes   */
#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08010000) /* Base address of Sector 4, 64 Kbytes   */
#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08020000) /* Base address of Sector 5, 128 Kbytes  */
#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08040000) /* Base address of Sector 6, 128 Kbytes  */
#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x08060000) /* Base address of Sector 7, 128 Kbytes  */
/* USER CODE END Private defines */



/* USER CODE BEGIN Prototypes */
#define STMFLASH_ReadWord(faddr) (*(uint32_t*)(faddr))
void Flash_clear(void);
void STMFLASH_Write(uint32_t WriteAddr,uint8_t *pBuffer,uint32_t len);
/* USER CODE END Prototypes */

#ifdef __cplusplus
}
#endif

#endif /* __USART_H__ */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Flash.c

#include "Flash.h"

/* Flash */

/* 要擦除内部FLASH的起始地址 */
#define FLASH_USER_START_ADDR   ADDR_FLASH_SECTOR_2   
/* 要擦除内部FLASH的结束地址 */
#define FLASH_USER_END_ADDR     ADDR_FLASH_SECTOR_7  



static uint32_t GetSector(uint32_t Address);

/* 块	名称	块基址	大小
    扇区 0	    0x0800 0000 - 0x0800 3FFF	16 KB
	扇区 1  	0x0800 4000 - 0x0800 7FFF	16 KB
	扇区 2  	0x0800 8000 - 0x0800 BFFF	16 KB
	扇区 3   	0x0800 C000 - 0x0800 FFFF	16 KB
	扇区 4	    0x0801 0000 - 0x0801 FFFF	64 KB
	扇区 5      0x0802 0000 - 0x0803 FFFF	128 KB
	扇区 6	    0x0804 0000 - 0x0805 FFFF	128 KB
		?	
	扇区 11	0x080E 0000 - 0x08OF FFFF	128 KB
系统存储器	     0x1 FFF 0000 - 0x1 FFF 77FF	30 KB
OTP区域	         0x1 FFF 7800-0X1FFF 7A0F	528 字 W
选项字节	     0x1 FFF C000 - 0x1 FFF C00F	16字节 */

void Flash_clear(void){
	FLASH_EraseInitTypeDef EraseInitStruct;
	uint32_t FirstSector = 0;
    uint32_t NbOfSectors = 0; 
	uint32_t SECTORError = 0;
	/* FLASH 解锁 ********************************/
	/* 使能访问FLASH控制寄存器 */
	HAL_FLASH_Unlock();

	FirstSector = GetSector(FLASH_USER_START_ADDR);
	NbOfSectors = GetSector(FLASH_USER_END_ADDR)- FirstSector + 1;
	
	/* 擦除用户区域 (用户区域指程序本身没有使用的空间,可以自定义)**/
	/* Fill EraseInit structure*/
	EraseInitStruct.TypeErase     = FLASH_TYPEERASE_SECTORS;
	EraseInitStruct.VoltageRange  = FLASH_VOLTAGE_RANGE_3;/* 以“字”的大小进行操作 */ 
	EraseInitStruct.Sector        = FirstSector;
	EraseInitStruct.NbSectors     = NbOfSectors;
	/* 开始擦除操作 */
	if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
	{
		/*擦除出错*/
		printf("Flash Erase Error\r\n");
	}
	else
		printf("Flash Erase OK\r\n");
		HAL_FLASH_Lock();
}


void STMFLASH_Write(uint32_t WriteAddr,uint8_t *pBuffer,uint32_t len){  	
		HAL_FLASH_Unlock();             //解锁	
		 uint32_t CountNum=0;
		 uint32_t flat=0;
		for(uint32_t i=0; i<len; i++)
		{

			if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, WriteAddr, pBuffer[i])==HAL_OK)
			{
				CountNum++;
//				printf("speed of progress start\r\n");
				if((CountNum>(len/4))&&(CountNum<(len/2))&&(flat==0))
				{
					flat++;
					printf("speed of progress 1/4\r\n");
				}
				if((CountNum>(len/2))&&(CountNum<(len/4*3))&&(flat==1))
				{
					flat++;
					printf("speed of progress 2/4\r\n");
				}
				if((CountNum>(len/4*3))&&(CountNum<=len)&&(flat==2))
				{
					flat++;
					printf("speed of progress 3/4\r\n");
				}
				if(CountNum>=len)
				{
					printf("speed of progress 4/4\r\n");
					printf("Down Ok\r\n");
				}
			}
            else
                printf("Flash write error\r\n");
			WriteAddr++;
		}
		HAL_FLASH_Lock();           		//上锁
//		printf("%d\r\n",STMFLASH_ReadWord(FLASH_USER_START_ADDR));
} 


/**
  * @brief  根据输入的地址给出它所在的sector
  *					例如:
						uwStartSector = GetSector(FLASH_USER_START_ADDR);
						uwEndSector = GetSector(FLASH_USER_END_ADDR);	
  * @param  Address:地址
  * @retval 地址所在的sector
  */
static uint32_t GetSector(uint32_t Address)
{
  uint32_t sector = 0;
  
  if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
  {
    sector = FLASH_SECTOR_0;  
  }
  else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
  {
    sector = FLASH_SECTOR_1;  
  }
  else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
  {
    sector = FLASH_SECTOR_2;  
  }
  else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
  {
    sector = FLASH_SECTOR_3;  
  }
  else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
  {
    sector = FLASH_SECTOR_4;  
  }
  else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
  {
    sector = FLASH_SECTOR_5;  
  }
  else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
  {
    sector = FLASH_SECTOR_6;  
  }
  else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_23))*/
  {
    sector = FLASH_SECTOR_7;  
  }
  return sector;
}

 重定向fputc

APP段

加上这两句

 

 fromelf --bin !L --output printf.bin

 完结撒花!!!!!

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
这段代码定义了一些函数和变量,并提供了两个函数 `data_reserve` 和 `data_remeber`。下面是对每个部分的解释: 1. `void Delay(__IO uint32_t nCount)`: 这是一个延时函数,用于在程序中产生一定的延时。`nCount` 是一个无符号32位整数,表示延时的计数值。 2. `void LED_Configuration(void)`: 这是一个LED配置函数,用于初始化LED相关的GPIO引脚设置。 3. `static void IAP_Init(void)`: 这是一个IAP(In-Application Programming)初始化函数,用于初始化应用程序中的编程功能。 4. `void KEY_Configuration(void)`: 这是一个按键配置函数,用于初始化按键相关的GPIO引脚设置。 5. `void GPIO_Configuration(void)`: 这是一个GPIO引脚配置函数,用于初始化其他一些与GPIO引脚相关的设置。 6. `void USART_Configuration(void)`: 这是一个USART(通用同步/异步收发器)配置函数,用于初始化USART外设的相关设置。 7. `void NVIC_Configuration(void)`: 这是一个NVIC(Nested Vector Interrupt Controller)配置函数,用于配置中断优先级和使能中断。 8. `void USART1_Init(u32 Baudrate)`: 这是一个USART1初始化函数,用于初始化USART1外设的通信速率(波特率)。 9. `void TIM2_Int_Init(u16 arr, u16 psc)`: 这是一个TIM2定时器初始化函数,用于配置TIM2定时器的自动重装载值和预分频值。 10. `void IWDG_Init(u8 prer, u16 rlr)`: 这是一个独立看门狗(IWDG)初始化函数,***

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苗大壮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值