2023-06-10 11:52:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "rtthread.h"
|
2023-09-09 17:27:06 +08:00
|
|
|
|
#include "stm32f10x.h"
|
2023-06-10 11:52:00 +08:00
|
|
|
|
#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
|
|
|
|
|
|
2023-09-09 17:27:06 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
bootloader 0~7
|
|
|
|
|
app 8~57
|
|
|
|
|
buff 58~107
|
|
|
|
|
params 108
|
|
|
|
|
scheme 109~110
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
#define FLASH_SECTOR_SIZE 2048
|
2023-10-12 23:37:12 +08:00
|
|
|
|
#define FLASH_BOOT_SECTOR (0)
|
|
|
|
|
#define FLASH_BOOT_SECTOR_NUM (8)
|
2023-09-09 17:27:06 +08:00
|
|
|
|
#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)
|
2023-10-09 18:12:00 +08:00
|
|
|
|
#define FLASH_JWTCODE_SECTOR (109)
|
2023-10-07 18:15:52 +08:00
|
|
|
|
#define FLASH_JWTCODE_SECTOR_NUM (9)
|
2023-10-09 18:12:00 +08:00
|
|
|
|
#define FLASH_SCHEME_SECTOR (118)
|
|
|
|
|
#define FLASH_SCHEME_SECTOR_NUM (6)
|
2023-09-09 17:27:06 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-06-10 11:52:00 +08:00
|
|
|
|
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() \
|
2023-09-09 17:27:06 +08:00
|
|
|
|
FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
|
2023-06-10 11:52:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 擦除指定扇区,返回0成功,-1失败
|
2023-10-07 18:15:52 +08:00
|
|
|
|
static int flash_erase(uint32_t sector)
|
2023-06-10 11:52:00 +08:00
|
|
|
|
{
|
|
|
|
|
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);
|
2023-10-08 18:27:10 +08:00
|
|
|
|
//irq_disable();
|
2023-06-10 11:52:00 +08:00
|
|
|
|
FLASH_Unlock();
|
|
|
|
|
FLASH_CLEAR_FLAG();
|
2023-09-09 17:27:06 +08:00
|
|
|
|
// 对于f103 2048byte为一个扇区,这里把扇区地址转化为flash地址
|
2023-10-08 18:27:10 +08:00
|
|
|
|
ret=FLASH_ErasePage(FLASH_BASE+ sector*2048);
|
|
|
|
|
//FLASH_Lock();
|
|
|
|
|
//irq_enable();
|
2023-06-10 11:52:00 +08:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-11 18:10:06 +08:00
|
|
|
|
// 擦除指定地址
|
|
|
|
|
int flash_erase_addr(uint32_t addr)
|
|
|
|
|
{
|
|
|
|
|
addr=addr-FLASH_BASE;
|
|
|
|
|
return flash_erase(addr/2048);
|
|
|
|
|
}
|
2023-10-07 18:15:52 +08:00
|
|
|
|
|
|
|
|
|
// 操作开始
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-06-10 11:52:00 +08:00
|
|
|
|
// 操作结束
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-12 23:37:12 +08:00
|
|
|
|
// 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;
|
|
|
|
|
}
|
2023-06-10 11:52:00 +08:00
|
|
|
|
|
2023-09-09 17:27:06 +08:00
|
|
|
|
// 参数区2K
|
2023-06-10 11:52:00 +08:00
|
|
|
|
int flash_erase_param(void)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
2023-09-09 17:27:06 +08:00
|
|
|
|
for(int i=0;i<FLASH_PARAM_SECTOR_NUM;i++){
|
|
|
|
|
ret=flash_erase(FLASH_PARAM_SECTOR+i);
|
|
|
|
|
if(ret!=0) return -1;
|
|
|
|
|
}
|
2023-06-10 11:52:00 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2023-09-09 17:27:06 +08:00
|
|
|
|
//程序区1 100K
|
2023-06-10 11:52:00 +08:00
|
|
|
|
int flash_erase_app1(void)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
2023-09-09 17:27:06 +08:00
|
|
|
|
for(int i=0;i<FLASH_APP_SECTOR_NUM;i++){
|
|
|
|
|
ret=flash_erase(FLASH_APP_SECTOR+i);
|
|
|
|
|
if(ret!=0) return -1;
|
|
|
|
|
}
|
2023-06-10 11:52:00 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2023-09-09 17:27:06 +08:00
|
|
|
|
//程序区2 100K 对于f103 程序区2与小板程序区相同
|
2023-06-10 11:52:00 +08:00
|
|
|
|
int flash_erase_app2(void)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
2023-09-09 17:27:06 +08:00
|
|
|
|
for(int i=0;i<FLASH_BUFF_SECTOR_NUM;i++){
|
|
|
|
|
ret=flash_erase(FLASH_BUFF_SECTOR+i);
|
|
|
|
|
if(ret!=0) return -1;
|
|
|
|
|
}
|
2023-06-10 11:52:00 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2023-09-09 17:27:06 +08:00
|
|
|
|
//小板程序区 100K
|
2023-06-10 11:52:00 +08:00
|
|
|
|
int flash_erase_slave(void)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
2023-09-09 17:27:06 +08:00
|
|
|
|
for(int i=0;i<FLASH_BUFF_SECTOR_NUM;i++){
|
|
|
|
|
ret=flash_erase(FLASH_BUFF_SECTOR+i);
|
|
|
|
|
if(ret!=0) return -1;
|
|
|
|
|
}
|
2023-06-10 11:52:00 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2023-10-07 18:15:52 +08:00
|
|
|
|
//方案区 6K
|
2023-06-10 11:52:00 +08:00
|
|
|
|
int flash_erase_scheme(void)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
2023-09-09 17:27:06 +08:00
|
|
|
|
for(int i=0;i<FLASH_SCHEME_SECTOR_NUM;i++){
|
|
|
|
|
ret=flash_erase(FLASH_SCHEME_SECTOR+i);
|
|
|
|
|
if(ret!=0) return -1;
|
|
|
|
|
}
|
2023-06-10 11:52:00 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2023-09-09 17:27:06 +08:00
|
|
|
|
//脚本区
|
2023-06-10 11:52:00 +08:00
|
|
|
|
int flash_erase_lua(void)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
2023-09-09 17:27:06 +08:00
|
|
|
|
return -1;
|
2023-06-10 11:52:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-07 18:15:52 +08:00
|
|
|
|
// 模块程序区 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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-10 11:52:00 +08:00
|
|
|
|
|
|
|
|
|
uint32_t *flash_get_param(void)
|
|
|
|
|
{
|
2023-09-09 17:27:06 +08:00
|
|
|
|
return (void *)(FLASH_BASE+FLASH_SECTOR_SIZE*FLASH_PARAM_SECTOR);
|
2023-06-10 11:52:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//uint32_t *flash_get_app1(void)
|
|
|
|
|
//{
|
|
|
|
|
// return (void *)0x08020000;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
uint32_t *flash_get_app2(void)
|
|
|
|
|
{
|
2023-09-09 17:27:06 +08:00
|
|
|
|
return (void *)(FLASH_BASE+FLASH_SECTOR_SIZE*FLASH_BUFF_SECTOR);
|
2023-06-10 11:52:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t *flash_get_slave(void)
|
|
|
|
|
{
|
2023-09-09 17:27:06 +08:00
|
|
|
|
return (void *)(FLASH_BASE+FLASH_SECTOR_SIZE*FLASH_BUFF_SECTOR);
|
2023-06-10 11:52:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t *flash_get_scheme(void)
|
|
|
|
|
{
|
2023-09-09 17:27:06 +08:00
|
|
|
|
return (void *)(FLASH_BASE+FLASH_SECTOR_SIZE*FLASH_SCHEME_SECTOR);
|
2023-06-10 11:52:00 +08:00
|
|
|
|
}
|
2023-10-07 18:15:52 +08:00
|
|
|
|
uint32_t *flash_get_jwtcode(void)
|
|
|
|
|
{
|
|
|
|
|
return (void *)(FLASH_BASE+FLASH_SECTOR_SIZE*FLASH_JWTCODE_SECTOR);
|
|
|
|
|
}
|
2023-06-10 11:52:00 +08:00
|
|
|
|
|
|
|
|
|
uint32_t *flash_get_lua(void)
|
|
|
|
|
{
|
2023-09-09 17:27:06 +08:00
|
|
|
|
return (void *)0;
|
2023-06-10 11:52:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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.");
|
2023-11-03 18:15:01 +08:00
|
|
|
|
return 1;
|
2023-06-10 11:52:00 +08:00
|
|
|
|
}
|
|
|
|
|
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字节
|
2023-10-08 18:27:10 +08:00
|
|
|
|
//FLASH_Unlock();
|
2023-06-10 11:52:00 +08:00
|
|
|
|
for(int i=0;i<len/4;i++)
|
|
|
|
|
{
|
2023-10-08 18:27:10 +08:00
|
|
|
|
//irq_disable();
|
2023-06-10 11:52:00 +08:00
|
|
|
|
//state=FLASH_ProgramByte((uint32_t)addr,data[i]);
|
|
|
|
|
state=FLASH_ProgramWord(flash_addr,t[i]);
|
2023-10-08 18:27:10 +08:00
|
|
|
|
//FLASH_CLEAR_FLAG();
|
|
|
|
|
//irq_enable();
|
2023-06-10 11:52:00 +08:00
|
|
|
|
if(state!=FLASH_COMPLETE)
|
|
|
|
|
{
|
|
|
|
|
DBG_WARN("flash write failed.ret=%d",state);
|
2023-10-08 18:27:10 +08:00
|
|
|
|
DBG_WARN("addr=%08X",flash_addr);
|
2023-11-03 18:15:01 +08:00
|
|
|
|
ret=2;
|
2023-06-10 11:52:00 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
2023-10-08 18:27:10 +08:00
|
|
|
|
flash_addr+=4;
|
2023-06-10 11:52:00 +08:00
|
|
|
|
}
|
2023-10-08 18:27:10 +08:00
|
|
|
|
//FLASH_Lock();
|
2023-06-10 11:52:00 +08:00
|
|
|
|
if(memcmp(addr,data,(len/4)*4)!=0)
|
|
|
|
|
{
|
|
|
|
|
DBG_WARN("addr=%08x write/read data not equate.",addr);
|
2023-11-03 18:15:01 +08:00
|
|
|
|
ret=3;
|
2024-01-08 18:04:05 +08:00
|
|
|
|
}else{
|
|
|
|
|
ret=0;
|
2023-06-10 11:52:00 +08:00
|
|
|
|
}
|
|
|
|
|
rt_mutex_release(s->mutex);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-10-07 18:15:52 +08:00
|
|
|
|
// 写数据自动擦除
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-10 11:52:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2023-09-09 17:27:06 +08:00
|
|
|
|
uint8_t *dst=(uint8_t *)0x08004000;
|
2023-06-10 11:52:00 +08:00
|
|
|
|
flash_erase_app1();
|
|
|
|
|
return flash_write(dst,rom,size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-10-12 23:37:12 +08:00
|
|
|
|
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);
|
|
|
|
|
}
|
2023-06-10 11:52:00 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 保存参数
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|