搜索
bottom↓
回复: 100

SD卡升级——SDIO_IAP实验

  [复制链接]

出0入0汤圆

发表于 2013-5-29 18:18:19 | 显示全部楼层 |阅读模式
本帖最后由 hexiaolong2009 于 2013-5-29 19:40 编辑

     在嵌入式项目中,经常会用到SD卡升级这一方式来进行产品的软件升级。刚好最近做的项目也需要这一功能,由于之前未接触过IAP开发,刚好在这个时候可以学习一下,于是先到各大网站去搜索相关资料,两天下来,基本对于IAP的概念和编程步骤有了大致的了解。本人手里有块正点原子的开发板,前期的实验都是在这块开发板上实现的。在实现了SD卡IAP功能以后,立马将工程移植到项目中去,很快就把这个功能添加进去了,甚是高兴,对于以前的SD卡升级功能也不再那么神秘了。

    本人是先看正点原子的超级战舰手册,先看的《第三十九章 FLASH模拟EEPROM实验》,了解了STM32片内FLASH编程的步骤,然后再看的《第五十三章 串口IAP实验》,学习IAP编程的思想,最后到阿莫电子论坛上搜索相关的资料,最终完成了SD卡IAP编程的学习,并解决了实际问题。

    学习总结:
    1.STM32片内FLASH编程步骤4步曲:解锁、擦除、编程、上锁;

    2.设置IAP程序在FLASH的起始地址,设置用户程序的起始地址为IAP后面的地址,并修改ROM空间大小;

    3.在用户程序中,设置中断向量偏移地址为用户程序的起始地址;

    4.STM32大容量存储器的页大小为2K,起初总以为是512字节;

    5.页擦除的时候,所有的页地址都是实际的字节地址,而并非常说的“第几页第几页”中的页编号;

    6.页擦除的时候,如果指定的页地址没有和页边界对齐的话,擦除操作仍然有效,只是擦除的范围是指定地址所在的整页大小;


    原子哥的IAP实验是基于串口的,由于串口的数据发送是不可调的,只能一次性将整个用户程序的BIN文件发送给bootloader,而且bootloader是将接收到的用户文件暂存在片内SRAM的,这就限值了用户程序的大小,不能大于SRAM的大小64K。而SD卡设计则不受用户程序大小限值,只要FLASH装得下就行。由于原子哥的代码很多都是寄存器版本的,而文件系统又是他自己独门的FAT32驱动,再加上他的开发板SD卡例程都基于SPI驱动的(只有一个扩展例程是SDIO的),而我的项目时间比较急,要求用最高的效率完成这项功能,于是就产生了以ST官方库函数为主导,以网上开源文件系统Fatfs作为SD卡文件系统驱动,以SDIO4位总线的DMA访问模式为SD卡驱动这样一个方案,一切都只为了开发的效率,同时,也将源代码与大家分享,相信也有很多人使用这样一种方案的。

    本工程试验平台:
    1.硬件:正点原子超级战舰开发板,由于购买时配套的3.5寸触摸屏,对于3.5以下的屏为测试过,但应该没问题,因为LCD驱动用的还是原子哥的驱动,是兼容2.4到3.5的。SanDisk 1G SD卡, MicroSD 2G。注意:要使用超级战舰开发板上的SDIO功能,必须将开发板上的P10跳线帽接到P11上,因为原子的SD卡驱动默认使用SPI接口的,所以这里必须要设置!

    2.软件:ST官方库V3.0的,比较老了。

   FatFs文件系统,注意:本人在ff.h配置中将宏_FS_READONLY配置为1,即只生成读操作的代码,不编译写操作的代码,目的是为了减小
   bootloader的代码量,包括原子哥的LCD.C中的代码也删减了很多。

    下面就将主要的源代码贴出,供大家参考。
  1. /*****************************************************************************************************
  2. 文件名  :main.c

  3. 文件描述:程序执行的主要文件,不用说也明白

  4. 创建人  :何小龙
  5.                   博客:http://blog.csdn.net/hexiaolong2009

  6. 创建时间:2012.05.16

  7. 更改历史:2012.05.29

  8. *****************************************************************************************************/
  9. #include "stm32f10x.h"
  10. #include "delay.h"
  11. #include "LED.h"
  12. #include "diskio.h"
  13. #include "ff.h"
  14. #include "lcd.h"

  15. #define FLASH_APP_ADDR                0x08010000          //第一个应用程序起始地址(存放在FLASH)
  16. #define STM_PAGE_SIZE                2048                        //注意:STM32F103ZET6的FLASH页大小为2K



  17. //****************************************************************************************************
  18. //全局变量声明
  19. FATFS Fs;
  20. FIL file;     
  21. BYTE buffer[STM_PAGE_SIZE];
  22. FRESULT res;        
  23. UINT br;        

  24. typedef  void (*fun)(void);                                //定义一个函数类型的参数.   
  25. fun AppStart;

  26. /*****************************************************************************************************
  27. 函数名  :Jump2App

  28. 功    能:从Bootloader跳转到用户APP程序地址空间

  29. 入口参数:Addr,用户APP的起始执行地址

  30. 出口参数:无

  31. 返回值  :无
  32. *****************************************************************************************************/
  33. void Jump2App(u32 Addr)
  34. {
  35.         if(((*(vu32*)Addr)&0x2FFE0000) == 0x20000000)        //检查栈顶地址是否合法.
  36.         {
  37.                 AppStart = (fun)(*(vu32*)(Addr+4));                        //用户代码区第二个字为程序开始地址(复位地址)               
  38.                 AppStart();                                                                        //跳转到APP.
  39.         }
  40. }                 


  41. /*****************************************************************************************************
  42. 函数名  :FirmwareUpdate

  43. 功    能:固件升级函数

  44. 入口参数:无

  45. 出口参数:无

  46. 返回值  :无
  47. *****************************************************************************************************/
  48. void FirmwareUpdate(void)
  49. {
  50. int PageOffest = 0;                //页偏移,从APP的基地址到当前页起始位置的字节总数
  51. int ByteOffest;                        //当前页内的字节偏移,从当前操作页的起始位置到正在写入位置的字节偏移
  52. int a, b;
  53. u8 i = 0;

  54.         /*首先初始化SD卡*/
  55.         if(0 != disk_initialize(0))        return;

  56.         /*接着挂载文件系统对象*/
  57.         f_mount(0, &Fs);

  58.         /*查找是否存在要升级的BIN文件*/
  59.         res = f_open(&file, "RTC.bin", FA_OPEN_EXISTING | FA_READ);
  60.         if(FR_OK != res) return;

  61.         /*绘制进度条边框*/
  62.         LCD_DrawRectangle(50, 225, 250, 255);

  63.         /*初始化临时变量*/
  64.         a = file.fsize / 100;  //100表示将进度条平均分成100份,由于进度条长度为200个像素,所以1份占用2个像素
  65.         a &= 0xfffffffe;           //将文件平均分成100份,所以a表示一份文件所占的字节数,为确保该字节数为偶数,故做此转换
  66.         b = 0;                                   //b表示当前已经更新了多少字节

  67.         /*执行主要的IAP功能*/
  68.         while(1)
  69.         {
  70.                 /*每次读取一个页的数据到内存缓冲区,注意:STM32F103ZE的页大小为2K*/
  71.             res = f_read(&file, buffer, STM_PAGE_SIZE, &br);
  72.             if (res || br == 0) break;   

  73.                 /*然后就是永恒的4步骤:解锁、擦除、更新、上锁*/
  74.                 FLASH_Unlock();
  75.                 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
  76.                 FLASH_ErasePage(FLASH_APP_ADDR + PageOffest);
  77.                 for(ByteOffest = 0; ByteOffest < STM_PAGE_SIZE; ByteOffest += 2)
  78.                 {
  79.                         /*更新FLASH,注意当前操作的实际位置:APP基地址FLASH_APP_ADDR+页偏移字节PageOffest+当前页内的字节偏移ByteOffest*/
  80.                         FLASH_ProgramHalfWord(FLASH_APP_ADDR + PageOffest + ByteOffest, *(u16*)(buffer + ByteOffest));
  81.                        
  82.                         b += 2;

  83.                         /*更新显示进度条,(b % a == 0)的目的是确保当前正好写完1份文件*/
  84.                         if(b % a == 0)
  85.                         {
  86.                                 LCD_Fill(50, 225, 50 + 2 * (b / a), 255, 0x7e0); //(b / a)表示已经写了几份文件
  87.                         }
  88.                 }
  89.                 FLASH_Lock();
  90.                 PageOffest += STM_PAGE_SIZE;

  91.                 /*每更新完1页,让LED状态翻转一次*/
  92.                 i = !i;
  93.                 if(i)
  94.                         GPIO_SetBits(GPIOB, GPIO_Pin_5);
  95.                 else
  96.                         GPIO_ResetBits(GPIOB, GPIO_Pin_5);
  97.         }

  98.         /*关闭文件,卸载文件系统*/
  99.         f_close(&file);
  100.         f_mount(0, 0);
  101. }


  102. /*****************************************************************************************************
  103. 函数名  :main

  104. 功    能:主程序入口函数

  105. 入口参数:无

  106. 出口参数:无

  107. 返回值  :int
  108. *****************************************************************************************************/
  109. int main(void)
  110. {
  111.         SystemInit();
  112.         delay_init(72);
  113.         LED_Init();
  114.         LCD_Init();
  115.         FirmwareUpdate();
  116.         Jump2App(FLASH_APP_ADDR);
  117.         while(1);
  118. }


