add:增加上位机交互框架、Flash R/W 框架
This commit is contained in:
166
Core/User/Driver/drv_flash.c
Normal file
166
Core/User/Driver/drv_flash.c
Normal file
@@ -0,0 +1,166 @@
|
||||
#include "drv_flash.h"
|
||||
|
||||
/* flash数据帧格式 */
|
||||
/* 帧头, 同时表示当前帧状态 */
|
||||
/* 整帧大小, 5~65536 */
|
||||
/* 帧类型, 用于区分不同存储数据, 0~255*/
|
||||
/* 帧数据 */
|
||||
/* 帧尾, 同时表示当前帧状态 */
|
||||
|
||||
/* 可读帧表,存放不同帧类型的第一个可读帧的地址与大小 */
|
||||
type_readable_frame_t data_form[255] = {0};
|
||||
/* 首个可写地址 */
|
||||
uint32_t writeable_addr = 0;
|
||||
uint8_t erase_flag = 0;
|
||||
|
||||
/* 地址对齐向高地址取整 */
|
||||
#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
|
||||
|
||||
uint32_t i = 0;
|
||||
|
||||
int8_t flash_manage_init(flash_manage_t *flash_manage)
|
||||
{
|
||||
uint8_t buff[4] = {0}; /* 存放帧头,帧大小,帧类型 */
|
||||
|
||||
if (flash_manage->manage_sector_num == 0 || flash_manage->sector_size == 0 || flash_manage->read_flash == 0 ||
|
||||
flash_manage->write_flash == 0 || flash_manage->erase_sector == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 遍历管理的空间以更新地址 */
|
||||
for (; i < flash_manage->manage_sector_num * flash_manage->sector_size; ) {
|
||||
/* 取出帧信息 */
|
||||
flash_manage->read_flash(buff, ALIGN_UP(flash_manage->flash_start_address + i, flash_manage->align_num), 4);
|
||||
/* 只获取该类帧类型的首个可读帧地址 */
|
||||
if (buff[0] == FLASH_READABLE_HEAD) {
|
||||
if (data_form[buff[3]].state == 0) {
|
||||
uint8_t frame_tail = 0;
|
||||
flash_manage->read_flash(&frame_tail, ALIGN_UP(flash_manage->flash_start_address + i, flash_manage->align_num) + (buff[2] << 8 | buff[1]) - 1, 1);
|
||||
if (frame_tail == FLASH_READABLE_TAIL) {
|
||||
/* 只有帧头帧尾均为可读, 才把对齐后的地址填入 */
|
||||
data_form[buff[3]].addr = ALIGN_UP(flash_manage->flash_start_address + i, flash_manage->align_num);
|
||||
/* 帧大小按小端排列 */
|
||||
data_form[buff[3]].size = buff[2] << 8 | buff[1];
|
||||
data_form[buff[3]].state = 1;
|
||||
}
|
||||
}
|
||||
i = i + ALIGN_UP(buff[2] << 8 | buff[1], flash_manage->align_num);
|
||||
} else if ((buff[0] & buff[1] & buff[2] & buff[3]) == FLASH_WRITABLE) {
|
||||
/* 遍历提前结束 */
|
||||
writeable_addr = ALIGN_UP(flash_manage->flash_start_address + i, flash_manage->align_num);
|
||||
return 1;
|
||||
} else {
|
||||
i += flash_manage->align_num;
|
||||
}
|
||||
}
|
||||
erase_flag = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void update_readable_frame(flash_manage_t *flash_manage, uint32_t addr, uint8_t frame_type)
|
||||
{
|
||||
uint8_t buff[4] = {0}; /* 存放帧头,帧大小,帧类型 */
|
||||
|
||||
/* 从当前位置遍历剩余空间 */
|
||||
for (uint32_t i = 0; i < flash_manage->manage_sector_num * flash_manage->sector_size - (addr - flash_manage->flash_start_address);) {
|
||||
/* 取出帧信息 */
|
||||
flash_manage->read_flash(buff, ALIGN_UP(addr + i, flash_manage->align_num), 4);
|
||||
/* 寻找相同类型的帧数据 */
|
||||
if (buff[0] == FLASH_READABLE_HEAD) {
|
||||
if (buff[3] == frame_type) {
|
||||
uint8_t frame_tail = 0;
|
||||
flash_manage->read_flash(&frame_tail, ALIGN_UP(addr + i, flash_manage->align_num) + (buff[2] << 8 | buff[1]) - 1, 1);
|
||||
if (frame_tail == FLASH_READABLE_TAIL) {
|
||||
/* 只有帧头帧尾均为可读, 才把地址填入 */
|
||||
data_form[buff[3]].addr = ALIGN_UP(addr + i, flash_manage->align_num);
|
||||
data_form[buff[3]].size = buff[2] << 8 | buff[1];
|
||||
data_form[buff[3]].state = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
i += ALIGN_UP(buff[2] << 8 | buff[1], flash_manage->align_num);
|
||||
} else if ((buff[0] | buff[1] | buff[2] | buff[3]) == FLASH_WRITABLE) {
|
||||
return;
|
||||
} else {
|
||||
i += flash_manage->align_num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int8_t flash_manage_read(flash_manage_t *flash_manage, uint8_t *pbuf, uint8_t frame_type)
|
||||
{
|
||||
if (flash_manage->manage_sector_num == 0 || flash_manage->sector_size == 0 || flash_manage->read_flash == 0 ||
|
||||
flash_manage->write_flash == 0 || flash_manage->erase_sector == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 可读表存在数据 */
|
||||
if (data_form[frame_type].state != 0) {
|
||||
flash_manage->read_flash(pbuf, data_form[frame_type].addr + 4, data_form[frame_type].size - 5);
|
||||
if (flash_manage->flash_read_mode == FLASH_CLEAR_MODE) {
|
||||
/* 将flash内部数据帧头尾置为无效数据 */
|
||||
uint8_t frame_head[flash_manage->align_num];
|
||||
memset(frame_head, FLASH_NULL, flash_manage->align_num);
|
||||
flash_manage->write_flash(frame_head, data_form[frame_type].addr, flash_manage->align_num);
|
||||
flash_manage->write_flash(frame_head, data_form[frame_type].addr + data_form[frame_type].size - 32, flash_manage->align_num);
|
||||
/* 将对应类型的可读表置0 */
|
||||
data_form[frame_type].state = 0;
|
||||
if (flash_manage->flash_write_mode == FLASH_NO_OVERWRITING_MODE) {
|
||||
/* flash处于覆写模式下, 可读帧是唯一的,故无需更新可读表, 而非覆写模式, 需要更新可读表 */
|
||||
update_readable_frame(flash_manage, ALIGN_UP(data_form[frame_type].addr + data_form[frame_type].size, flash_manage->align_num), frame_type);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t flash_manage_write(flash_manage_t *flash_manage, uint8_t *pbuf, uint16_t size, uint8_t frame_type)
|
||||
{
|
||||
uint8_t buff[size + 5];
|
||||
uint16_t len = 0;
|
||||
|
||||
memset(buff, 0, size + 5);
|
||||
len = size + 5;
|
||||
|
||||
if (flash_manage->manage_sector_num == 0 || flash_manage->sector_size == 0 || flash_manage->read_flash == 0 ||
|
||||
flash_manage->write_flash == 0 || flash_manage->erase_sector == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (writeable_addr > flash_manage->flash_start_address + flash_manage->manage_sector_num * flash_manage->sector_size - len || erase_flag == 1) {
|
||||
erase_flag = 0;
|
||||
flash_manage->erase_sector(flash_manage->flash_start_address);
|
||||
writeable_addr = ALIGN_UP(flash_manage->flash_start_address, flash_manage->align_num);
|
||||
/* 重置可读表 */
|
||||
for (uint8_t i = 0; i < 255; i++) {
|
||||
data_form[i].state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
buff[0] = FLASH_READABLE_HEAD;
|
||||
buff[1] = len & 0xff;
|
||||
buff[2] = len >> 8 & 0xff;
|
||||
buff[3] = frame_type;
|
||||
buff[len - 1] = FLASH_READABLE_TAIL;
|
||||
memcpy(buff + 4, pbuf, size);
|
||||
flash_manage->write_flash(buff, writeable_addr, len);
|
||||
|
||||
if (data_form[frame_type].state == 0) {
|
||||
/* 可读表为空时更新 */
|
||||
data_form[frame_type].addr = writeable_addr;
|
||||
data_form[frame_type].size = len;
|
||||
data_form[frame_type].state = 1;
|
||||
} else if (flash_manage->flash_write_mode == FLASH_OVERWRITING_MODE && data_form[frame_type].state == 1) {
|
||||
/* 将flash内部上一个相同类型的数据帧头置为无效数据 */
|
||||
uint8_t frame_head[flash_manage->align_num];
|
||||
memset(frame_head, FLASH_NULL, flash_manage->align_num);
|
||||
flash_manage->write_flash(frame_head, data_form[frame_type].addr, flash_manage->align_num);
|
||||
data_form[frame_type].addr = writeable_addr;
|
||||
data_form[frame_type].size = len;
|
||||
}
|
||||
writeable_addr = ALIGN_UP(writeable_addr + len, flash_manage->align_num);
|
||||
|
||||
return 1;
|
||||
}
|
||||
70
Core/User/Driver/drv_flash.h
Normal file
70
Core/User/Driver/drv_flash.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#ifndef __DRV_FLASH_H__
|
||||
#define __DRV_FLASH_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
enum flash_state {
|
||||
/* 数据无效帧头/帧尾,等于flash擦除后的值取反 */
|
||||
FLASH_NULL = 0x00,
|
||||
/* 数据可读帧头 */
|
||||
FLASH_READABLE_HEAD = 0xa5,
|
||||
/* 数据可读帧尾 */
|
||||
FLASH_READABLE_TAIL = 0x5a,
|
||||
/* 数据可写帧头/帧尾,等于flash擦除后的值 */
|
||||
FLASH_WRITABLE = 0xff,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
/* 不覆写模式 */
|
||||
FLASH_NO_OVERWRITING_MODE = 0x00,
|
||||
/* 覆写模式, 即写入数据后将先前同类型数据置为无效 */
|
||||
FLASH_OVERWRITING_MODE,
|
||||
/* 读取不清空模式 */
|
||||
FLASH_NO_CLEAR_MODE,
|
||||
/* 读取清空模式,即读取数据所在的flash位置0 */
|
||||
FLASH_CLEAR_MODE,
|
||||
} flash_write_read_mode_t;
|
||||
|
||||
typedef struct {
|
||||
/* 可读表标志位,表示当前是否存在可读数据 */
|
||||
uint8_t state;
|
||||
/* 可读数据大小, 包含帧头帧尾 */
|
||||
uint16_t size;
|
||||
/* 可读数据起始地址, 包含帧头 */
|
||||
uint32_t addr;
|
||||
} type_readable_frame_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* 地址对齐数, 1-2^5 */
|
||||
uint8_t align_num;
|
||||
/* flash写入模式 */
|
||||
flash_write_read_mode_t flash_write_mode;
|
||||
/* flashdu'q'b模式 */
|
||||
flash_write_read_mode_t flash_read_mode;
|
||||
/* 管理的flash起始地址,按扇区对齐 */
|
||||
uint32_t flash_start_address;
|
||||
/* 管理的flash扇区数量 */
|
||||
uint32_t manage_sector_num;
|
||||
/* flash的扇区大小 */
|
||||
uint32_t sector_size;
|
||||
|
||||
/* 开启flash */
|
||||
void (*open_flash)(void);
|
||||
/* 关闭flash */
|
||||
void (*close_flash)(void);
|
||||
/* 读flash */
|
||||
void (*read_flash)(uint8_t *pbuf, uint32_t addr, uint16_t datalen);
|
||||
/* 写flash */
|
||||
void (*write_flash)(uint8_t *pbuf, uint32_t addr, uint16_t datalen);
|
||||
/* 擦除flash */
|
||||
uint8_t (*erase_sector)(uint32_t addr);
|
||||
} flash_manage_t;
|
||||
|
||||
int8_t flash_manage_init(flash_manage_t *flash_manage);
|
||||
int8_t flash_manage_read(flash_manage_t *flash_manage, uint8_t *pbuf, uint8_t frame_type);
|
||||
int8_t flash_manage_write(flash_manage_t *flash_manage, uint8_t *pbuf, uint16_t size, uint8_t frame_type);
|
||||
|
||||
|
||||
#endif /* _FLASH_MANAGE_H__ */
|
||||
@@ -10,6 +10,7 @@
|
||||
/* Includes -------------------------------------------------------------------*/
|
||||
#include "drv_init.h"
|
||||
#include <stdint.h>
|
||||
#include "flash_config.h"
|
||||
|
||||
/* code -----------------------------------------------------------------------*/
|
||||
void send_cmd_to_air724(uint8_t *cmd, uint16_t len)
|
||||
@@ -37,6 +38,7 @@ void send_server_address_to_air724(void)
|
||||
pos = 0;
|
||||
memset(config_cmd, 0, sizeof(config_cmd));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief drv_all_Init:所有传感器、外设芯片、外部设备初始化
|
||||
*
|
||||
@@ -50,4 +52,5 @@ void send_server_address_to_air724(void)
|
||||
void drv_all_Init(void)
|
||||
{
|
||||
AIR724_RESET(); /* AIR724 复位 */
|
||||
stm_flash_init();/* 初始化flash */
|
||||
}
|
||||
|
||||
150
Core/User/Driver/flash_config.c
Normal file
150
Core/User/Driver/flash_config.c
Normal file
@@ -0,0 +1,150 @@
|
||||
#include "flash_config.h"
|
||||
#include "stm32h7xx_hal.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
void stmflash_read_data(uint8_t *pbuf, uint32_t addr, uint16_t datalen)
|
||||
{
|
||||
if (pbuf == NULL || datalen == 0) {
|
||||
return;
|
||||
}
|
||||
memcpy(pbuf, (const void *)addr, datalen);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* 写 Flash
|
||||
* 函数指针原型: void (*write_flash)(uint8_t *pbuf, uint32_t addr, uint16_t datalen)
|
||||
*
|
||||
* H743 写入规则:
|
||||
* - 每次必须写 32字节 (FLASH_TYPEPROGRAM_FLASHWORD)
|
||||
* - 写入地址必须 32字节对齐
|
||||
* - 不满 32字节的部分用 0xFF 填充
|
||||
* ============================================================ */
|
||||
void stmflash_write_data(uint8_t *pbuf, uint32_t addr, uint16_t datalen)
|
||||
{
|
||||
if (pbuf == NULL || datalen == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 地址必须32字节对齐 */
|
||||
if ((addr % 32) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* 计算对齐后的长度 */
|
||||
uint16_t aligned_len = (datalen + 31) & ~31U;
|
||||
|
||||
/* 构建对齐缓冲区, 多余部分填 0xFF */
|
||||
uint8_t buf[aligned_len];
|
||||
memset(buf, 0xFF, aligned_len);
|
||||
memcpy(buf, pbuf, datalen);
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
uint32_t address = addr;
|
||||
uint8_t *writePtr = buf;
|
||||
uint16_t remain = aligned_len;
|
||||
|
||||
while (remain >= 32)
|
||||
{
|
||||
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD,
|
||||
address,
|
||||
(uint32_t)writePtr) != HAL_OK)
|
||||
{
|
||||
/* 写入失败,退出 */
|
||||
break;
|
||||
}
|
||||
address += 32;
|
||||
writePtr += 32;
|
||||
remain -= 32;
|
||||
}
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
* 擦除 Flash Sector
|
||||
* 函数指针原型: uint8_t (*erase_sector)(uint32_t addr)
|
||||
*
|
||||
* H743 参数:
|
||||
* - Bank2, Sector0 起始地址 0x08100000
|
||||
* - 每个 Sector = 128KB
|
||||
* - VoltageRange = FLASH_VOLTAGE_RANGE_3 (2.7V ~ 3.6V)
|
||||
* ============================================================ */
|
||||
uint8_t flash_sector_erase(uint32_t addr)
|
||||
{
|
||||
FLASH_EraseInitTypeDef EraseInitStruct = {0};
|
||||
uint32_t SECTORError = 0;
|
||||
|
||||
/* 根据地址计算 Sector 编号 */
|
||||
/* Bank2: 0x08100000 ~ 0x081FFFFF, 共8个Sector, 每个128KB */
|
||||
uint32_t sector = (addr - 0x08100000) / (128 * 1024);
|
||||
|
||||
if (sector > 7) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
|
||||
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
|
||||
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
|
||||
EraseInitStruct.Banks = FLASH_BANK_2;
|
||||
EraseInitStruct.Sector = sector;
|
||||
EraseInitStruct.NbSectors = 1;
|
||||
|
||||
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
|
||||
{
|
||||
HAL_FLASH_Lock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
HAL_FLASH_Lock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
flash_manage_t stm_flash_manage = {0};
|
||||
|
||||
/* demo */
|
||||
// stm_flash_read(data[0], 1);
|
||||
// stm_flash_read(data[1], 0);
|
||||
// stm_flash_read(data[0], 1);
|
||||
// stm_flash_read(data[1], 0);
|
||||
// stm_flash_write("12345678912345678912345678912345678912345", 41, 1);
|
||||
// stm_flash_write("abcdef", 6, 0);
|
||||
// stm_flash_write("12345678912345678912345678912345678912345", 41, 1);
|
||||
// stm_flash_write("abcdef", 6, 0);
|
||||
|
||||
void stm_flash_init(void)
|
||||
{
|
||||
stm_flash_manage.align_num = 32;
|
||||
stm_flash_manage.flash_write_mode = FLASH_OVERWRITING_MODE;
|
||||
stm_flash_manage.flash_read_mode = FLASH_NO_CLEAR_MODE;
|
||||
stm_flash_manage.flash_start_address = 0x08180000;
|
||||
stm_flash_manage.manage_sector_num = 1;
|
||||
stm_flash_manage.sector_size = 128 * 1024;
|
||||
stm_flash_manage.open_flash = NULL;
|
||||
stm_flash_manage.close_flash = NULL;
|
||||
stm_flash_manage.read_flash = stmflash_read_data;
|
||||
stm_flash_manage.write_flash = stmflash_write_data;
|
||||
stm_flash_manage.erase_sector = flash_sector_erase;
|
||||
|
||||
// stm_flash_manage.open_flash();
|
||||
flash_manage_init(&stm_flash_manage);
|
||||
}
|
||||
|
||||
int8_t stm_flash_read(uint8_t *pbuf, uint8_t frame_type)
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
int8_t flag = flash_manage_read(&stm_flash_manage, pbuf, frame_type);
|
||||
taskEXIT_CRITICAL();
|
||||
return flag;
|
||||
}
|
||||
|
||||
int8_t stm_flash_write(uint8_t *pbuf, uint16_t size, uint8_t frame_type)
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
int8_t flag = flash_manage_write(&stm_flash_manage, pbuf, size, frame_type);
|
||||
taskEXIT_CRITICAL();
|
||||
return flag;
|
||||
}
|
||||
13
Core/User/Driver/flash_config.h
Normal file
13
Core/User/Driver/flash_config.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef _FLASH_CONFIG_H__
|
||||
#define _FLASH_CONFIG_H__
|
||||
|
||||
#include "drv_flash.h"
|
||||
|
||||
|
||||
void stm_flash_init(void);
|
||||
int8_t stm_flash_read(uint8_t *pbuf, uint8_t frame_type);
|
||||
int8_t stm_flash_write(uint8_t *pbuf, uint16_t size, uint8_t frame_type);
|
||||
|
||||
extern flash_manage_t stm_flash_manage; // 声明flash管理结构体
|
||||
|
||||
#endif /* _FLASH_CONFIG_H__ */
|
||||
Reference in New Issue
Block a user