网上看到很多关于flash不耐用的文章,并推荐将程序直接加载到内存运行,但很多方法都是需要J-Link或者其他仿真器的支持,现在手上如果没有仿真器怎么办?我在网上查了很多资料,好像暂时还没有其他好的方法把直接加载到内存运行, 要是有的话希望大家分享一下,mcuisp软件有个有个RamIsp功能,也不知道是不是有这个作用?
闲话少说,我自己在战舰STM32综合实验程序中增加了一个类似于烧写器的功能,此功能的好处是无需每次下载程序都要刷flash,不过要说明这是针对战舰板的,其他板可能不适用,原理是参照运行器的功能,还有串口IAP功能,将运行器中从SD卡中读取文件改为从串口接收文件,首先将源程序分享一下:
使用方法:首次使用进入综合实验程序界面的应用中心,选择第二个烧写器功能并确定就会进入烧写器界面,配合软件就能将BIN文件加载到开发板并运行
注意:使用本功能有如下限制:一是代码量不能超出64K;二是程序起始地址必须尾0x20001000,并设置中断偏移量
核心代码BIN_Load_System()函数是对串口IAP实验作修改而得来的,如下:
void BIN_Load_System(void) //BIN_Load系统.
{
u8 t;
u8 key;
u16 oldcount=0; //之前串口接收到的数据长度
u16 applenth=0; //接收到的app代码长度
u8 start_add_buf[8];//存放app程序运行首地址
/*
Stm32_Clock_Init(9); //系统时钟设置
delay_init(72); //延时初始化
uart_init(72,115200); //串口初始化为115200
LCD_Init(); //初始化LCD
LED_Init(); //初始化与LED连接的硬件接口
KEY_Init(); //按键初始化
FSMC_SRAM_Init(); //初始化外部SRAM
BEEP_Init(); //初始化蜂鸣器端口
*/
binflag =0xff; //设置为二进制接收模式
USART_RX_STA=0; //串口接收到的总字节数为0
  OINT_COLOR=RED;//设置字体为红色
// x ,y ,长 ,宽,字体大小,字符串起始地址
LCD_ShowString(60,50,200,16,16,"BIN Load System");
LCD_ShowString(30,110,200,16,16,"2014/11/09");
LCD_ShowString(30,150,200,16,16,"KEY_LEFT:Exit"); //退出
LCD_ShowString(30,170,200,16,16,"KEY_RIGHT:Run SRAM APP"); //强制运行
//显示提示信息
  OINT_COLOR=BLUE;//设置字体为蓝色
while(1)//死循环,让下位机停留在BIN_Load系统.
{
/////////////串口中断法/////////////////////
if(USART_RX_STA)//接收到第一个数据,进入接收数据状态
{
while(oldcount!=USART_RX_STA)//每接收一个数据,USART_RX_CNT+1
{
oldcount=USART_RX_STA;
t++;
if(t==2)
{
//LED0=!LED0;//灯闪烁
t=0;
}
//if(oldcount==USART_RX_STA) delay_ms(250); //延时,等待接收数据,
//if(oldcount==USART_RX_STA) delay_ms(25); //延时,等待接收数据,
//if(oldcount==USART_RX_STA) delay_ms(25); //延时,等待接收数据,
if(oldcount==USART_RX_STA) delay_ms(10); //延时,等待接收
}
//延时之后,仍没有收到任何数据,认为本次数据接收完成,下面处理接收到的数据
applenth=USART_RX_STA;
oldcount=0;
USART_RX_STA=0;//重新开始接收
if(applenth<20)//数据长度太小,将视为命令处理
{
if((mem2base[USART_RX_BASE]=='R')&&(mem2base[USART_RX_BASE+1]=='u')&&(mem2base[USART_RX_BASE+2]=='n'))
{ //收到"Run SRAM app !" 校验成功,可以运行BIN程序
delay_ms(50); //等待上位机关闭串口才能将下位机复位
exeplay_write_appmask(0X5050); //写入标志字,标志有app需要运行
Sys_Soft_Reset(); //系统软复位
}
}
else //将视为APP数据处理
{
mymemcpy((u8*)EXEPLAY_SRC_BASE,(u8*)(EXEPLAY_SRC_BASE+USART_RX_BASE),applenth);//拷贝applenth字节
if(((*(vu32*)(0X68000000+4))&0xFF000000)==0x20000000) printf("Lenth:%dBytes\r\n",applenth);//发送给上位以校验数据
else if(((*(vu32*)(0X68000000+4))&0xFF000000)==0x68000000)
printf("Lenth:%dBytes\r\n",applenth);
else //文件非法
{
printf("Illegal SRAM APP!\r\n");
LCD_ShowString(30,210,200,16,16,"Illegal SRAM APP!");
sprintf((char*)start_add_buf,"%X",*(vu32*)(0X68000000+4)); //十六进制输出结果start_add_buf里面
LCD_ShowString(30,230,200,16,16,"Start_add: 0X"); //显示所加载程序的运行首地址
LCD_ShowString(140,230,200,16,16,start_add_buf); //显示所加载程序的运行首地址
LCD_ShowString(30,270,200,16,16,"KEY_LEFT: Try to Run APP!"); //强制运行SRAM APP
}
}
//delay_ms(50);
}
///////////没有收到数据的时候作如下处理///////////////////
delay_ms(10);
t++;
if(t==50)
{
if(!USART_RX_STA) printf("BIN \r\n");//通知上位机已经进入BIN System ,可以接收文件了
LED0=!LED0;
t=0;
}
key=KEY_Scan(0);
if(key==KEY_LEFT)//退出BIN Load 系统并运行
{
RCC->APB1ENR|=1<<28; //使能电源时钟
RCC->APB1ENR|=1<<27; //使能备份时钟
PWR->CR|=1<<8; //取消备份区写保护
BKP->DR3=0X0000; //取消标记,重启后不要进入BIN Load 系统
Sys_Soft_Reset(); //系统软复位
}
if((key==KEY_RIGHT))//强制运行之前加载的SRAM程序
{
if(applenth)
{
delay_ms(100); //等待上位机关闭串口才能将下位机复位
exeplay_write_appmask(0X5050); //写入标志字,标志有app需要运行
Sys_Soft_Reset(); //系统软复位
}
else LCD_ShowString(30,210,200,16,16,"No APP!");
}
}
}
对比原实验56 战舰STM32开发板综合实验文件作了如下修改:
修改\APP appplay.c文件,增加进入烧写器界面的代码
复制binload文件夹到\SYSTEM文件夹,并且在工程SYSTEM文件夹下面增加binload文件,然后在Target的C\C++中添加..\HARDWARE\SRAM路径
在test.c的头文件添加extern void BIN_Load_check(void);并在system_init函数里面应用此函数
|