复制代码
工程源码:

    还要注意的地方:用户程序是放在FLASH地址0x08010000的位置的,而且该代码只识别SD卡根目录下的RTC.bin文件,如果要更改文件名,则只需将FirmwareUpdate函数中的“RTC.bin”文件改成你要升级的文件即可。

    以下是运行效果:
   
   
希望对大家有帮助。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-5-29 18:59:22 | 显示全部楼层
本帖最后由 adce 于 2013-5-29 19:01 编辑

每次都FLASH_Unlock(); FLASH_Lock();啊....
为什么串口不能接2048就写进去2048...慢慢写呗?....


十分有用感谢楼主...


#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.
程序只需要把这个偏移改了就可以了吧...

出0入0汤圆

 楼主| 发表于 2013-5-29 19:24:34 | 显示全部楼层
adce 发表于 2013-5-29 18:59
每次都FLASH_Unlock(); FLASH_Lock();啊....
为什么串口不能接2048就写进去2048...慢慢写呗?....

一般用串口升级的话,都是在PC机上打开一个串口调试助手,然后索引到要升级的BIN文件,设置好波特率,点击串口调试助手上的“文件发送”,就不停的发送文件,如果波特率速度设置的过快,导致单片机还没有擦除或编程完,就将原来的接收缓冲区的数据给覆盖了,这样的结果是程序最终无法运行。尤其是FLASH的擦写速度都是比较慢的,所以尽量还是一次性传输完成,再进行升级,这样可靠。

