Browse Source

【主线待合】解决上一条中所述的日志问题

paint_robot_new-v1.5
Lizongdi 2 weeks ago
parent
commit
8a38870ca6
  1. 8
      bspMCU/include/w25qxx.h
  2. 57
      bspMCU/w25qxx.c
  3. 18
      library/common/rd_stdio.c
  4. 2
      library/littlefs/include/lfs.h
  5. 36
      library/littlefs/lfs_flashbd.c
  6. 3
      library/log/elog_file.c

8
bspMCU/include/w25qxx.h

@ -79,12 +79,12 @@ void W25QXX_4ByteAddr_Enable(void);
void W25QXX_Write_SR(uint8_t regno, uint8_t sr);
void W25QXX_Write_Enable(void);
void W25QXX_Write_Disable(void);
void W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
void W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead);
int W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
int W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
int W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead);
void W25QXX_Write(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
void W25QXX_Erase_Chip(void);
void W25QXX_Erase_Sector(uint32_t Dst_Addr);
int W25QXX_Erase_Sector(uint32_t Dst_Addr);
void W25QXX_Wait_Busy(void);
void W25QXX_PowerDown(void);
void W25QXX_WAKEUP(void);

57
bspMCU/w25qxx.c

@ -221,14 +221,14 @@ void W25QXX_Write_Disable(void)
W25QXX_CommandOnly(W25X_WriteDisable);
}
/** 读取指定地址、指定长度的数据(1-Line 标准读 0x03) */
void W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
/** 读取指定地址、指定长度的数据(1-Line 标准读 0x03),返回 0 成功 / -1 失败 */
int W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
QSPI_CommandTypeDef cmd = {0};
if (NumByteToRead == 0)
{
return;
return 0;
}
W25QXX_Command_Base(&cmd);
@ -241,19 +241,23 @@ void W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
if (HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return;
return -1;
}
if (HAL_QSPI_Receive(&hqspi, pBuffer, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return -1;
}
HAL_QSPI_Receive(&hqspi, pBuffer, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
return 0;
}
/** 页编程(≤256 字节,不跨页) */
void W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
/** 页编程(≤256 字节,不跨页),返回 0 成功 / -1 失败 */
int W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
QSPI_CommandTypeDef cmd = {0};
if (NumByteToWrite == 0)
{
return;
return 0;
}
W25QXX_Write_Enable();
@ -268,14 +272,18 @@ void W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToW
if (HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return;
return -1;
}
if (HAL_QSPI_Transmit(&hqspi, pBuffer, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return -1;
}
HAL_QSPI_Transmit(&hqspi, pBuffer, HAL_QSPI_TIMEOUT_DEFAULT_VALUE);
W25QXX_Wait_Busy();
return 0;
}
/** 无校验写入:自动跨页,不检查/不擦除(调用方须保证目标区已擦除) */
void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
/** 无校验写入:自动跨页,不检查/不擦除(调用方须保证目标区已擦除),返回 0 成功 / -1 失败 */
int W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
uint16_t pageremain = W25QXX_PAGE_SIZE - (WriteAddr % W25QXX_PAGE_SIZE); /* 本页剩余 */
@ -286,7 +294,10 @@ void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByte
while (1)
{
W25QXX_Write_Page(pBuffer, WriteAddr, pageremain);
if (W25QXX_Write_Page(pBuffer, WriteAddr, pageremain) != 0)
{
return -1;
}
if (NumByteToWrite == pageremain)
{
@ -308,6 +319,7 @@ void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByte
}
}
}
return 0;
}
/** 带擦除的写入:自动跨页跨扇区,非 0xFF 区域先擦除再写 */
@ -387,8 +399,8 @@ void W25QXX_Erase_Chip(void)
W25QXX_WaitBusy_Timeout(250000U);
}
/** 扇区擦除,入参为扇区号(内部 ×4096 得到字节地址) */
void W25QXX_Erase_Sector(uint32_t Dst_Addr)
/** 扇区擦除,入参为扇区号(内部 ×4096 得到字节地址),返回 0 成功 / -1 失败 */
int W25QXX_Erase_Sector(uint32_t Dst_Addr)
{
uint32_t byte_addr = Dst_Addr * W25QXX_SECTOR_SIZE;
QSPI_CommandTypeDef cmd = {0};
@ -405,9 +417,10 @@ void W25QXX_Erase_Sector(uint32_t Dst_Addr)
if (HAL_QSPI_Command(&hqspi, &cmd, HAL_QSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
return;
return -1;
}
W25QXX_Wait_Busy();
return 0;
}
/** 等待 Flash 空闲:自动轮询状态寄存器 bit0(BUSY) 直至为 0 */
@ -541,7 +554,7 @@ uint16_t W25QXX_ReadID(void)
return Temp;
}
void W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
int W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
uint16_t i;
W25QXX_CS(0);
@ -558,9 +571,10 @@ void W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
pBuffer[i] = SPI2_ReadWriteByte(0xFF);
}
W25QXX_CS(1);
return 0;
}
void W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
int W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
uint16_t i;
W25QXX_Write_Enable();
@ -579,9 +593,10 @@ void W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToW
}
W25QXX_CS(1);
W25QXX_Wait_Busy();
return 0;
}
void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
int W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
uint16_t pageremain;
pageremain = 256 - WriteAddr % 256;
@ -611,6 +626,7 @@ void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByte
}
}
}
return 0;
}
void W25QXX_Write(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
@ -686,7 +702,7 @@ void W25QXX_Erase_Chip(void)
W25QXX_Wait_Busy();
}
void W25QXX_Erase_Sector(uint32_t Dst_Addr)
int W25QXX_Erase_Sector(uint32_t Dst_Addr)
{
Dst_Addr *= 4096;
W25QXX_Write_Enable();
@ -702,6 +718,7 @@ void W25QXX_Erase_Sector(uint32_t Dst_Addr)
SPI2_ReadWriteByte((uint8_t)Dst_Addr);
W25QXX_CS(1);
W25QXX_Wait_Busy();
return 0;
}
void W25QXX_Wait_Busy(void)

