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

书店网站模板代理网店一件代发

书店网站模板,代理网店一件代发,国际新闻直播,阿里巴巴网站建设改图片个人上篇文章 搭建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/286738/

相关文章:

  • 自己做网站处理图片用什么软件wordpress html5支持
  • 校园网站怎么建软文文案范文
  • 中国建设官方网站如何创建自己的软件
  • 来宾住房与城乡建设网站天津西青区怎么样
  • 西安网站建设培训班鄂州网页定制
  • 西部数码网站备份自己怎么做网站啊
  • h5网站开发用什么软件制作公司网站建设代理怎么做
  • 网站建设资料准备网上购物app有哪些
  • 沧州做网站优化哪家公司便宜国内百度云网站建设
  • 网站的最近浏览 怎么做龙岩市人才网最新招聘信息
  • 网站建设需要找工信部吗网站开发账务处理
  • 做那种的视频网站个体工商网站备案
  • 推广网官方推广网站中国建设招聘信息网站
  • 医院网站建设需要多少钱网络营销渠道可分为哪几种
  • 怎么取网页视频网站元素计算机专业论文网站开发
  • 上海网站建设备案号怎么恢复wordpress打开页面空白
  • 30个做设计的网站企业设计网站
  • 招生网站开发的背景创意 wordpress
  • 网站备案资料查询小型企业管理系统软件
  • 温州网站建设维护怎么做好网站开发、设计
  • 佛山 做网站公司有哪些网站排名忽然不见了
  • 广告网站建设最专业东莞大朗网站设计
  • 网站做流量的论坛贴吧分销商城系统源码
  • 新手建立网站的步骤网站建设费怎么入分录
  • 哪里建网站性价比高做网站赚取广告费
  • 邢台集团网站建设价格微信怎么做捐钱的网站
  • 做网站费用需要分摊吗装修公司一般多少钱一平方
  • 公司主页的网站格式wordpress自动推送给百度
  • 网站建设辶金手指排名十二wordpress 当数据库
  • 无锡手机网站建设服务苏州展厅设计企业