出0入0汤圆

发表于 2013-5-29 19:56:23 | 显示全部楼层
哈哈~ 顶一下!~

我是在ST原有的IAP历程上加入了U盘升级
正常运行时利用板载Flash做成一个优盘,把程序拷贝进去,下次重启时升级

如果升级失败,还可以用串口升级

出0入0汤圆

发表于 2013-5-29 20:12:50 | 显示全部楼层
刚才试了一下...非常的好使....听君一席话...省我十本书....
加密用的冗余...
不过速度很快啊...我感觉串口跟的上....

出0入0汤圆

发表于 2013-5-29 20:14:14 | 显示全部楼层
hexiaolong2009 发表于 2013-5-29 19:24
一般用串口升级的话,都是在PC机上打开一个串口调试助手,然后索引到要升级的BIN文件,设置好波特率,点 ...

“在用户程序中,设置中断向量偏移地址为用户程序的起始地址”

中断向量偏移地址怎么设置?

出0入0汤圆

发表于 2013-5-29 20:33:11 | 显示全部楼层
这是个高级东东,要好好学习。谢谢楼主分享。

出0入0汤圆

发表于 2013-5-29 20:33:26 | 显示全部楼层
SNOOKER 发表于 2013-5-29 20:14
“在用户程序中,设置中断向量偏移地址为用户程序的起始地址”

中断向量偏移地址怎么设置? ...

#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.

出0入0汤圆

