当前位置: 首页 > news >正文

苏州高端做网站优舟网站建设

苏州高端做网站,优舟网站建设,狼人通知紧急页面自动升级,wordpress修改教程个人上篇文章 搭建STM32F407的SPI-Flash#xff08;基于STM32CubeMX#xff09;_小刚学長的博客-CSDN博客 主要是解决STM32CubeMX这边的配置#xff0c;对code端侧是简单介绍了下 实际项目上一般都是拿片外flash存储一些东西#xff0c;比如一些比较多的配置、参数…个人上篇文章  搭建STM32F407的SPI-Flash基于STM32CubeMX_小刚学長的博客-CSDN博客 主要是解决STM32CubeMX这边的配置对code端侧是简单介绍了下 实际项目上一般都是拿片外flash存储一些东西比如一些比较多的配置、参数偶尔修改下还有一些程序文件日志之类的。存在读写操作而nor flash是每次擦除后才可以写入也就是说你要更新内容也是要先擦除再写入新的数据往往这种操作比较麻烦最近简单的方法先把当簇内容读出来然后对相应的位置进行修改然后先擦除当前簇再写入如果更新内容存在跨簇那更麻烦点需要判断。另外还有个特点nor flash存在擦除次数上限如果超过一定次数此区域容易坏。 对于windows、linux存在文件系统文件系统就可以很好规避以上问题使用时也不用去关心、去计算这些值。对于STM32显然文件系统开销很大不太合适 那么STM32有没有轻量点库之类的答案是有的 FlashDB SFUD SPI Flash  FlashDB就是个简单版本的DB也是专门适合MCU环境而且针对Flash特点对相同簇写入次数也有优化写入均衡。FlashDB 支持kv类型数据库、也支持时间序列数据库一般也足够用了。关键还是占资源少写flash均衡这样应用者可更关注逻辑部分。是个好东西记得早些年都是自己造轮子的又无法证明自己造轮子是可靠的因此经常被吊。 当然FlashDB 不仅仅是 通过SFUD去访问SPI Flash也可以通过自己封装的SPI FLASH驱动代码去访问也支持文件系统文件方式去访问外部flash。但经典组合还是  由于芯片本身不同这里芯片不仅仅是FLASH芯片还包括MCU因此要实现自己的代码需要做相应的改进调整以下的方案是基于STM32F407芯片具体硬件配置参考上篇 1. 把相关代码复制到工程里面包括对应 h文件 2. fal_cfg.h  fal 配置 #ifndef _FAL_CFG_H_ #define _FAL_CFG_H_#include main.h#define FAL_DEBUG 1 #define FAL_PART_HAS_TABLE_CFG #define FAL_USING_SFUD_PORT/* Flash device Configuration */ extern struct fal_flash_dev nor_flash0;/* flash device table */ #define FAL_FLASH_DEV_TABLE \ { \nor_flash0, \ //nor flash 基本信息以及读写擦除接口等。是fal_flash_sfud_port.c 有描述也是需要初始化的对象 }/* Partition Configuration */ #ifdef FAL_PART_HAS_TABLE_CFG /* partition table */ #define FAL_PART_TABLE \ { \{FAL_PART_MAGIC_WROD, fdb_kvdb1, norflash0, 0, 1024*1024, 0}, \ /* 1MFLASH 地址0~1M 大小的table, 这里只是一张表根据实际情况配置*/ } #endif /* FAL_PART_HAS_TABLE_CFG */#endif /* _FAL_CFG_H_ */ 3. fal_flash_sfud_port.c 修改印象中只修改过 init  #ifndef FAL_USING_NOR_FLASH_DEV_NAME #define FAL_USING_NOR_FLASH_DEV_NAME norflash0 #endifstatic int init(void); static int read(long offset, uint8_t *buf, size_t size); static int write(long offset, const uint8_t *buf, size_t size); static int erase(long offset, size_t size);static sfud_flash_t sfud_dev NULL; struct fal_flash_dev nor_flash0 {.name FAL_USING_NOR_FLASH_DEV_NAME,.addr 0,.len 1024 * 1024,.blk_size 4096,.ops {init, read, write, erase},.write_gran 1 };static int init(void) {#ifdef RT_USING_SFUD/* RT-Thread RTOS platform */sfud_dev rt_sfud_flash_find_by_dev_name(FAL_USING_NOR_FLASH_DEV_NAME); #else/* bare metal platform */extern sfud_flash flash_table[1]; // 这里table实际上是 指 SFUD_FLASH_DEVICE_TABLEsfud_dev flash_table[0]; // sfud_dev 指向 table[0] 这个非常重要 #endifif (NULL sfud_dev){return -1;}/* update the flash chip information */nor_flash0.blk_size sfud_dev-chip.erase_gran;nor_flash0.len sfud_dev-chip.capacity;return 0; }static int read(long offset, uint8_t *buf, size_t size) {assert(sfud_dev);assert(sfud_dev-init_ok);sfud_read(sfud_dev, nor_flash0.addr offset, size, buf);return size; }static int write(long offset, const uint8_t *buf, size_t size) {assert(sfud_dev);assert(sfud_dev-init_ok);if (sfud_write(sfud_dev, nor_flash0.addr offset, size, buf) ! SFUD_SUCCESS){return -1;}return size; }static int erase(long offset, size_t size) {assert(sfud_dev);assert(sfud_dev-init_ok);if (sfud_erase(sfud_dev, nor_flash0.addr offset, size) ! SFUD_SUCCESS){return -1;}return size; } 4. sfud_cfg.h 配置 SFUD_FLASH_DEVICE_TABLE #ifndef _SFUD_CFG_H_ #define _SFUD_CFG_H_#define SFUD_DEBUG_MODE#define SFUD_USING_SFDP#define SFUD_USING_FLASH_INFO_TABLEenum {SFUD_W25Q128_DEVICE_INDEX 0, // 如果多个往下加名字自己取但要跟其他对应好 };// 上下要对应好 #define SFUD_FLASH_DEVICE_TABLE \ { \[SFUD_W25Q128_DEVICE_INDEX] {.name W25Q128B, .spi.name SPI1}, \ }#endif /* _SFUD_CFG_H_ */ 5. sfud_port.c 修改就是要实现 对接SPI接口 要做 SPI相关配置是通过HAL访问SPI还是其他片选信号对应GPIO信息 SPI延时函数、锁、解锁等 SPI 读写接口封装 #include spi.htypedef struct {SPI_HandleTypeDef *spix;GPIO_TypeDef *cs_gpiox;uint32_t cs_gpio_pin; } spi_user_data, *spi_user_data_t;void sfud_log_debug(const char *file, const long line, const char *format, ...);static void spi_configuration(spi_user_data_t spi) {}static void spi_lock(const sfud_spi *spi) {__disable_irq(); }static void spi_unlock(const sfud_spi *spi) {__enable_irq(); }/*** 这个函数要重新写*/ static sfud_err spi_write_read(const sfud_spi *spi, 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;uint16_t blockSize 0;uint32_t offset 0;if (write_size) {SFUD_ASSERT(write_buf);}if (read_size) {SFUD_ASSERT(read_buf);}// HAL - 片选拉低HAL_GPIO_WritePin(spi_dev-cs_gpiox,spi_dev-cs_gpio_pin,GPIO_PIN_RESET); if (write_size){if (HAL_SPI_Transmit(spi_dev-spix, write_buf, write_size, 100) ! HAL_OK){result SFUD_ERR_WRITE;goto exit;}}while (read_size){blockSize read_size 0xFFFF ? 0xFFFF : read_size;read_size - blockSize;if (HAL_SPI_Receive(spi_dev-spix, read_buf offset, blockSize, 100) ! HAL_OK){result SFUD_ERR_READ;goto exit;}offset blockSize;}exit: // HAL - 片选拉高HAL_GPIO_WritePin(spi_dev-cs_gpiox,spi_dev-cs_gpio_pin,GPIO_PIN_SET);return result; }/* about 100 microsecond delay */ static void retry_delay_100us(void) {DWT_Delay(100); // 这里要自己去实现一个主要是100微秒不是100ms }// spi 关键信息配置对应spi多少片选多少 static spi_user_data spi1 { .spix hspi1, .cs_gpiox SPI_FLASH_CS_GPIO_Port, .cs_gpio_pin SPI_FLASH_CS_Pin }; sfud_err sfud_spi_port_init(sfud_flash *flash) {sfud_err result SFUD_SUCCESS;switch (flash-index) {case SFUD_W25Q128_DEVICE_INDEX: {/* SPI 外设初始化 */spi_configuration(spi1);/* 同步 Flash 移植所需的接口及数据 */flash-spi.wr spi_write_read;flash-spi.lock spi_lock;flash-spi.unlock spi_unlock;flash-spi.user_data spi1;/* about 100 microsecond delay */flash-retry.delay retry_delay_100us;/* about 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;printf([%s,%d] , file, line);va_start(args, format);printf(format, args);va_end(args);printf(\n); }/*** This function is print routine info.** param format output format* param ... args*/ void sfud_log_info(const char *format, ...) {va_list args;va_start(args, format);printf(format, args);va_end(args);printf(\n); } 以上信息一般网上例子就最多那么多实际还有两个关键 1. printf 要重定向还不能用Micro LIB的方式 在usart.c 添加如下代码并不要勾选Micro LIB /* USER CODE BEGIN 1 */ /* 加入以下代码, 支持printf函数, 而不需要选择use MicroLIB */#if 1 #if (__ARMCC_VERSION 6010050) /* 使用AC6编译器时 */ __asm(.global __use_no_semihosting\n\t); /* 声明不使用半主机模式 */ __asm(.global __ARM_use_no_argv \n\t); /* AC6下需要声明main函数为无参数格式否则部分例程可能出现半主机模式 */#else /* 使用AC5编译器时, 要在这里定义__FILE 和 不使用半主机模式 */ #pragma import(__use_no_semihosting)struct __FILE {int handle;/* Whatever you require here. If the only file you are using is *//* standard output using printf() for debugging, no file handling *//* is required. */ };#endif/* 不使用半主机模式至少需要重定义_ttywrch\_sys_exit\_sys_command_string函数,以同时兼容AC6和AC5模式 */ int _ttywrch(int ch) {ch ch;return ch; }/* 定义_sys_exit()以避免使用半主机模式 */ void _sys_exit(int x) {x x; }char *_sys_command_string(char *cmd, int len) {return NULL; }/* FILE 在 stdio.h里面定义. */ FILE __stdout;/* 重定义fputc函数, printf函数最终会通过调用fputc输出字符串到串口 */ int fputc(int ch, FILE *f) {while ((USART1-SR 0X40) 0); /* 等待上一个字符发送完成 */USART1-DR (uint8_t)ch; /* 将要发送的字符 ch 写入到DR寄存器 */ return ch; } #endif/* USER CODE END 1 */ 2. 增加芯片信息    SFUD_FLASH_CHIP_TABLE   最后一个就是我的芯片信息如果没有需要手动添加注意 W25Q128B 的name 关键字这个也不是随便取的要注意与前面的对应 #define SFUD_FLASH_CHIP_TABLE \ { \{AT45DB161E, SFUD_MF_ID_ATMEL, 0x26, 0x00, 2*1024*1024, SFUD_WM_BYTE|SFUD_WM_DUAL_BUFFER, 512, 0x81}, \{W25Q40BV, SFUD_MF_ID_WINBOND, 0x40, 0x13, 512*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \{SST25VF016B, SFUD_MF_ID_SST, 0x25, 0x41, 2*1024*1024, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \{M25P32, SFUD_MF_ID_MICRON, 0x20, 0x16, 4*1024*1024, SFUD_WM_PAGE_256B, 64*1024, 0xD8}, \{EN25Q32B, SFUD_MF_ID_EON, 0x30, 0x16, 4*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \{GD25Q64B, SFUD_MF_ID_GIGADEVICE, 0x40, 0x17, 8*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \{S25FL216K, SFUD_MF_ID_CYPRESS, 0x40, 0x15, 2*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \{A25L080, SFUD_MF_ID_AMIC, 0x30, 0x14, 1*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \{F25L004, SFUD_MF_ID_ESMT, 0x20, 0x13, 512*1024, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \{PCT25VF016B, SFUD_MF_ID_SST, 0x25, 0x41, 2*1024*1024, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \{W25Q128B, SFUD_MF_ID_WINBOND, 0x40, 0x18, 16*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, \ } 这样应该可以了。我记得就这么多
http://www.w-s-a.com/news/365826/

