专栏首页物联网相关TencentOS_tiny 之EVB_MX支持QSPI FLASH
原创

TencentOS_tiny 之EVB_MX支持QSPI FLASH

先看板子原理图:

再看代码结构:

也就是在BSP里,没有看到对qspi或者spi flash的支持。

看到的spi.c,里面也只有一个spi的初始化。

但是qspi和spi是两个不一样的驱动。

但既然板子上有spi flash,就需要使用它。

spi flash可以有什么使用呢。

比如,你可以存储应用数据,用户信息。

还有就是可以存储固件,用于OTA的设计。特别是对于有远程更新app的需求来说,这个就必须用起来了。

板子联网后,通过网络把程序传输过来的,你要把这个程序文件放到哪里呢,不要告诉我这个程序直接放到STM32自带的FLASH吧,而且,自带的FLASH空间有限,估计也不允许你再存一个备份用于更新吧。

这时候SPI_FLASH就起作用了。

把要更新的程序,可以是STM32本身的程序,也可以是WiFI模块的固件,先传到SPI_FLASH里,然后再从SPI_FLASH拷贝到FLASH。

至于STM32的BOOT程序设计及更新,还有跳转,可以参考我另一篇文章,

https://cloud.tencent.com/developer/article/1599222

当然,不管怎么样呢,既然硬件上,放了这个资源,不可能不使用吧,是吧。

那我们就把它驱动起来吧。

参考了STM32的资料,以及网上关于QSPI的使用。然后整理起来,在这板子进行验证了。下面大概描述一下驱动过程。

为了和原来代码框架比较接近,我就直接在BSP的spi.c spi.h上,添加对QSPI_FLASH的支持。

文件网址:

https://github.com/xidongliang/TencentOS_tiny_EVB_MX_Plus_QSPI

直接从git上,下载这两个文件替换或合并进去 就差不多了。

当然,还要在keil工程里,启用QSPI的宏定义,把它开出来。这样在编译的时候,才能把QSPI的库编译进去。

同时,还需要在keil工程里,将qpis的系统库文件添加到工程目录里,否则编译的时候,会提示各种函数找不到,会编译不过。

首先第一件事就是初始化啦:

void QSPI_FLASH_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

/* 使能 QSPI 及 GPIO 时钟 */

QSPI_FLASH_CLK_ENABLE();

QSPI_FLASH_CLK_GPIO_ENABLE();

QSPI_FLASH_BK1_IO0_CLK_ENABLE();

QSPI_FLASH_BK1_IO1_CLK_ENABLE();

//QSPI_FLASH_BK1_IO2_CLK_ENABLE();

//QSPI_FLASH_BK1_IO3_CLK_ENABLE();

QSPI_FLASH_CS_GPIO_CLK_ENABLE();

//设置引脚

/*!< 配置 QSPI_FLASH 引脚: CLK */

GPIO_InitStruct.Pin = QSPI_FLASH_CLK_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

GPIO_InitStruct.Alternate = QSPI_FLASH_CLK_GPIO_AF;

HAL_GPIO_Init(QSPI_FLASH_CLK_GPIO_PORT, &GPIO_InitStruct);

/*!< 配置 QSPI_FLASH 引脚: IO0 */

GPIO_InitStruct.Pin = QSPI_FLASH_BK1_IO0_PIN;

GPIO_InitStruct.Alternate = QSPI_FLASH_BK1_IO0_AF;

HAL_GPIO_Init(QSPI_FLASH_BK1_IO0_PORT, &GPIO_InitStruct);

/*!< 配置 QSPI_FLASH 引脚: IO1 */

GPIO_InitStruct.Pin = QSPI_FLASH_BK1_IO1_PIN;

GPIO_InitStruct.Alternate = QSPI_FLASH_BK1_IO1_AF;

HAL_GPIO_Init(QSPI_FLASH_BK1_IO1_PORT, &GPIO_InitStruct);

#if 0

/*!< 配置 QSPI_FLASH 引脚: IO2 */

GPIO_InitStruct.Pin = QSPI_FLASH_BK1_IO2_PIN;

GPIO_InitStruct.Alternate = QSPI_FLASH_BK1_IO2_AF;

HAL_GPIO_Init(QSPI_FLASH_BK1_IO2_PORT, &GPIO_InitStruct);

/*!< 配置 QSPI_FLASH 引脚: IO3 */

GPIO_InitStruct.Pin = QSPI_FLASH_BK1_IO3_PIN;

GPIO_InitStruct.Alternate = QSPI_FLASH_BK1_IO3_AF;

HAL_GPIO_Init(QSPI_FLASH_BK1_IO3_PORT, &GPIO_InitStruct);

#endif

/*!< 配置 SPI_FLASH_SPI 引脚: NCS */

GPIO_InitStruct.Pin = QSPI_FLASH_CS_PIN;

GPIO_InitStruct.Alternate = QSPI_FLASH_CS_GPIO_AF;