发表于 2013-5-29 20:46:32 | 显示全部楼层
mark           

出0入0汤圆

发表于 2013-5-29 21:01:59 | 显示全部楼层
这好东西也,要开始学习学习了!

出0入0汤圆

发表于 2013-5-29 21:19:42 | 显示全部楼层
高级

出0入0汤圆

发表于 2013-5-29 22:05:54 | 显示全部楼层
收藏了 很有用的方式 谢谢分享

出0入0汤圆

发表于 2013-5-29 22:05:56 | 显示全部楼层
hexiaolong2009 发表于 2013-5-29 19:24
一般用串口升级的话,都是在PC机上打开一个串口调试助手,然后索引到要升级的BIN文件,设置好波特率,点 ...

用串口升級是絕對可行的,只不過用第三方的串口调试助手這類工具,只是一股腦的一直發送資料,而不能對資料作驗證
最好的方式還是自行作一個協議,並加上校驗
否則只是單純丟資料寫入,被人加上木馬讀出IAP一點也不困難

出0入0汤圆

发表于 2013-5-29 22:18:16 | 显示全部楼层
不错,挺新颖的。
我用的还是串口升级的模式呢。
学习了

出0入0汤圆

 楼主| 发表于 2013-5-29 22:25:48 | 显示全部楼层
jcyao 发表于 2013-5-29 22:05
用串口升級是絕對可行的,只不過用第三方的串口调试助手這類工具,只是一股腦的一直發送資料,而不能對資 ...

吼吼!你那种情况也太高级了!居然还装木马什么的。。。。
之所以选择用SD卡升级,目的是给用户去自己升级的,而非专业人员去升级,所以要求程序越简单越好,操作越方便越好,要是用自己定制的串口软件给用户的话,用户在现场就必须要有一台带串口的电脑,然后还要了解软件的使用说明,还要去将产品与电脑的串口连接好,这些操作对于普通的用户来说,都是很繁琐麻烦的事。而如果给他一张SD卡,把升级文件拷进去,塞进产品里,什么都不用管了,傻瓜式的,多方便啊!
至于你说的加密什么的,一般对于STM32这类芯片的运用场合,也都不是什么高级东西了,大家也没必要搞得那么紧张。。。。。仅代表个人观点,交流学习而已。

出0入0汤圆

 楼主| 发表于 2013-5-29 22:34:20 | 显示全部楼层
SNOOKER 发表于 2013-5-29 20:14
“在用户程序中,设置中断向量偏移地址为用户程序的起始地址”

中断向量偏移地址怎么设置? ...

8楼说的没错,修改ST官方库文件里的宏定义#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.即可,不过这是运用库函数的操作方法。
原子哥也提供了使用寄存器的方法,在进入main的第一句执行SCB->VTOR = 0x08000000 | 0x10000;这里的0x10000就是中断向量的偏移地址,0x08000000为FLASH基地址。
两种方法任你选择。

出0入0汤圆

发表于 2013-5-29 22:44:56 来自手机 | 显示全部楼层
Mark…
来自:amoBBS 阿莫电子论坛 Windows Phone 7 客户端

出0入0汤圆

发表于 2013-5-29 23:16:36 | 显示全部楼层
hexiaolong2009 发表于 2013-5-29 22:25
吼吼!你那种情况也太高级了!居然还装木马什么的。。。。
之所以选择用SD卡升级,目的是给用户去自己升 ...

加密很简单啊...100K的bin冗余到1M....就可以了...

出0入0汤圆

发表于 2013-5-29 23:22:11 | 显示全部楼层
楼主写的很详细,辛苦,学习了,谢谢

出0入0汤圆

发表于 2013-5-29 23:43:48 | 显示全部楼层
一直在用串口升级,有幸接触下SD升级,学习了

出0入0汤圆

发表于 2013-5-30 08:14:48 | 显示全部楼层
不错,Mark。

出0入96汤圆

发表于 2013-5-30 08:35:20 | 显示全部楼层
暂时没有用到的,mark一下吧

出0入0汤圆

发表于 2013-5-30 08:53:20 | 显示全部楼层
马克一下

出0入0汤圆

发表于 2013-5-30 09:18:30 | 显示全部楼层
这东东有用呀,谢谢楼主提供资料

