这里用的芯片是STM32F103VC;偏移地址为64KB,这里的0x40000意思是256kb
这边也需要对应的配置哦!
IAP是根据正点原子的串口IAP修改来的,这里的起始地址是0x800000;(可以去正点原子官网去找相关的资料,这里就不多赘述了)
//设置Bootloader的大小,算出APP起始位置 FLASH_BASE = 0x8000000
#define BOOTLOADER_SIZE (64*1024) /*64K bootloader*/
#define FIRMWARE_START_ADDR (FLASH_BASE + BOOTLOADER_SIZE)
#define BOOTLOADER_START_ADDR FLASH_BASE
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "stmflash.h"
#include "iap.h"
iapfun jump2app;
u16 iapbuf[1024];
//appxaddr:应用程序的起始地址
//appbuf:应用程序CODE.
//appsize:应用程序大小(字节).
void iap_write_appbin(u32 appxaddr,u8 *appbuf,u32 appsize)
{
u16 t;
u16 i=0;
u16 temp;
u32 fwaddr=appxaddr;//当前写入的地址
u8 *dfu=appbuf;
for(t=0;t<appsize;t+=2)
{
temp=(u16)dfu[1]<<8;
temp+=(u16)dfu[0];
dfu+=2;//偏移2个字节
iapbuf[i++]=temp;
if(i==1024)
{
i=0;
STMFLASH_Write(fwaddr,iapbuf,1024);
fwaddr+=2048;//偏移2048 16=2*8.所以要乘以2.
}
}
if(i)STMFLASH_Write(fwaddr,iapbuf,i);//将最后的一些内容字节写进去.
}
//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_app(u32 appxaddr)
{
if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.
{
jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
jump2app(); //跳转到APP.
}
}
main:
#include <string.h>
#include "sys.h"
#include "led.h"
#include "iap.h"
#include "stmflash.h"
int main(void)
{
bool updateFlag = false; //是否需要升级 升级标志位
LCD_BL_ON();
while(1)
{
if(updateFlag)
{
//可以将升级的bin文件下载进app区 然后重启进行跳转
//........
iap_load_app(FIRMWARE_START_ADDR); //跳转到应用APP
}
else
{
LED_OFF();
iap_load_app(FIRMWARE_START_ADDR); //跳转到应用APP
}
}
}
APP:
这里需要修改misc.h 中 NVIC_VectTab_FLASH 的值为0x08010000
#define NVIC_VectTab_RAM ((uint32_t)0x20000000)
//只需要改这个即可
#define NVIC_VectTab_FLASH ((uint32_t)0x08000000 | 0x10000)
#define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == NVIC_VectTab_RAM) || \
((VECTTAB) == NVIC_VectTab_FLASH))
misc.c中调用这个;时钟初始化之后即可调用
void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
{
/* Check the parameters */
assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
assert_param(IS_NVIC_OFFSET(Offset));
SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
}
//此代码在初始化中
SysTickInit(); //时钟初始化
NVIC_SetVectorTable(FIRMWARE_START_ADDR,0);
//设置栈顶地址
//addr:栈顶地址
__asm void MSR_MSP(u32 addr)
{
MSR MSP, r0 //set Main Stack value
BX r14
}
typedef void (*iapfun)(void); //定义一个函数类型的参数.
iapfun jump2bootloader;
//跳转到应用程序段
//appxaddr:用户代码起始地址.
void iap_load_bootloader(u32 appxaddr)
{
int i;
if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.
{
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数嵌入式工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/f59f338ad701547a30cf4a23375fe297.png)
![img](https://img-blog.csdnimg.cn/img_convert/9fc401b11d17de352fd191ef1f1d494e.jpeg)
![img](https://img-blog.csdnimg.cn/img_convert/9ae64372b09db2ec16c257594135aadb.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**
![img](https://img-blog.csdnimg.cn/img_convert/37f07503f66f65290427a909ef7a2e96.png)
![img](https://img-blog.csdnimg.cn/img_convert/c2110c574b0b0619b86713bb2ecc6470.png)
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)**
<img src="https://img-community.csdnimg.cn/images/73bb5de17851459088c6af944156ee24.jpg" alt="img" style="zoom: 67%;" />
# 最后
**资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~**
**你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!**
tps://img-community.csdnimg.cn/images/73bb5de17851459088c6af944156ee24.jpg" alt="img" style="zoom: 67%;" />
# 最后
**资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~**
**你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!**
**[更多资料点击此处获qu!!](https://bbs.csdn.net/topics/618376385)**