相关文章:

  • 做图书馆网站模板网站建设文化策划方案
  • 惠州城乡住房建设厅网站服装设计自学零基础
  • 网站建设常态化工作机制广州骏域网络
  • h5婚纱摄影网站模板wordpress 显示下列项目
  • 广告网站推广销售北京最新消息发布
  • 完整网站源码asp拨打12355可以找团员密码吗
  • 北京有多少家网站怎么自己在百度上做网站
  • 怎样围绕网站专题发展来做ppt网站建设回龙观
  • 网站配置服务Wordpress红色网站源码
  • 外贸网站建设内容包括软件开发公司流程
  • 做中医药网站有前景吗企业网站优化公司
  • 四川建设设计公司网站海南澄迈县
  • 邳州做网站梵克雅宝项链官网价格图片
  • dede网站收录滦平县建设局网站
  • 上海网站建设开发公注册公司要求什么条件
  • 安徽汽车网网站建设wordpress 知乎
  • 网站建设的功能都需要有哪些在线平台
  • 湖南岳阳网站开发网络公司石家庄做网站的公司哪个好
  • 西安市做网站的公司门户网站对应序号是什么
  • 太原网站域名开发什么是网页界面设计
  • 做产品类网站有哪些做一百度网站吗
  • 在线视频网站建设国外最新创意产品网站有哪些方面
  • 在一个网站下建设多个子网站宣传册画册设计公司
  • 潍坊网站建设公司排名网站建设预付
  • 手机和wap网站建设crm客户管理系统模板
  • 微商城网站建设市场唐山地方志网站建设
  • 想象力做网站网站301跳转代码
  • 做暧暧小视频有声音的网站太原网页搜索排名提升
  • 公众号链接的手机网站怎么做动易2006学校网站
  • 网站网上推广网站推他网站