出0入0汤圆

发表于 2013-6-20 10:21:09 | 显示全部楼层
正需要这个,谢谢楼主了。

出0入0汤圆

发表于 2013-6-20 10:34:55 | 显示全部楼层
不错很好!很有用!!

出0入0汤圆

发表于 2013-6-20 11:06:13 | 显示全部楼层
楼主写的太好了,学习

出0入0汤圆

发表于 2013-6-20 11:12:37 | 显示全部楼层
马克一下  先研究下串口IAP先

出0入0汤圆

发表于 2013-6-20 11:18:21 | 显示全部楼层
mark,留个脚印

出0入0汤圆

发表于 2013-6-20 21:57:31 | 显示全部楼层
jcyao 发表于 2013-5-29 22:05
用串口升級是絕對可行的,只不過用第三方的串口调试助手這類工具,只是一股腦的一直發送資料,而不能對資 ...

st官方串口iap例程,用的是超级终端的串口文件传输协议 xmodem 这样不需要自己发明协议了

出0入0汤圆

发表于 2013-7-12 13:54:54 | 显示全部楼层
我的板和楼主的板一样

出0入8汤圆

发表于 2013-7-12 14:28:55 | 显示全部楼层
学习了  lpc2368上面搞过iap

stm32 上面还没搞过  

想问下:
楼主的bootloader和应用程序的ram空间也是独立分开的么?

出0入0汤圆

 楼主| 发表于 2013-7-17 22:39:04 | 显示全部楼层
justdomyself 发表于 2013-7-12 14:28
学习了  lpc2368上面搞过iap

stm32 上面还没搞过  

ROM独立的,RAM不独立。bootloader的时候,RAM会被初始化一次;应用程序启动后,RAM又被重新初始化一次,所以第二次初始化的时候,会将bootloader分配的内存覆盖掉。

出115入0汤圆

发表于 2013-7-17 23:05:53 | 显示全部楼层
支持多大的SD卡?

出0入0汤圆

发表于 2013-7-17 23:14:10 | 显示全部楼层
mark 学习了 , 谢谢

出0入8汤圆

发表于 2013-7-18 09:37:11 | 显示全部楼层
hexiaolong2009 发表于 2013-7-17 22:39
ROM独立的,RAM不独立。bootloader的时候,RAM会被初始化一次;应用程序启动后,RAM又被重新初始化一次, ...

能否将相关代码贴出来参考下  

我看看lpc上能否这么干

出0入0汤圆

发表于 2013-7-18 10:12:16 | 显示全部楼层
mark一下

出0入147汤圆

发表于 2013-7-18 10:25:04 | 显示全部楼层
编程过程不需要一直进行unlock和lock操作,另外从安全性考虑,最好把固件用AES加密后再下发。

出0入0汤圆

发表于 2013-7-21 19:09:39 | 显示全部楼层
马克,马可

出0入0汤圆

 楼主| 发表于 2013-7-23 14:36:43 | 显示全部楼层
justdomyself 发表于 2013-7-18 09:37
能否将相关代码贴出来参考下  

我看看lpc上能否这么干

这个是初始化过程是由C Runtime 库函数完成的,用户代码是看不到的。建议你去看一下ARM 链接器的工作原理就知道了。

出0入8汤圆

发表于 2013-7-23 15:46:39 | 显示全部楼层
hexiaolong2009 发表于 2013-7-23 14:36
这个是初始化过程是由C Runtime 库函数完成的,用户代码是看不到的。建议你去看一下ARM 链接器的工作原理 ...

runtime  ?  
你用的不是keil?

你的意思就是通过软件的配置来实现   只不过不同的软件配置方式不尽相同


我用的是ads

出0入0汤圆

发表于 2013-10-3 22:34:33 | 显示全部楼层
跟高手学习下

出0入0汤圆

发表于 2013-10-4 13:09:42 | 显示全部楼层

mark一下

出0入0汤圆

发表于 2013-10-4 14:05:43 | 显示全部楼层
升级过程中断电会怎样?

出0入0汤圆

发表于 2013-10-4 15:18:24 来自手机 | 显示全部楼层
有时间试试

出0入0汤圆