HAL_GPIO_Init(QSPI_FLASH_CS_GPIO_PORT, &GPIO_InitStruct);

/* QSPI_FLASH 模式配置 */

QSPIHandle.Instance = QUADSPI;

QSPIHandle.Init.ClockPrescaler = 2;

QSPIHandle.Init.FifoThreshold = 4;

QSPIHandle.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_HALFCYCLE;

QSPIHandle.Init.FlashSize = 23;

QSPIHandle.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_8_CYCLE;

QSPIHandle.Init.ClockMode = QSPI_CLOCK_MODE_0;

HAL_QSPI_Init(&QSPIHandle);

/*初始化QSPI接口*/

BSP_QSPI_Init();

}

初始化里,要把IO2和IO3去掉。因为使用硬件电路只使用了IO0,IO1。

初始化的工作,就是把GPIO设置正确的模式,并把QSPI启用就行了。基本问题不大。

接下来就是读写函数了。

封装了几个函数。具体代码各位可以直接git上下载下来阅读和调试。如果调试遇到问题,可留言评论交流。

其中主要的函数有:

一个是初始化函数,

读ID函数。

读数据函数。

写数据函数。

对应用层来说,该SPI_FLASH 一定有8M空间可用。

在读或者写的时候,把要访问的地址和长度确定一下就行了。使用起来还是比较方便的。

不过,值得注意的是,这里面的读写的函数都是原始数据流的形式。如果有对文件格式要求的,最好需要移植一个fat文件格式库吧。这里就不介绍怎么做文件格式操作了。

这个板子本身硬件资源有限,达不到做linux或者精简版linux的级别。当然,这个就是一个tinyOS。里面貌似也有关于fatfs的代码。

但是还没有添加对SPI_FLASH的支持。

其实到了这一步,添加支持就很方便了。

在这个disk_read里添加QSPI的读写就可以了。当然,笔者还没有去验证,但是理论上是可行的,有能力的读者可以自己去尝试。或者也可以留言交流。

我估计这个tinyOS系统,也在陆续完善,很多偏应用层的东西,还在慢慢维护和支持,也需要各开发者贡献自己的demo和库吧。

https://github.com/xidongliang/TencentOS_tiny_EVB_MX_Plus_QSPI

笔者也曾想过,是否要将这个QSPI的驱动支持,提交到TencentOS_tiny的git中。

主要是笔者对git的使用不太熟悉。还有一个还是,建议还是由官方的技术人员来验证并添加支持,这样可保证代码风格,系统功能等的

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [TencentOS_tiny_EVB_MX]之程序跳转

    现针对TencentOS_tiny_EVB_MX这个,做一个简单的程序跳转demo分享出来。

    诸子东
  • 开源一个自己写过的MQTT 客户端调试工具

    有时候我们开发或者MQTT,并不会用太多的功能,或者能支持十六进制发送和接收。也曾在网上找过几款MQTT工具,也都没能让自己满意,于是自己就写了一个MQTT客户...

    诸子东
  • 理解数据库连接池底层原理之手写实现前言对数据库连接池的一点思考写一个迷你版数据库连接池

    数据库连接池的基本思想是:为数据库连接建立一个“缓冲池”,预先在池中放入一定数量的数据库连接管道,需要时,从池子中取出管道进行使用,操作完毕后,在将管道放入池子...

    用户2890438
  • 理解数据库连接池底层原理之手写实现

    数据库连接池的基本思想是:为数据库连接建立一个“缓冲池”,预先在池中放入一定数量的数据库连接管道,需要时,从池子中取出管道进行使用,操作完毕后,在将管道放入池子...

    Java团长
  • 理解数据库连接池底层原理之手写实现

    数据库连接池的基本思想是:为数据库连接建立一个“缓冲池”,预先在池中放入一定数量的数据库连接管道,需要时,从池子中取出管道进行使用,操作完毕后,在将管道放入池子...

    java进阶架构师
  • 深度学习 — 图像风格化实验记录

    ------问对了问题 ,就成功了一半 Tags: 深度学习 CNN 图片风格化 ---- ? A Neural Algorithm of Artistic S...

    zhwhong
  • 是谁在说话?谷歌多人语音识别新系统错误率降至2%

    识别「谁说了什么」,也就是「说话人分类」任务是自动理解人类对话音频的关键步骤。例如,在一个医生与患者的对话中,「患者」在回答医生的问题(「你经常服用心脏病药物吗...

    机器之心
  • SQL Server分区表(一):分区表的介绍

    如果你的数据库中某一个表中的数据满足以下几个条件,那么你就要考虑创建分区表了。

    Vaccae
  • Server 2005中的分区表(一)

    本文转载:http://blog.csdn.net/smallfools/article/details/4930810

    跟着阿笨一起玩NET
  • require和import的区别

    CommonJs 规范规定,每个模块内部,module变量代表当前模块。这个变量是一个对象,它的 exports属性(即module.exports)是对外的接...

    木子星兮

扫码关注云+社区

领取腾讯云代金券