389 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			389 lines
		
	
	
		
			7.1 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | ||
| 
 | ||
| #include "rtthread.h"
 | ||
| #include "stm32f10x.h"
 | ||
| #include "board.h"
 | ||
| #include "dev_flash.h"
 | ||
| #include "debug.h"
 | ||
| #include "stdlib.h"
 | ||
| #include "string.h"
 | ||
| 
 | ||
| #ifndef RT_THREAD
 | ||
| 
 | ||
| #define rt_interrupt_enter()
 | ||
| #define rt_interrupt_leave()
 | ||
| #define rt_mutex_create(...) 0
 | ||
| #define rt_mutex_delete(...)
 | ||
| #define rt_mutex_take(...)
 | ||
| #define rt_mutex_release(...)
 | ||
| 
 | ||
| #endif
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| /*
 | ||
| 
 | ||
| bootloader 0~7
 | ||
| app 8~57
 | ||
| buff 58~107
 | ||
| params 108
 | ||
| scheme 109~110
 | ||
| 
 | ||
| */
 | ||
| #define FLASH_SECTOR_SIZE         2048
 | ||
| #define FLASH_BOOT_SECTOR         (0)
 | ||
| #define FLASH_BOOT_SECTOR_NUM     (8)
 | ||
| #define FLASH_APP_SECTOR          (8)
 | ||
| #define FLASH_APP_SECTOR_NUM      (50)
 | ||
| #define FLASH_BUFF_SECTOR         (58)
 | ||
| #define FLASH_BUFF_SECTOR_NUM     (50)
 | ||
| #define FLASH_PARAM_SECTOR        (108)
 | ||
| #define FLASH_PARAM_SECTOR_NUM    (1)
 | ||
| #define FLASH_JWTCODE_SECTOR      (109)
 | ||
| #define FLASH_JWTCODE_SECTOR_NUM  (9)
 | ||
| #define FLASH_SCHEME_SECTOR       (118)
 | ||
| #define FLASH_SCHEME_SECTOR_NUM   (6)
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| typedef struct{
 | ||
|   void *mutex;
 | ||
| }self_def;
 | ||
| 
 | ||
| static self_def g_self;
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| typedef struct{
 | ||
|   uint32_t *addr;
 | ||
|   uint32_t sector;
 | ||
| }flash_item;
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| #define FLASH_CLEAR_FLAG()  \
 | ||
|   FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| // 擦除指定扇区,返回0成功,-1失败
 | ||
| static int flash_erase(uint32_t sector)
 | ||
