STM32串口IAP实验笔记

简介: STM32串口IAP实验笔记
+关注继续查看

STM32的IAP功能确实方便,以前对此如何实现有所了解,但是一直没去测试,这两天来练了下,可谓困难重重,搞了两天问题也一一解决,下面做些简要的笔记

IAP就是在线应用编程,方便程序升级,可以不用打开产品,直接通过串口升级,那么就需要一个引导程序(大神们喜欢称bootload),一个APP程序(实际产品的工作程序)

减小测试难度,我设计了3个程序,一个bootload程序,一个LED闪烁程序,一个KEY+LED点动程序,我的目的就是用两个不一样的APP程序,互相升级,方便验证结果

我手里的开发板是STM32F103ZET,属于大容量产品,flash有512K, 我们的bootload和APP应用程序就需要在flash里面进行划分,对于我的测试程序,这些空间实在是太大了,有点大材小用了

STM32F103ZET的flash起始地址是0x8000000,总共是512k,那就是到0x807ffff结束。

定义bootload的范围0x8000000 --- 0x800ffff;

定义APP的范围     0x8010000 --- 0x807ffff;

下面首先是bootload介绍

bootload的程序和一般程序区别不大,就是在MDK配置方面需要注意

image

image

这些设置好以后直接生产HEX文件,下载便可

在此,测试的时候遇到两个问题,

一个是串口接受时,上位设置了256000的波特率,我芯片波特率设置成25600,少了一个0,数据一直不对,接受到的APP数据全是乱码,搞了有四五小时才发现,真是蛋疼

image

另外一个在验证flash读写时,数据位没搞对,applenth本身是接受的数据长度,我前面一直在箭头的方向,进来就清零,导致可写入flash的数据数为0,后面读flash的时候全是0xffff,这块也耗了有两个小时。

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

int main(void)                                //bootload的main汗死

