文章目录
【相关文章导航】
[FlashDB]基于GD32纯代码裸机移植FlashDB数据库——一、介绍
[FlashDB]基于GD32纯代码裸机移植FlashDB数据库——二、移植前准备
[FlashDB]基于GD32纯代码裸机移植FlashDB数据库——三、移植SFUD
[FlashDB]基于GD32纯代码裸机移植FlashDB数据库——四、移植Fal
[FlashDB]基于GD32纯代码裸机移植FlashDB数据库——五、移植FlashDB
五、移植SFUD
5.1 移植步骤
- 移动源代码
- 在Keil的文件组中添加源文件
- 修改
sfud_flash_def.h
文件 - 修改
sfud_cfg.h
文件 - 修改
sfud_port.c
文件 - 测试SFUD
5.2 移动源码文件
移动源码文件到当前工程相应文件夹下,如下图:
5.3 在Keil的文件组中添加源文件
5.4 修改 sfud_flash_def.h 文件
当前使用Flash为GD25Q32,sfud_flash_def.h
文件的宏定义SFUD_FLASH_CHIP_TABLE
中无此型号Flash芯片,在 line139添加此芯片型号。
如下图:
代码如下:
{"GD25Q32B", SFUD_MF_ID_GIGADEVICE, 0x40, 0x15, 4L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \
5.5 修改 sfud_cfg.h 文件
定义当前flash标识符。如下图:
代码如下:
#ifndef _SFUD_CFG_H_
#define _SFUD_CFG_H_
#define SFUD_DEBUG_MODE
#define SFUD_USING_SFDP
#define SFUD_USING_FLASH_INFO_TABLE
enum {
SFUD_GD25Q32_DEVICE_INDEX = 0,
};
#define SFUD_FLASH_DEVICE_TABLE \
{ \
[SFUD_GD25Q32_DEVICE_INDEX] = {.name = "GD25Q32", .spi.name = "SPI0"}, \
}
#endif /* _SFUD_CFG_H_ */
说明:
- 此处定义的标识符在后面需要使用。
5.6 修改 sfud_port.c 文件
关键修改两处:
-
实现函数
spi_write_read
,即SPI的读写函数;调用自己实现的读写函数,从头文件
bsp_flash_drv.h
引用。 -
实现函数
sfud_spi_port_init
,即SPI的初始化;调用自己实现的SPI初始化函数,从头文件
bsp_flash_drv.h
引用。
上述两个函数的实现,请参考4.6。
请参考如下代码:(原代码未删除,仅屏蔽掉了。可做参考)
#include <sfud.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
//#include <stm32f4xx_hal.h>
#include "bsp_flash_drv.h"
//typedef struct {
// SPI_TypeDef *spix;
// SPI_HandleTypeDef *spi_handle;
// GPIO_TypeDef *cs_gpiox;
// uint16_t cs_gpio_pin;
//} spi_user_data, *spi_user_data_t;
/* 用户数据 */
uint32_t SPI_userData;
static char log_buf[256];
void sfud_log_debug(const char *file, const long line, const char *format, ...);
static SPI_HandleTypeDef hspi2;
//static void spi_configuration(spi_user_data_t spi)
//{
// SPI_HandleTypeDef *spi_handle = spi->spi_handle;
// spi_handle->Instance = spi->spix;
// spi_handle->Init.Mode = SPI_MODE_MASTER;
// spi_handle->Init.Direction = SPI_DIRECTION_2LINES;
// spi_handle->Init.DataSize = SPI_DATASIZE_8BIT;
// spi_handle->TxXferSize = 8;
// spi_handle->RxXferSize = 8;
// spi_handle->Init.CLKPhase = SPI_PHASE_1EDGE;
// spi_handle->Init.CLKPolarity = SPI_POLARITY_LOW;
// spi_handle->Init.NSS = SPI_NSS_SOFT;
// spi_handle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
// spi_handle->Init.FirstBit = SPI_FIRSTBIT_MSB;
// spi_handle->Init.TIMode = SPI_TIMODE_DISABLE;
// spi_handle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
// spi_handle->State = HAL_SPI_STATE_RESET;
// HAL_SPI_Init(spi_handle);
//}
static void spi_lock(const sfud_spi *spi) {
__disable_irq();
}
static void spi_unlock(const sfud_spi *spi) {
__enable_irq();
}
/**
* SPI write data then read data
*/
static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf,
size_t read_size) {
sfud_err result = SFUD_SUCCESS;
// spi_user_data_t spi_dev = (spi_user_data_t) spi->user_data;
// HAL_StatusTypeDef state = HAL_OK;
if (write_size) {
SFUD_ASSERT(write_buf);
}
if (read_size) {
SFUD_ASSERT(read_buf);
}
// HAL_GPIO_WritePin(spi_dev->cs_gpiox, spi_dev->cs_gpio_pin, GPIO_PIN_RESET);
// if (write_size) {
// state = HAL_SPI_Transmit(spi_dev->spi_handle, (uint8_t *)write_buf, write_size, 1000);
// while (HAL_SPI_GetState(spi_dev->spi_handle) != HAL_SPI_STATE_READY);
// }
// if (state != HAL_OK) {
// goto __exit;
// }
// if (read_size) {
// memset((uint8_t *)read_buf, 0xFF, read_size);
// state = HAL_SPI_Receive(spi_dev->spi_handle, read_buf, read_size, 1000);
// while (HAL_SPI_GetState(spi_dev->spi_handle) != HAL_SPI_STATE_READY);
// }
//__exit:
// HAL_GPIO_WritePin(spi_dev->cs_gpiox, spi_dev->cs_gpio_pin, GPIO_PIN_SET);
user_spi_flash_page_write(write_buf ,write_size);
user_spi_flash_buffer_read(read_buf ,read_size);
SPI_FLASH_CS_HIGH();
return result;
}
/* about 100 microsecond delay */
static void retry_delay_100us(void) {
uint32_t delay = 120;
while(delay--);
}
//static spi_user_data spi2 = { .spix = SPI2, .cs_gpiox = GPIOB, .cs_gpio_pin = GPIO_PIN_12, .spi_handle = &hspi2};
sfud_err sfud_spi_port_init(sfud_flash *flash) {
sfud_err result = SFUD_SUCCESS;
// if (!strcmp(flash->spi.name, "SPI2"))
// {
// GPIO_InitTypeDef GPIO_Initure;
// /* SPI 外设初始化 */
// spi_configuration(&spi2);
// /* 初始化 CS 引脚 */
// GPIO_Initure.Pin = spi2.cs_gpio_pin;
// GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;
// GPIO_Initure.Pull = GPIO_PULLUP;
// GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
// HAL_GPIO_Init(spi2.cs_gpiox, &GPIO_Initure);
// HAL_GPIO_WritePin(spi2.cs_gpiox, spi2.cs_gpio_pin, GPIO_PIN_SET);
// /* 同步 Flash 移植所需的接口及数据 */
// flash->spi.wr = spi_write_read;
// flash->spi.lock = spi_lock;
// flash->spi.unlock = spi_unlock;
// flash->spi.user_data = &spi2;
// /* about 100 microsecond delay */
// flash->retry.delay = retry_delay_100us;
// /* adout 60 seconds timeout */
// flash->retry.times = 60 * 10000;
// }
switch (flash->index){
case SFUD_GD25Q32_DEVICE_INDEX:{
bsp_spi_flash_init();
/* 同步 Flash 移植所需的接口及数据 */
flash->spi.wr = spi_write_read;
flash->spi.lock = spi_lock;
flash->spi.unlock = spi_unlock;
flash->spi.user_data = &SPI_userData;
/* about 100 microsecond delay */
flash->retry.delay = retry_delay_100us;
/* adout 60 seconds timeout */
flash->retry.times = 60 * 10000;
break;
}
}
return result;
}
/**
* This function is print debug info.
*
* @param file the file which has call this function
* @param line the line number which has call this function
* @param format output format
* @param ... args
*/
void sfud_log_debug(const char *file, const long line, const char *format, ...) {
va_list args;
/* args point to the first variable parameter */
va_start(args, format);
printf("[SFUD](%s:%ld) ", file, line);
/* must use vprintf to print */
vsnprintf(log_buf, sizeof(log_buf), format, args);
printf("%s\r\n", log_buf);
va_end(args);
}
/**
* This function is print routine info.
*
* @param format output format
* @param ... args
*/
void sfud_log_info(const char *format, ...) {
va_list args;
/* args point to the first variable parameter */
va_start(args, format);
printf("[SFUD]");
/* must use vprintf to print */
vsnprintf(log_buf, sizeof(log_buf), format, args);
printf("%s\r\n", log_buf);
va_end(args);
}
至此,SFUD移植完成!!!
然后测试SFUD移植是否成功。。。
5.7 测试SFUD
-
SFUD测试函数实现:
void sfud_test(uint32_t addr, size_t size, uint8_t *data) { sfud_err result = SFUD_SUCCESS; extern sfud_flash *sfud_dev; const sfud_flash *flash = sfud_get_device(SFUD_GD25Q32_DEVICE_INDEX); size_t i; /* prepare write data */ for (i = 0; i < size; i++) { data[i] = i; } /* erase test */ result = sfud_erase(flash, addr, size); if (result == SFUD_SUCCESS) { printf("Erase the %s flash data finish. Start from 0x%08X, size is %zu.\r\n", flash->name, addr, size); } else { printf("Erase the %s flash data failed.\r\n", flash->name); return; } /* write test */ result = sfud_write(flash, addr, size, data); if (result == SFUD_SUCCESS) { printf("Write the %s flash data finish. Start from 0x%08X, size is %zu.\r\n", flash->name, addr, size); } else { printf("Write the %s flash data failed.\r\n", flash->name); return; } /* read test */ result = sfud_read(flash, addr, size, data); if (result == SFUD_SUCCESS) { printf("Read the %s flash data success. Start from 0x%08X, size is %zu. The data is:\r\n", flash->name, addr, size); printf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n"); for (i = 0; i < size; i++) { if (i % 16 == 0) { printf("[%08X] ", addr + i); } printf("%02X ", data[i]); if (((i + 1) % 16 == 0) || i == size - 1) { printf("\r\n"); } } printf("\r\n"); } else { printf("Read the %s flash data failed.\r\n", flash->name); } /* data check */ for (i = 0; i < size; i++) { if (data[i] != i % 256) { printf("Read and check write data has an error. Write the %s flash data failed.\r\n", flash->name); break; } } if (i == size) { printf("The %s flash test is success.\r\n", flash->name); } }
-
测试,主函数代码如下:
#include "sfud.h" #define SFUD_DEMO_TEST_BUFFER_SIZE 1024 static uint8_t sfud_demo_test_buf[SFUD_DEMO_TEST_BUFFER_SIZE]; int main(void) { systick_config(); led_init(); gd_eval_com_init(EVAL_COM); //初始化串口1 sfud_init(); //SFUD初始化 sfud_test(0, sizeof(sfud_demo_test_buf), sfud_demo_test_buf); while(1) { printf("测试成功!!!"); led_flash(5); } }
-
测试结果如下:
打印结果提示,Flash初始化成功! Flash测试成功!
至此,SFUD正常工作,移植完成。
接下来进行Fal移植。。。