18
library/common/rd_stdio.c

@ -81,10 +81,22 @@ WEAK void *Rd_Fopen(const char *path, const char *mode)
#else
const char *p = path;
lfs_file_t *file = RD_MALLOC(sizeof(lfs_file_t));
int flags;
int flags = 0;
if (strlen(path) >= 2 && path[1] == ':') p = path + 2;
if (strchr(mode, 'r') != NULL) flags = LFS_O_RDONLY;
else flags = LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC;
/* 按 mode 首字符解析:r 只读 / w 写并截断 / a 追加;
带 '+' 则为读写。避免 "a+" 被误判为 TRUNC 清空文件 */
if (mode[0] == 'r') {
flags = LFS_O_RDONLY;
if (strchr(mode, '+')) flags = LFS_O_RDWR;
} else if (mode[0] == 'w') {
flags = LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC;
if (strchr(mode, '+')) flags = LFS_O_RDWR | LFS_O_CREAT | LFS_O_TRUNC;
} else if (mode[0] == 'a') {
flags = LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND;
if (strchr(mode, '+')) flags = LFS_O_RDWR | LFS_O_CREAT | LFS_O_APPEND;
} else {
flags = LFS_O_RDONLY; /* 未知 mode 默认只读 */
}
int err = lfs_file_open(&g_lfs, file, p, flags);
if(err) return NULL;
else return (void *)file;

2
library/littlefs/include/lfs.h

@ -32,7 +32,7 @@ extern "C"
#define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16))
#define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >> 0))
#define LFS_THREADSAFE
/// Definitions ///
// Type definitions

36
library/littlefs/lfs_flashbd.c