发表于 2013-10-27 22:21:54 | 显示全部楼层
学习了。

出0入0汤圆

发表于 2013-10-28 08:26:55 来自手机 | 显示全部楼层
不错。就是程序比较大的时候,不能全部下载来写,只能一页一页的来了。
还有通讯的错误校验很必要吧!

出0入0汤圆

发表于 2013-10-28 11:28:17 | 显示全部楼层
好贴,学习了!!

出0入0汤圆

发表于 2013-10-28 11:49:32 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2013-11-5 21:21:26 | 显示全部楼层
高手,mark            mark        mark

出0入0汤圆

发表于 2013-11-14 14:31:58 | 显示全部楼层
mark backup

出0入0汤圆

发表于 2013-11-14 14:45:05 | 显示全部楼层
不错不错不错

出0入14汤圆

发表于 2013-11-14 17:35:14 | 显示全部楼层

这个是定义用户程序的起始地址
#define FLASH_APP_ADDR                0x08010000          //第一个应用程序起始地址(存放在FLASH)

那么在下载的时候怎么才能正确的吧程序下载到这个地址里面?怎么设置?

出0入14汤圆

发表于 2013-11-14 17:52:31 | 显示全部楼层
void Jump2App(u32 Addr)
{
        if(((*(vu32*)Addr)&0x2FFE0000) == 0x20000000)        //检查栈顶地址是否合法.
        {
                AppStart = (fun)(*(vu32*)(Addr+4));                        //用户代码区第二个字为程序开始地址(复位地址)               
                AppStart();                                                                        //跳转到APP.
        }
}

在这个函数里面  

AppStart();                                                                        //跳转到APP.

这个没有定义啊,为什么在其他的IAP里面都有这个,

typedef  void (*fun)(void);                                //定义一个函数类型的参数.   
fun AppStart;

只有这个定义是什么意思?

出0入0汤圆

发表于 2013-11-14 17:54:58 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2013-11-14 18:58:18 来自手机 | 显示全部楼层
记号,记号

出0入0汤圆

发表于 2013-11-14 22:05:09 | 显示全部楼层
sd卡刚开始接触 还没有学会操作 看来要努力学习了 谢谢楼主好文

出0入0汤圆

发表于 2013-11-14 22:30:23 | 显示全部楼层
标记学习。谢谢楼主分享。

出0入0汤圆

 楼主| 发表于 2013-11-15 21:38:39 | 显示全部楼层
isakura 发表于 2013-11-14 17:35
这个是定义用户程序的起始地址
#define FLASH_APP_ADDR                0x08010000          //第一个应用程序起始地址(存放在FL ...

请看正点原子超级战舰手册里的《第五十三章 串口IAP实验》
里面有你想要的答案。

出0入0汤圆

 楼主| 发表于 2013-11-15 21:40:33 | 显示全部楼层