{

   u16 oldcount=0;

   u16 applenth=0;

   main_init();

   

   while(1)

   {

       time_loop();

       key_dispose();

       

       if(bit_20ms==1)                            //20ms检测一次串口数据,是否有数据,是否数据不变,就接受完成了

       {

           bit_20ms=0;

           if(USART_RX_CNT)

           {

               if(oldcount==USART_RX_CNT)          //新周期内,没有收到任何数据,认为本次数据接收完成.

               {

                   applenth=USART_RX_CNT;

                   oldcount=0;

                   USART_RX_CNT=0;

               }

               else 

                   oldcount=USART_RX_CNT;            

           }        

           

       }

       if(applenth!=0)                           //数据长度不为0,说明串口接受完成了                            

       {

               add_tmp=(*(vu32*)(0X20001000+4));    //这里add_tmp是验证地址数据,好自己判断下面的if条件是否成立

                if(((*(vu32*)(0X20001000+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.

               {     

                   iap_write_appbin(FLASH_APP1_ADDR,USART_RX_BUF,applenth);//更新FLASH代码     //串口数据写入到flash 

                   delay_ms(100);

                   bit_new=1;

               }

               applenth=0;

       }

   

       if((bit_10s==1)&&(bit_new==1))        //10s后才执行更新部分的程序

       {

           bit_10s=0;

           bit_new=0;

           add_tmp=(*(vu32*)(FLASH_APP1_ADDR+4));         //这里add_tmp也为验证,不用的话可以去掉

            if(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判断是否为0X08XXXXXX.

           {     

               iap_load_app(FLASH_APP1_ADDR);               //执行FLASH APP代码

           }    

       }

   }

}

再来介绍下APP的程序,APP程序,我们上面已经定义了APP的地址,相比bootload的地址,我偏移了0x1000,那么APP的一些中断向量什么都要进行设置

先配置下MDK文件

image

然后在程序main函数里面设置 SCB->VTOR = FLASH_BASE | 0x10000;我们自己定义的偏移量

其他和正常程序类似

在调速APP程序时也遇到一个头疼问题

就是偏移量问题,我们上面说了,一进main函数就设置下,但是我的依然不行,最后发现原来是我的程序在其他地方又复位成了0,因为程序模版是拷贝的,一些地方没记得改image

这个是中断配置汗死,以前的模版,习惯上中断偏移为0,按下面流程走下来后,等于回头了

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

static void NVIC_Configuration(void)

{

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0);    //这里需要配置偏移量,放在APP里面0是错误的

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置NVIC中断分组4:4位抢占优先级,0位响应优先级

}

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

void    main_init(void)

{

   SCB->VTOR = FLASH_BASE | 0x10000;

   NVIC_Configuration();

   SysTick_init();

   

   led_init();

   key_init();

}

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

int main(void)

{

   main_init();

   

   while(1)

   {

       time_loop();

       key_dispose();

   }

}

下面来到最关键的一步,我们要用串口下面,怎么下载,下载什么问题

APP需要先生产BIN文件,然后接受常规的串口软件便可,方法如下

image

这个需要填写到上面框中D:\KEIL\ARM\ARMCC\BIN\fromelf.exe  --bin -o  ..\OBJ\LEDKEYTOBIN.bin ..\OBJ\LEDKEYTOBIN.axf

在网上查了路径要按照自己的来,有的是KEIL\ARM\BIN40\....等等

LEDKEYTOBIN,这个是根据自己的喜好来的,但是要和下图所框的对应起来

image

大功告成,编译如下

image

 

类似的再搞个其他的APP程序,就可以完成bootload做为引导,APP升级方式。

相关文章
|
2月前
|
存储 物联网 芯片
STM32速成笔记(十四)—串口IAP
本文介绍了什么是IAP,IAP有什么作用,如何实现IAP。最后,给出了IAP的实现程序。
29 0
STM32速成笔记(十四)—串口IAP
|
2月前
|
芯片 内存技术
STM32速成笔记(十三)—低功耗模式
本文介绍了三种STM32低功耗模式的进入和退出方法,针对待机唤醒给出了程序设计。
26 0
STM32速成笔记(十三)—低功耗模式
|
2月前
|
存储 芯片 内存技术
STM32速成笔记(十二)—Flash闪存
本文简单介绍了什么是Flash。针对STM32F1的Flash做了详细介绍,介绍了操作Flash的步骤,并且给出了程序设计。最后,介绍了一些注意事项。
16 0
STM32速成笔记(十二)—Flash闪存
|
2月前
|
存储 芯片
STM32速成笔记(十一)—EEPROM(AT24C02)
本文详细介绍了什么是AT24C02,介绍了它的引脚,读/写时序,给出了应用实例和详细的程序设计。最后,简单介绍了AT24C02的应用场景。
29 0
STM32速成笔记(十一)—EEPROM(AT24C02)
|
2月前
STM32速成笔记(十)—IWDG
本文详细介绍了什么是IWDG,STM32的IWDG特性,框图和配置步骤。此外,给出了STM32的IWDG配置程序。通过一个简单的应用实例,展示了IWDG的配置和使用方法。
12 0
STM32速成笔记(十)—IWDG
|
2月前
|
API
STM32速成笔记(九)—RTC
本文详细介绍了RTC模块,介绍了STM32的RTC的特性,框图,配置步骤,并给出了详细的程序设计。最后,针对实际使用时可能遇到的问题给出了解决方法以及程序。
25 0
STM32速成笔记(九)—RTC
|
2月前
|
存储 Perl
STM32速成笔记(八)—DMA
本文介绍了DMA的概念,用途。对于STM32F103ZET6的DMA做出了详细地介绍,给出了DMA配置步骤。最后,以配置DMA搬运ADC转换结果为例,给出了DMA的配置和使用方法。
27 0
STM32速成笔记(八)—DMA
|
2月前
|
存储 传感器
STM32速成笔记(七)—ADC
本文介绍了ADC的概念,用途,针对STM32的ADC做出了详细介绍,给出了配置步骤,配置程序。通过一个简单的小项目展示了ADC的配置和使用方法。此外,还针对如何利用定时器触发AD转换,如何采集交流信号,如何计算交流信号有效值进行了介绍,并给出了程序设计。
46 0
STM32速成笔记(七)—ADC
|
2月前
STM32速成笔记(六)—定时器
本文介绍了定时器的概念,作用。针对STM32F1的通用定时器做了详细介绍。此外,介绍了PWM的概念,用途以及STM32F1的PWM,给出了PWM频率的计算方法。最后通过介绍利用定时器的更新中断和PWM这两种方法实现呼吸灯,展示了定时器和PWM的配置步骤,并给出了详细的程序设计。另外,介绍了利用定时器实现按键长短按的检测方法。
53 0
STM32速成笔记(六)—定时器
|
2月前
|
芯片
STM32速成笔记(五)—串口通信
本文介绍了串口通信的概念,用途以及一些相关概念。介绍了如何进行printf重定向,如何根据接收到的特定信息,执行特定操作。此外,本文以通过上位机发送特殊指令控制LED亮灭的小项目,给出了详细的配置方法和程序设计。
59 0
STM32速成笔记(五)—串口通信