{
USART_RX_BUF[USART_RX_CNT]=res;
USART_RX_CNT++;
}
}
#ifdef OS_CRITICAL_METHOD
//如果OS_CRITICAL_METHOD定义了,说明使用ucosII了.
OSIntExit();
#endif
}
这里,我们指定USART_RX_BUF的地址是从0X20001000开始,该地址也就是SRAM APP程序的起始地址!然后在USART1_IRQHandler函数里面,将串口发送过来的数据,全部接收到USART_RX_BUF,并通过USART_RX_CNT计数。代码比较简单,我们就不多说了。
改完usart.c和usart.h之后,我们在test.c修改main函数如下:
int main(void)
{
u8 t;
u8 key;
u16 oldcount=0; //老的串口接收数据值
u16 applenth=0; //接收到的app代码长度
u8 clearflag=0;
Stm32_Clock_Init(9); //系统时钟设置
uart_init(72,256000); //串口初始化为256000
delay_init(72); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init(); //初始化LCD
KEY_Init(); //按键初始化
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(60,50,200,16,16,\"Warship STM32\");
LCD_ShowString(60,70,200,16,16,\"IAP TEST\");
LCD_ShowString(60,90,200,16,16,\"ATOM@ALIENTEK\");
LCD_ShowString(60,110,200,16,16,\"2012/9/24\");
LCD_ShowString(60,130,200,16,16,\"WK_UP:Copy APP2FLASH\");
LCD_ShowString(60,150,200,16,16,\"KEY1:Erase SRAM APP\");
LCD_ShowString(60,170,200,16,16,\"KEY0:Run SRAM APP\");
LCD_ShowString(60,190,200,16,16,\"KEY2:Run FLASH APP\");
POINT_COLOR=BLUE;
//显示提示信息
POINT_COLOR=BLUE;//设置字体为蓝色
while(1)
{
if(USART_RX_CNT)
{
if(oldcount==USART_RX_CNT)
//新周期内,没有收到任何数据,认为本次数据接收完成.
{
applenth=USART_RX_CNT;
oldcount=0;
USART_RX_CNT=0;
printf(\"用户程序接收完成!\\r\\n\");
printf(\"代码长度:%dBytes\\r\\n\",applenth);
}else oldcount=USART_RX_CNT;
}
t++; delay_ms(10);
if(t==30)
{
LED0=!LED0; t=0;
if(clearflag)
{
clearflag--;
if(clearflag==0)LCD_Fill(60,210,240,210+16,WHITE);//清除显示
}
}
key=KEY_Scan(0);
if(key==KEY_UP)
{
if(applenth)
{
printf(\"开始更新固件...\\r\\n\");
LCD_ShowString(60,210,200,16,16,\"Copying APP2FLASH...\");
if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)
//判断是否为0X08XXXXXX.
{
iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,
applenth); //更新FLASH代码
LCD_ShowString(60,210,200,16,16,\"Copy APP Successed!!\");
printf(\"固件更新完成!\\r\\n\");
}else
{
LCD_ShowString(60,210,200,16,16,\"Illegal FLASH APP! \");
printf(\"非FLASH应用程序!\\r\\n\");
}
}else
{
printf(\"没有可以更新的固件!\\r\\n\");
LCD_ShowString(60,210,200,16,16,\"No APP!\");
}
clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示
}
if(key==KEY_DOWN)
{
if(applenth)
{
printf(\"固件清除完成!\\r\\n\");
LCD_ShowString(60,210,200,16,16,\"APP Erase Successed!\");
applenth=0;
}else
{
printf(\"没有可以清除的固件!\\r\\n\");
LCD_ShowString(60,210,200,16,16,\"No APP!\");
}
clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示
}
if(key==KEY_LEFT)
{
printf(\"开始执行FLASH用户代码!!\\r\\n\");
if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)
//判断是否为0X08XXXXXX.
{
iap_load_app(FLASH_APP1_ADDR);//执行FLASH APP代码
}else
{
printf(\"非FLASH应用程序,无法执行!\\r\\n\");
LCD_ShowString(60,210,200,16,16,\"Illegal FLASH APP!\");
}
clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示
}
if(key==KEY_RIGHT)
{
printf(\"开始执行SRAM用户代码!!\\r\\n\");
if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x20000000)
//判断是否为0X20XXXXXX.
{
iap_load_app(0X20001000);//SRAM地址
}else
{
printf(\"非SRAM应用程序,无法执行!\\r\\n\");
LCD_ShowString(60,210,200,16,16,\"Illegal SRAM APP!\");
}
clearflag=7;//标志更新了显示,并且设置7*300ms后清除显示
}
}
}
该段代码,实现了串口数据处理,以及IAP更新和跳转等各项操作。Bootloader程序就设计完成了,但是一般要求bootloader程序越小越好(给APP省空间嘛),所以,本章我们把一些不需要用到的.c文件全部去掉,最后得到工程截图如图53.3.1所示:
图53.3.1 Bootloader 工程截图
从上图可以看出,虽然去掉了一些不用的.c文件,但是Bootloader大小还是有18K左右,比较大,主要原因是液晶驱动和printf占用了比较多的flash,如果大家想进一步删减,可以去掉LCD显示和printf等,不过我们在本章为了演示效果,所以保留了这些代码。
至此,本实验的软件设计部分结束。
FLASH APP和SRAM APP两部分代码,根据53.1节的介绍,大家自行修改都比较简单,我们这里就不介绍了,不过要提醒大家:FLASH APP的起始地址必须是0X08005000,而SRAM APP的起始地址必须是0X20001000。
53.4 下载验证 在代码编译成功之后,我们下载代码到ALIENTEK战舰STM32开发板上,得到,如图53.4.1所示:
图53.4.1 IAP程序界面
此时,我们可以通过串口,发送FLASH APP或者SRAM APP到战舰STM32开发板,如图53.4.2所示:
图53.4.2 串口发送APP程序界面
先用串口调试助手的打开文件按钮(如图标号1所示),找到APP程序生成的.bin文件,然后设置波特率为256000(为了提高速度,Bootloader程序将波特率被设置为256000了),最后点击发送文件(图中标号3所示),将.bin文件发送给战舰STM32开发板。
在收到APP程序之后,我们就可以通过KEY0/KEY2运行这个APP程序了(如果是FLASH APP,则先需要通过WK_UP将其存入对应FLASH区域)。
[ 本帖最后由 正点原子 于 2013-4-19 23:06 编辑 ]本文来自论坛,点击查看完整帖子内容。