@ -10,6 +10,9 @@
#include "lfs_flashbd.h"
#include "../../bspMCU/include/w25qxx.h"
#include <string.h>
#include "rd_thread.h"
static rd_mutex_t g_lfs_mutex;
int lfs_flashbd_create(const struct lfs_config *cfg,
const struct lfs_flashbd_config *bdcfg) {
@ -47,7 +50,10 @@ int lfs_flashbd_read(const struct lfs_config *cfg, lfs_block_t block,
+ (uint32_t)block * cfg->block_size
+ (uint32_t)off;
W25QXX_Read((uint8_t *)buffer, addr, (uint16_t)size);
if (W25QXX_Read((uint8_t *)buffer, addr, (uint16_t)size) != 0)
{
return LFS_ERR_IO;
}
return LFS_ERR_OK;
}
@ -68,7 +74,10 @@ int lfs_flashbd_prog(const struct lfs_config *cfg, lfs_block_t block,
* 但该函数只读取 buffer 内容,不会修改,故安全地去除 const。
* littleFS 保证写入前块已擦除,因此无需带擦除的 W25QXX_Write。
*/
W25QXX_Write_NoCheck((uint8_t *)(uintptr_t)buffer, addr, (uint16_t)size);
if (W25QXX_Write_NoCheck((uint8_t *)(uintptr_t)buffer, addr, (uint16_t)size) != 0)
{
return LFS_ERR_IO;
}
return LFS_ERR_OK;
}
@ -85,7 +94,10 @@ int lfs_flashbd_erase(const struct lfs_config *cfg, lfs_block_t block) {
* W25QXX_Erase_Sector 的参数是扇区号(内部会乘以 4096),
* 所以传入字节地址除以扇区大小。
*/
W25QXX_Erase_Sector(addr / LFS_FLASHBD_SECTOR_SIZE);
if (W25QXX_Erase_Sector(addr / LFS_FLASHBD_SECTOR_SIZE) != 0)
{
return LFS_ERR_IO;
}
return LFS_ERR_OK;
}
@ -96,6 +108,20 @@ int lfs_flashbd_sync(const struct lfs_config *cfg) {
return LFS_ERR_OK;
}
int lfs_flashbd_lock(const struct lfs_config *cfg)
{
(void)cfg;
Rd_MutexLock(&g_lfs_mutex, __func__, NULL);
return LFS_ERR_OK;
}
int lfs_flashbd_unlock(const struct lfs_config *cfg)
{
(void)cfg;
Rd_MutexUnlock(&g_lfs_mutex, __func__, NULL);
return LFS_ERR_OK;
}
void lfs_flashbd_default_config(
struct lfs_config *cfg,
lfs_flashbd_t *bd,
@ -113,12 +139,16 @@ void lfs_flashbd_default_config(
bd->cfg = bdcfg;
(void)Rd_MutexInit(&g_lfs_mutex);
/* 回调函数 */
cfg->context = bd;
cfg->read = lfs_flashbd_read;
cfg->prog = lfs_flashbd_prog;
cfg->erase = lfs_flashbd_erase;
cfg->sync = lfs_flashbd_sync;
cfg->lock = lfs_flashbd_lock;
cfg->unlock = lfs_flashbd_unlock;
/* 块设备参数 */
cfg->read_size = 256; /* W25QXX 页大小,读取可任意长度 */

3
library/log/elog_file.c

@ -81,7 +81,8 @@ static bool elog_file_rotate(void)
RD_MEMCPY(oldpath, local_cfg.name, base);
RD_MEMCPY(newpath, local_cfg.name, base);
fclose(fp);
Rd_Mclose(fp);
fp = NULL;
for (n = local_cfg.max_rotate - 1; n >= 0; --n) {
RD_SNPRINTF(oldpath + base, SUFFIX_LEN, n ? ".%d" : "", n - 1);

Loading…
Cancel
Save