isakura 发表于 2013-11-14 17:52
void Jump2App(u32 Addr)
{
        if(((*(vu32*)Addr)&0x2FFE0000) == 0x20000000)        //检查栈顶地 ...

这是C语言的基础知识,建议你补一下typedef的用法以及函数指针的用法。

出0入14汤圆

发表于 2013-11-15 22:24:41 | 显示全部楼层
hexiaolong2009 发表于 2013-11-15 21:40
这是C语言的基础知识,建议你补一下typedef的用法以及函数指针的用法。

这个函数指针这些理解的差不多了,就是那个 0x2FFE0000 还没弄懂,不明白为什么是这个值

与操作究竟是判断什么的

现在正在找正点原子的手册,先看看有没有收获

出0入0汤圆

发表于 2013-11-15 23:37:55 | 显示全部楼层
参考一下,最近这个项目也需要sd卡烧写固件。

出0入0汤圆

发表于 2013-11-23 09:33:14 | 显示全部楼层
mark,备用!
谢谢楼主

出0入0汤圆

发表于 2013-11-26 00:34:05 | 显示全部楼层
学习了,谢谢!

出0入0汤圆

发表于 2013-11-26 09:55:02 | 显示全部楼层
isakura 发表于 2013-11-15 22:24
这个函数指针这些理解的差不多了,就是那个 0x2FFE0000 还没弄懂,不明白为什么是这个值

与操作究竟是判 ...

同问 ,这句话判断的意思是什么?

出0入0汤圆

 楼主| 发表于 2013-11-26 21:28:42 | 显示全部楼层
isakura 发表于 2013-11-15 22:24
这个函数指针这些理解的差不多了,就是那个 0x2FFE0000 还没弄懂,不明白为什么是这个值

与操作究竟是判 ...

这个“0x2FFE0000与操作”主要是用来判断堆栈地址是否合法的,Cotex-M3在中断向量表的第一个表项,即0地址的4字节内容不是用来存储中断跳转指令的,而是用来存储初始堆栈指针的。
你可以通过查看应用程序的startup_stm32f10x_hd.s文件中的__initial_spTop标号来确定自己的应用程序初始堆栈指针指向哪里。
例如,我的要被加载的应用程序startup_stm32f10x_hd.s文件内容如下:

Stack_Size      EQU     0x00000800

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

__initial_spTop EQU    0x20000800                 ; stack used for SystemInit_ExtMemCtl

可以看到,我的堆栈大小为0x00000800,栈顶指针为0x20000800。而对于不同的用户所设定的堆栈空间大小可能不同,但对于同一型号的芯片而言,有一点是相同的,那就是它的片内RAM大小是相同的。比如我所用的STM32F103VET6的IRAM为64K,即0x10000,而内部RAM的起始地址为0x20000000,所以初始堆栈指针最大也不会超过0x20010000,这就是为什么一定要与上个0x2FFE0000,只有这样才能保证你所设置的堆栈指针只能在0x20000000~0x20010000合法,而这个地址以外的为非法地址。

如果不合法,则说明可能加载了一个错误的地址,那么bootloader就不会跳转到应用程序中去,这样就可以防止内存访问出错而造成死机。

小伙伴们,明白了吗。。。。。。

出0入0汤圆

 楼主| 发表于 2013-11-26 21:29:24 | 显示全部楼层
lpdpzc 发表于 2013-11-26 09:55
同问 ,这句话判断的意思是什么?

请看楼上!

出0入0汤圆

发表于 2013-11-26 21:35:31 | 显示全部楼层
如此好贴 不得不顶一下      

出0入0汤圆

发表于 2013-11-26 22:42:58 | 显示全部楼层
收下了

出0入0汤圆

发表于 2013-11-27 08:28:03 | 显示全部楼层

谢谢你的详细解答!

出0入14汤圆

发表于 2013-11-27 17:02:58 | 显示全部楼层
hexiaolong2009 发表于 2013-11-26 21:28
这个“0x2FFE0000与操作”主要是用来判断堆栈地址是否合法的,Cotex-M3在中断向量表的第一个表项,即0地 ...

谢谢解答,大概明白了

出0入0汤圆

发表于 2013-11-27 19:52:14 | 显示全部楼层
学习,观摩

出0入0汤圆

发表于 2013-11-28 08:53:53 | 显示全部楼层
正好要用到IAP ,先学习一下,谢谢LZ分享!

出0入0汤圆

发表于 2013-11-28 09:17:24 | 显示全部楼层
IAP 楼主发的都是好文···感动的哭了

出0入0汤圆

发表于 2013-11-28 09:21:20 | 显示全部楼层
看楼主的 博客,和我一样好年轻,,目测 今年毕业的?学长好····

出0入0汤圆

发表于 2013-12-2 12:02:35 | 显示全部楼层
这个很有用,日后估计要用到/

出0入0汤圆

发表于 2013-12-2 21:58:26 | 显示全部楼层
不明觉厉

出0入0汤圆

发表于 2013-12-2 22:10:32 | 显示全部楼层
mark            

出0入4汤圆

发表于 2013-12-2 22:33:10 | 显示全部楼层
厉害厉害。。。。

出0入4汤圆

发表于 2013-12-2 22:33:36 | 显示全部楼层

成语高人啊!!!

出0入0汤圆

发表于 2014-1-2 21:43:42 | 显示全部楼层
hexiaolong2009 发表于 2013-11-26 21:28
这个“0x2FFE0000与操作”主要是用来判断堆栈地址是否合法的,Cotex-M3在中断向量表的第一个表项,即0地 ...

这位大哥,你研究的好透啊,佩服


我感觉还需要解决的问题是边接收边写进flash,和校验,你感觉呢

出0入0汤圆

发表于 2014-1-2 22:48:22 | 显示全部楼层
mark,学习了

出0入0汤圆

发表于 2014-1-3 09:00:09 | 显示全部楼层
用着方便

出0入0汤圆

发表于 2014-1-25 20:19:33 | 显示全部楼层
楼主厉害啊

出0入0汤圆

发表于 2014-1-25 23:00:12 | 显示全部楼层
这种方式确实不错 多谢

出0入0汤圆

发表于 2014-1-26 16:09:48 | 显示全部楼层
好好学习一下

出115入0汤圆

发表于 2014-1-27 09:48:02 | 显示全部楼层
楼主有没有试过8G的卡。我现在写的系统,8G的卡,如果容量超过4G,就不正常了。还不知道怎么处理才好。

出0入0汤圆

 楼主| 发表于 2014-1-27 13:39:12 | 显示全部楼层
newkey 发表于 2014-1-27 09:48
楼主有没有试过8G的卡。我现在写的系统,8G的卡,如果容量超过4G,就不正常了。还不知道怎么处理才好。 ...

你说“容量超过4G”,指的是SD卡大小超过4G还是指往里面写超过4G的文件?
如果是往里面写一个超过4G的文件,那么肯定是不行的,因为FAT32本身就只能支持最大4G的文件,再大就操作不了了(PC机也是一样的,所以才有NTFS文件系统,可以支持单个文件超过4G的访问);
如果你指的是超过4G的SD卡,那么我本人亲测过8G的SanDisk MicroSD卡,是能正常读写文件的。

出0入0汤圆

发表于 2014-1-27 14:36:46 | 显示全部楼层
不错,收藏下!

出115入0汤圆

发表于 2014-2-1 00:17:38 | 显示全部楼层
hexiaolong2009 发表于 2014-1-27 13:39
你说“容量超过4G”,指的是SD卡大小超过4G还是指往里面写超过4G的文件?
如果是往里面写一个超过4G的文 ...

8G的卡,我测试过,用STM32写进去再读出来是正常的。
但是如果这张8G的卡里面本来已经装有6G的东西,
这个时候你再从电脑里面拷贝一个TXT到卡里,然后用STM32来读,读出来的就是乱码。
然后我再把SD卡里面的东西删掉一些,还占用2G空间,那么这个时候从电脑里再拷贝一个TXT文件到卡里,用STM32来读,就正常了。

我现在还不知道是不是因为文件系统里面地址是32位变量,所以寻址范围才有4G造成的。

出0入0汤圆

发表于 2014-2-12 21:27:16 | 显示全部楼层
谢楼主,已成功使用SD卡升级。

出0入0汤圆

发表于 2014-2-13 08:54:38 | 显示全部楼层
学习了mark

出0入0汤圆

发表于 2014-7-11 11:53:38 | 显示全部楼层
谢谢楼主,正需要这方面的知识

出0入0汤圆

发表于 2014-7-11 16:50:45 | 显示全部楼层
你这个IAP 需要占用多大的FLASH 空间.

出0入0汤圆

发表于 2014-9-20 08:17:36 | 显示全部楼层
好资料,收藏备用!

出0入0汤圆

发表于 2014-12-4 14:20:27 | 显示全部楼层
好东西,赶紧收藏,谢谢楼主分享

出0入0汤圆

发表于 2014-12-4 14:50:55 | 显示全部楼层
谢谢分享  正打算研究一下  IAP呢  ..

出0入0汤圆

发表于 2014-12-4 19:21:37 | 显示全部楼层
很有用,谢谢

出0入53汤圆

发表于 2015-1-13 16:05:39 | 显示全部楼层
adce 发表于 2013-5-29 20:12
刚才试了一下...非常的好使....听君一席话...省我十本书....
加密用的冗余...
不过速度很快啊...我感觉串口 ...

请问IAP文件如何去写呢

出0入0汤圆

发表于 2017-7-17 12:06:16 | 显示全部楼层
mark  SD卡升级——SDIO_IAP实验
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-2 21:13

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表