STM32F051 IAP源码分享
如果不懂IAP的请自动脑补或者怒戳这里
http://www.openedv.com/posts/list/11494.htm
然后STM32F051的IAP有一点区别也请自动脑补 ^_^
其实我只是来分享源码的:
事情是介个样子滴:
IAP需要有两个工程,第一个是Bootloader,第二个是Application
同时将这两份程序放在mcu的flash里的不同位置,启动时自动进入bootloader(可选择)进行iap,成功后跳转至application。
完整源码见最后内容,这里先瞎扯一点点:
那么IAP问题简化成三个步骤,
Step1:做Bootloader工程
Step2:做Application工程
Step3:烧进Flash的不同位置
Step1:需要做这些事情:
1:初始化IAP相关外设
2:下载文件(ymodem协议)
3: 写入Application程序存储空间
鸡:
IAP_Init();
SerialDownload();
具体实现:
/**
*@brief Initialize the Iap module(leddelay usart and unlock flash)
*@param None
*@retval None
*/
void IAP_Init(void)
{
uint32_tt;
LEDInit(); /*--Set up Led to Output signal --*/
SysTickInit(); /*-- Config System Tick for delay functions --*/
USART_Configuration(); /*-- Config usart to download .bin --*/
FLASH_If_Init(); /*-- Unlock Flash --*/
for(t = 2000; t > 10; t >>= 1 ) /*-- LED1 blink 3 second indeicate IAPbegin--*/
{
LEDTogle(1); delayms(t);
}
}
void SerialDownload(void)
{
uint8_t Number[10] = {0};
int32_t Size = 0;
SerialPutString("Waitingfor the file to be sent ... (press 'a' to abort)\n\r");
Size = Ymodem_Receive(&tab_1024[0]);
if(Size > 0)
{
SerialPutString("\n\n\r Programming CompletedSuccessfully!\n\r--------------------------------\r\n Name: ");
SerialPutString(FileName);
Int2Str(Number, Size);
SerialPutString("\n\r Size: ");
SerialPutString(Number);
SerialPutString(" Bytes\r\n");
SerialPutString("-------------------\n");
}
else if (Size == -1)
{
SerialPutString("\n\n\rThe image size is higher than the allowedspace memory!\n\r");
}
else if (Size == -2)
{
SerialPutString("\n\n\rVerification failed!\n\r");
}
else if (Size == -3)
{
SerialPutString("\r\n\nAborted by user.\n\r");
}
else
{
SerialPutString("\n\rFailedto receive the file!\n\r");
}
}
Step2:需要这样干:
在Application工程中程序运行的一开始加上如下中断拷贝即可
void InterruptRemap(void)
{
u8 i;
u32 Data;
u32 Address;
for(i=1;i<48;i++)
{
Data = *(__IOu32*)(0x08003000+i*4);
Address = 0x20000000 + (i*4);
*(__IO u32*)Address= (u32)Data;
}
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
}
Step3:这就样
将两个工程分别烧在不同的flash地址段中
A:bootloader
1:点Project选项卡,然后点Optionsfor Target选项如图:
2:Target选项卡下有on-chip地址设置,bootloader放在0x8000000开头的0x3000空间内
如图:
然后正常手段烧入flash即可。
B:application
和上述设置手段一样,只不过in-chip的IROM1设置起始地址为0x8003000,Size为mcu的Flash大小减去0x3000即可(注意是16进制哦)
然后就祝你幸福了 0.0
完整源码:
Main.c
/* Includes------------------------------------------------------------------*/
#include "stm32f0xx.h"
#include "flash.h"
#include "powerAPI.h"
#include "IAP_Bootloader.h"
/**
*@brief Main program.
*@param None
*@retval None
*/
int main(void)
{
SystemPowerUp(); /*-- PowerUp && LoadSysMsg --*/
while (1)
{
if(FLASH_If_ReadWord((uint32_t)IAP_READY_FLAG_ADDRESS) == FLAG_READY)
{
IAP_Init();
SerialDownload();
IAP_End_Clear_Flag();
}
else
{
JumpToApp();
}
}
return 0;
}
/**
******************************************************************************
*@file bootloader.c
*@brief IAP module function
*@CPU STM32F051
*@compiler Keil uVision V4.74
*@author MetalSeed
*@version V1.0.0
*@date 18-Sept-2014
*@modifydate20-Sept-2014
******************************************************************************
*@attention
*/
#include "stm32f0xx.h"
#include "IAP_Bootloader.h"
#include "uart.h"
#include "led.h"
#include "delay.h"
#include "flash.h"
#include "ymodem.h"
/*================================================================
APPLICATION_ADDRESS = (uint32_t)0x08003000
defined in flash
================================================================*/
extern uint32_t IapReady;
uint8_t tab_1024[1024] ={ 0 };
uint8_t FileName[FILE_NAME_LENGTH];
/*================================================================
About Jump
======================================