stmflash.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. #include "stmflash.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "iap.h"
  5. //////////////////////////////////////////////////////////////////////////////////
  6. //本程序只供学习使用,未经作者许可,不得用于其它任何用途
  7. //ALIENTEK miniSTM32开发板
  8. //STM32 FLASH 驱动代码
  9. //正点原子@ALIENTEK
  10. //技术论坛:www.openedv.com
  11. //修改日期:2012/9/13
  12. //版本:V1.0
  13. //版权所有,盗版必究。
  14. //Copyright(C) 广州市星翼电子科技有限公司 2009-2019
  15. //All rights reserved
  16. //////////////////////////////////////////////////////////////////////////////////
  17. //读取指定地址的半字(16位数据)
  18. //faddr:读地址(此地址必须为2的倍数!!)
  19. //返回值:对应数据.
  20. u16 STMFLASH_ReadHalfWord(u32 faddr)
  21. {
  22. return *(vu16*)faddr;
  23. }
  24. #if STM32_FLASH_WREN //如果使能了写
  25. //不检查的写入
  26. //WriteAddr:起始地址
  27. //pBuffer:数据指针
  28. //NumToWrite:半字(16位)数
  29. void STMFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
  30. {
  31. u16 i;
  32. for(i=0;i<NumToWrite;i++)
  33. {
  34. FLASH_ProgramHalfWord(WriteAddr,pBuffer[i]);
  35. WriteAddr+=2;//地址增加2.
  36. }
  37. }
  38. //从指定地址开始写入指定长度的数据
  39. //WriteAddr:起始地址(此地址必须为2的倍数!!)
  40. //pBuffer:数据指针
  41. //NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)
  42. #if STM32_FLASH_SIZE<256
  43. #define STM_SECTOR_SIZE 1024 //字节
  44. #else
  45. #define STM_SECTOR_SIZE 2048
  46. #endif
  47. u16 STMFLASH_BUF[STM_SECTOR_SIZE/2];//最多是2K字节
  48. void STMFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
  49. {
  50. u32 secpos; //扇区地址
  51. u16 secoff; //扇区内偏移地址(16位字计算)
  52. u16 secremain; //扇区内剩余地址(16位字计算)
  53. u16 i;
  54. u32 offaddr; //去掉0X08000000后的地址
  55. if(WriteAddr<STM32_FLASH_BASE||(WriteAddr>=(STM32_FLASH_BASE+1024*STM32_FLASH_SIZE)))return;//非法地址
  56. FLASH_Unlock(); //解锁
  57. offaddr=WriteAddr-STM32_FLASH_BASE; //实际偏移地址.
  58. secpos=offaddr/STM_SECTOR_SIZE; //扇区地址 0~255 for STM32F103RCT6
  59. secoff=(offaddr%STM_SECTOR_SIZE)/2; //在扇区内的偏移(2个字节为基本单位.)
  60. secremain=STM_SECTOR_SIZE/2-secoff; //扇区剩余空间大小
  61. if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
  62. while(1)
  63. {
  64. STMFLASH_Read(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//读出整个扇区的内容
  65. for(i=0;i<secremain;i++) //校验数据
  66. {
  67. if(STMFLASH_BUF[secoff+i]!=0XFFFF)break; //需要擦除
  68. }
  69. if(i<secremain) //需要擦除
  70. {
  71. FLASH_ErasePage(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE);//擦除这个扇区
  72. for(i=0;i<secremain;i++) //复制
  73. {
  74. STMFLASH_BUF[i+secoff]=pBuffer[i];
  75. }
  76. STMFLASH_Write_NoCheck(secpos*STM_SECTOR_SIZE+STM32_FLASH_BASE,STMFLASH_BUF,STM_SECTOR_SIZE/2);//写入整个扇区
  77. }
  78. else
  79. STMFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.
  80. if(NumToWrite==secremain)
  81. break; //写入结束了
  82. else //写入未结束
  83. {
  84. secpos++; //扇区地址增1
  85. secoff=0; //偏移位置为0
  86. pBuffer+=secremain; //指针偏移
  87. WriteAddr+=secremain; //写地址偏移
  88. NumToWrite-=secremain; //字节(16位)数递减
  89. if(NumToWrite>(STM_SECTOR_SIZE/2))
  90. secremain=STM_SECTOR_SIZE/2;//下一个扇区还是写不完
  91. else
  92. secremain=NumToWrite;//下一个扇区可以写完了
  93. }
  94. };
  95. FLASH_Lock(); //上锁
  96. }
  97. #endif
  98. //从指定地址开始读出指定长度的数据
  99. //ReadAddr:起始地址
  100. //pBuffer:数据指针
  101. //NumToWrite:半字(16位)数
  102. void STMFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)
  103. {
  104. u16 i;
  105. for(i=0;i<NumToRead;i++)
  106. {
  107. pBuffer[i]=STMFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
  108. ReadAddr+=2;//偏移2个字节.
  109. }
  110. }
  111. //////////////////////////////////////////////////////////////////////////////////////////////////////
  112. //WriteAddr:起始地址
  113. //WriteData:要写入的数据
  114. void Test_Write(u32 WriteAddr,u16 WriteData)
  115. {
  116. STMFLASH_Write(WriteAddr,&WriteData,1);//写入一个字
  117. }
  118. //擦除app1
  119. uint32_t erase_app1(void)
  120. {
  121. uint32_t addr;
  122. DEBUG_F("start erase_app1......\r\n");
  123. for(addr=FLASH_APP1_ADDR;addr<FLASH_APP2_ADDR;addr+=STM_SECTOR_SIZE){
  124. IWDG_Feed(); //喂狗
  125. FLASH_ErasePage(addr);
  126. }
  127. DEBUG_F("end erase_app1......\r\n");
  128. return addr;
  129. }
  130. //擦除app2
  131. uint32_t erase_app2(void)
  132. {
  133. uint32_t addr;
  134. IWDG_Feed(); //喂狗
  135. DEBUG_F("start erase_app2......\r\n");
  136. for(addr=FLASH_APP2_ADDR;addr<FLASH_APP3_ADDR;addr+=STM_SECTOR_SIZE){
  137. FLASH_ErasePage(addr);
  138. }
  139. DEBUG_F("end erase_app2......\r\n");
  140. return addr;
  141. }
  142. //擦除app3,
  143. uint32_t erase_app3(void)
  144. {
  145. uint32_t addr;
  146. DEBUG_F("start erase_app3......\r\n");
  147. for(addr=FLASH_APP3_ADDR;addr<STM32_FLASH_SIZE*1024+STM32_FLASH_BASE;addr+=STM_SECTOR_SIZE){
  148. FLASH_ErasePage(addr);
  149. }
  150. DEBUG_F("end erase_app3......\r\n");
  151. return addr;
  152. }
  153. //复制,
  154. uint32_t cp_app3_app1(void)
  155. {
  156. uint32_t i;
  157. uint16_t temp;
  158. uint32_t size=64/2*1024; //1个半字=2个字节,整个app的大小为64k字节=32k半字
  159. DEBUG_F("start cp_app3_app1......\r\n");
  160. for(i=0;i<size;i++){ //
  161. IWDG_Feed(); //喂狗
  162. temp = STMFLASH_ReadHalfWord(FLASH_APP3_ADDR+i*2);
  163. FLASH_ProgramHalfWord(FLASH_APP1_ADDR+i*2,temp);
  164. }
  165. DEBUG_F("end cp_app3_app1......\r\n");
  166. return size;
  167. }
  168. //复制,
  169. uint32_t cp_app1_app2(void)
  170. {
  171. uint32_t i;
  172. uint16_t temp;
  173. uint32_t size=64/2*1024; //1个半字=2个字节,整个app的大小为64k字节=32k半字
  174. DEBUG_F("start cp_app1_app2......\r\n");
  175. for(i=0;i<size;i++){ //
  176. IWDG_Feed(); //喂狗
  177. temp = STMFLASH_ReadHalfWord(FLASH_APP1_ADDR+i*2);
  178. FLASH_ProgramHalfWord(FLASH_APP2_ADDR+i*2,temp);
  179. }
  180. DEBUG_F("end cp_app1_app2......\r\n");
  181. return size;
  182. }
  183. //复制,
  184. uint32_t cp_app2_app1(void)
  185. {
  186. uint32_t i;
  187. uint16_t temp;
  188. uint32_t size=64/2*1024; //1个半字=2个字节,整个app的大小为64k字节=32k半字
  189. DEBUG_F("start cp_app2_app1......\r\n");
  190. for(i=0;i<size;i++){ //
  191. IWDG_Feed(); //喂狗
  192. temp = STMFLASH_ReadHalfWord(FLASH_APP2_ADDR+i*2);
  193. FLASH_ProgramHalfWord(FLASH_APP1_ADDR+i*2,temp);
  194. }
  195. DEBUG_F("end cp_app2_app1......\r\n");
  196. return size;
  197. }
  198. //读取app1,
  199. uint32_t read_app1(void)
  200. {
  201. uint32_t i;
  202. uint16_t temp;
  203. uint32_t size=64/2*1024; //1个半字=2个字节,整个app的大小为64k字节=32k半字
  204. DEBUG_F("start read_app1......\r\n");
  205. for(i=0;i<size;i++){ //
  206. if(i%128==0)
  207. IWDG_Feed(); //喂狗
  208. if((i%32 == 0)&&(i>0))
  209. printf("\r\n");
  210. temp = STMFLASH_ReadHalfWord(FLASH_APP1_ADDR+i*2);
  211. printf("%02X %02X ",(uint8_t)(temp&0xFF),(uint8_t)(temp>>8));
  212. }
  213. DEBUG_F("\r\nsize=%d\r\n",size*2);
  214. DEBUG_F("end read_app1......\r\n");
  215. return size;
  216. }
  217. //读取app1,
  218. uint32_t read_app2(void)
  219. {
  220. uint32_t i;
  221. uint16_t temp;
  222. uint32_t size=64/2*1024; //1个半字=2个字节,整个app的大小为64k字节=32k半字
  223. DEBUG_F("start read_app2......\r\n");
  224. for(i=0;i<size;i++){ //
  225. if(i%128==0)
  226. IWDG_Feed(); //喂狗
  227. if((i%32 == 0)&&(i>0))
  228. printf("\r\n");
  229. temp = STMFLASH_ReadHalfWord(FLASH_APP2_ADDR+i*2);
  230. printf("%02X %02X ",(uint8_t)(temp&0xFF),(uint8_t)(temp>>8));
  231. }
  232. DEBUG_F("\r\nsize=%d\r\n",size*2);
  233. DEBUG_F("end read_app2......\r\n");
  234. return size;
  235. }
  236. //读取app1,
  237. uint32_t read_app3(void)
  238. {
  239. uint32_t i;
  240. uint16_t temp;
  241. uint32_t size=64/2*1024; //1个半字=2个字节,整个app的大小为64k字节=32k半字
  242. DEBUG_F("start read_app3......\r\n");
  243. for(i=0;i<size;i++){ //
  244. if(i%128==0)
  245. IWDG_Feed(); //喂狗
  246. if((i%32 == 0)&&(i>0))
  247. printf("\r\n");
  248. temp = STMFLASH_ReadHalfWord(FLASH_APP3_ADDR+i*2);
  249. printf("%02X %02X ",(uint8_t)(temp&0xFF),(uint8_t)(temp>>8));
  250. }
  251. DEBUG_F("\r\nsize=%d\r\n",size*2);
  252. DEBUG_F("end read_app3......\r\n");
  253. return size;
  254. }