| {
 | ||
|   self_def *s=&g_self;
 | ||
|   FLASH_Status ret;
 | ||
|   if(s->mutex==0){
 | ||
|     s->mutex=rt_mutex_create("flash_mutex",RT_IPC_FLAG_FIFO);
 | ||
|   }
 | ||
|   rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
 | ||
|   //irq_disable();
 | ||
|   FLASH_Unlock();
 | ||
|   FLASH_CLEAR_FLAG();
 | ||
|   // 对于f103 2048byte为一个扇区,这里把扇区地址转化为flash地址
 | ||
|   ret=FLASH_ErasePage(FLASH_BASE+ sector*2048);
 | ||
|   //FLASH_Lock(); 	
 | ||
|   //irq_enable();
 | ||
|   rt_mutex_release(s->mutex);
 | ||
|   if(ret!=FLASH_COMPLETE)
 | ||
|   {
 | ||
|     DBG_WARN("flash earse failed.ret=%d",ret);
 | ||
|     return -1;
 | ||
|   }else{
 | ||
|     DBG_LOG("flash earse success.ret=%d",ret);
 | ||
|     return 0;
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| // 擦除指定地址
 | ||
| int flash_erase_addr(uint32_t addr)
 | ||
| {
 | ||
|   addr=addr-FLASH_BASE;
 | ||
|   return flash_erase(addr/2048);
 | ||
| }
 | ||
| 
 | ||
| // 操作开始
 | ||
| int flash_operate_start(void)
 | ||
| {
 | ||
|   FLASH_Status state;
 | ||
|   int ret=0;
 | ||
|   self_def *s=&g_self;
 | ||
|   #ifdef RT_THREAD
 | ||
|   param_check(s->mutex);
 | ||
|   #endif
 | ||
|   rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
 | ||
|   FLASH_Unlock();
 | ||
|   FLASH_CLEAR_FLAG();
 | ||
|   rt_mutex_release(s->mutex);
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // 操作结束
 | ||
| int flash_operate_end(void)
 | ||
| {
 | ||
|   FLASH_Status state;
 | ||
|   int ret=0;
 | ||
|   self_def *s=&g_self;
 | ||
|   #ifdef RT_THREAD
 | ||
|   param_check(s->mutex);
 | ||
|   #endif
 | ||
|   rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
 | ||
|   FLASH_Lock();
 | ||
|   rt_mutex_release(s->mutex);
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| // boot区
 | ||
| int flash_erase_boot(void)
 | ||
| {
 | ||
|   int ret;
 | ||
|   for(int i=0;i<FLASH_BOOT_SECTOR_NUM;i++){
 | ||
|     ret=flash_erase(FLASH_BOOT_SECTOR+i);
 | ||
|     if(ret!=0) return -1;
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| // 参数区2K
 | ||
| int flash_erase_param(void)
 | ||
| {
 | ||
|   int ret;
 | ||
|   for(int i=0;i<FLASH_PARAM_SECTOR_NUM;i++){
 | ||
|     ret=flash_erase(FLASH_PARAM_SECTOR+i);
 | ||
|     if(ret!=0) return -1;
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| //程序区1 100K
 | ||
| int flash_erase_app1(void)
 | ||
| {
 | ||
|   int ret;
 | ||
|   for(int i=0;i<FLASH_APP_SECTOR_NUM;i++){
 | ||
|     ret=flash_erase(FLASH_APP_SECTOR+i);
 | ||
|     if(ret!=0) return -1;
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| //程序区2 100K 对于f103 程序区2与小板程序区相同
 | ||
| int flash_erase_app2(void)
 | ||
| {
 | ||
|   int ret;
 | ||
|   for(int i=0;i<FLASH_BUFF_SECTOR_NUM;i++){
 | ||
|     ret=flash_erase(FLASH_BUFF_SECTOR+i);
 | ||
|     if(ret!=0) return -1;
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| //小板程序区 100K
 | ||
| int flash_erase_slave(void)
 | ||
| {
 | ||
|   int ret;
 | ||
|   for(int i=0;i<FLASH_BUFF_SECTOR_NUM;i++){
 | ||
|     ret=flash_erase(FLASH_BUFF_SECTOR+i);
 | ||
|     if(ret!=0) return -1;
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| //方案区 6K
 | ||
| int flash_erase_scheme(void)
 | ||
| {
 | ||
|   int ret;
 | ||
|   for(int i=0;i<FLASH_SCHEME_SECTOR_NUM;i++){
 | ||
|     ret=flash_erase(FLASH_SCHEME_SECTOR+i);
 | ||
|     if(ret!=0) return -1;
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| //脚本区 
 | ||
| int flash_erase_lua(void)
 | ||
| {
 | ||
|   int ret;
 | ||
|   return -1;
 | ||
| }
 | ||
| 
 | ||
| // 模块程序区 16K
 | ||
| int flash_erase_jwtcode(void)
 | ||
| {
 | ||
|   int ret;
 | ||
|   for(int i=0;i<FLASH_JWTCODE_SECTOR_NUM;i++){
 | ||
|     ret=flash_erase(FLASH_JWTCODE_SECTOR+i);
 | ||
|     if(ret!=0) return -1;
 | ||
|   }
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| uint32_t *flash_get_param(void)
 | ||
| {
 | ||
|   return (void *)(FLASH_BASE+FLASH_SECTOR_SIZE*FLASH_PARAM_SECTOR);
 | ||
| }
 | ||
| 
 | ||
| //uint32_t *flash_get_app1(void)
 | ||
| //{
 | ||
| //  return (void *)0x08020000;
 | ||
| //}
 | ||
| 
 | ||
| uint32_t *flash_get_app2(void)
 | ||
| {
 | ||
|   return (void *)(FLASH_BASE+FLASH_SECTOR_SIZE*FLASH_BUFF_SECTOR);
 | ||
| }
 | ||
| 
 | ||
| uint32_t *flash_get_slave(void)
 | ||
| {
 | ||
|   return (void *)(FLASH_BASE+FLASH_SECTOR_SIZE*FLASH_BUFF_SECTOR);
 | ||
| }
 | ||
| 
 | ||
| uint32_t *flash_get_scheme(void)
 | ||
| {
 | ||
|   return (void *)(FLASH_BASE+FLASH_SECTOR_SIZE*FLASH_SCHEME_SECTOR);
 | ||
| }
 | ||
| uint32_t *flash_get_jwtcode(void)
 | ||
| {
 | ||
|   return (void *)(FLASH_BASE+FLASH_SECTOR_SIZE*FLASH_JWTCODE_SECTOR);
 | ||
| }
 | ||
| 
 | ||
| uint32_t *flash_get_lua(void)
 | ||
| {
 | ||
|   return (void *)0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| int flash_write(uint8_t *addr,const uint8_t *data,int len)
 | ||
| {
 | ||
|   FLASH_Status state;
 | ||
|   int ret=0;
 | ||
|   self_def *s=&g_self;
 | ||
|   if((uint32_t)data%4)
 | ||
|   {
 | ||
|     DBG_WARN("write addr err.");
 | ||
|     return -1;
 | ||
|   }
 | ||
|   uint32_t *t=(uint32_t *)data;
 | ||
|   uint32_t flash_addr=(uint32_t)addr;
 | ||
|   #ifdef RT_THREAD
 | ||
|   param_check(s->mutex);
 | ||
|   #endif
 | ||
|   rt_mutex_take(s->mutex,RT_WAITING_FOREVER);
 | ||
|   
 | ||
|   //DBG_LOG("write flash addr=%08x",flash_addr);
 | ||
|   len+=3;// len不是4字节对齐时强行增加到4字节
 | ||
|   //FLASH_Unlock();
 | ||
|   for(int i=0;i<len/4;i++)
 | ||
|   {
 | ||
|     //irq_disable();
 | ||
|     //state=FLASH_ProgramByte((uint32_t)addr,data[i]);
 | ||
|     state=FLASH_ProgramWord(flash_addr,t[i]);
 | ||
|     //FLASH_CLEAR_FLAG();
 | ||
|     //irq_enable();
 | ||
|     if(state!=FLASH_COMPLETE)
 | ||
|     {
 | ||
|       DBG_WARN("flash write failed.ret=%d",state);
 | ||
|       DBG_WARN("addr=%08X",flash_addr);
 | ||
|       ret=-1;
 | ||
|       break;
 | ||
|     }
 | ||
|     flash_addr+=4;
 | ||
|   }
 | ||
|   //FLASH_Lock(); 
 | ||
|   if(memcmp(addr,data,(len/4)*4)!=0)
 | ||
|   {
 | ||
|     DBG_WARN("addr=%08x write/read data not equate.",addr);
 | ||
|     ret=-2;
 | ||
|   }
 | ||
|   rt_mutex_release(s->mutex);
 | ||
|   return ret;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // 写数据自动擦除
 | ||
| int flash_write_with_erase(uint8_t *addr,const uint8_t *data,int len)
 | ||
| {
 | ||
|   int ret=0;
 | ||
|   uint32_t addr_u32=(uint32_t)addr;
 | ||
|   if((addr_u32%FLASH_SECTOR_SIZE)==0){
 | ||
|     ret=flash_erase(addr_u32/FLASH_SECTOR_SIZE);
 | ||
|     flash_operate_end();
 | ||
|     if(ret!=0) return -1;
 | ||
|   }else{
 | ||
|     flash_operate_start();
 | ||
|   }
 | ||
|   ret=flash_write(addr,data,len);
 | ||
|   flash_operate_end();
 | ||
|   if(ret!=0) return -1;
 | ||
|   return 0;
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| uint8_t *flash_get_rom(rom_head **head)
 | ||
| {
 | ||
|   uint8_t *src=(uint8_t *)flash_get_app2();
 | ||
|   flash_file *file=(flash_file *)flash_get_app2();
 | ||
|   rom_head *h=(rom_head *)(src+FLASH_FILE_HEAD_SIZE);
 | ||
|   uint8_t *rom=src+ROM_HEAD_SIZE+FLASH_FILE_HEAD_SIZE;
 | ||
|   if(file->file_size==0xffffffff){
 | ||
|     return 0;
 | ||
|   }
 | ||
|   if(head) *head=h;
 | ||
|   return rom;
 | ||
| }
 | ||
| 
 | ||
| int flash_updata_app(uint8_t *rom,uint32_t size)
 | ||
| {
 | ||
|   uint8_t *dst=(uint8_t *)0x08004000;
 | ||
|   flash_erase_app1();
 | ||
|   return flash_write(dst,rom,size);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| int flash_updata_boot(uint8_t *rom,uint32_t size)
 | ||
| {
 | ||
|   uint8_t *dst=(uint8_t *)0x08000000;
 | ||
|   flash_erase_boot();
 | ||
|   return flash_write(dst,rom,size);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| // 保存参数
 | ||
| int flash_save_param(sys_param_def *par)
 | ||
| {
 | ||
|   uint8_t *dst=(uint8_t *)flash_get_param();
 | ||
|   uint8_t *src=(uint8_t *)par;
 | ||
|   int size=sizeof(sys_param_def);
 | ||
|   flash_erase_param();
 | ||
|   return flash_write(dst,src,size);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| const sys_param_def *sys_param(void)
 | ||
| {
 | ||
|   return (sys_param_def *)flash_get_param();
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| const scheme_def *check_scheme(void)
 | ||
| {
 | ||
|   uint8_t *d=(uint8_t *)flash_get_scheme();
 | ||
|   return (scheme_def *)(d+FLASH_FILE_HEAD_SIZE);
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | 
