Files
checker_slave/source/dev/dev_flash.c
ranchuan bcbd02a72c V2.13 使用新的can帧回复数据
解决ew自检模式 8导致小板死机的bug,自检返回值除以400,单位0.1ms
2024-01-08 18:04:05 +08:00

391 lines
7.1 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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=2;
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=3;
}else{
ret=0;
}
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);
}