news 2026/1/30 2:27:05

Zephyr学习之spi flash驱动记录(w25q128)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Zephyr学习之spi flash驱动记录(w25q128)

前言

1.环境搭建 Zephyr开发环境搭建记录(Clion)
2. 使用的开发板为正点原子的探索者:mcu使用的是STM32F407ZGT6
3. 本篇参考示例spi_flash
4. 开发环境使用Clion

参考说明

W25Q128部分原理图

W25Q128资料信息

DMA通道映射

参考示例

打开测试项目

项目配置编写(启用FLASH)

CONFIG_LOG=y CONFIG_FLASH=y CONFIG_FLASH_LOG_LEVEL_INF=y

设备树覆盖文件编写

  1. 完整overlay文件配置
/* 探索者开发板LED灯驱动 LED0 PF9 LED1 PF10 ===================w25q128(SPI1)=================== SPI1_MISO == PB4 SPI1_SCK == PB3 SPI1_MOSI == PB5 SPI1_CS == PB14 */// 定义根节点,包含整个设备树的主要配置/{// 配置系统选择项,指定控制台和shell使用的UART接口chosen{// 指定系统控制台使用USART1zephyr,console=&usart1;// 指定shell命令行使用USART1zephyr,shell-uart=&usart1;};// 定义LED设备节点,配置GPIO控制的LEDleds{// 设置兼容性字符串,表示使用GPIO LED驱动compatible="gpio-leds";// 定义第一个LED设备,别名为led_0led_0:led_0{// 配置GPIO引脚为PF9(GPIOF端口第9号引脚),高电平有效gpios=<&gpiof9GPIO_ACTIVE_HIGH>;// PF9// 设置LED的标签名称label="User LED0";};// 定义第二个LED设备,别名为led_1led_1:led_1{// 配置GPIO引脚为PF10(GPIOF端口第10号引脚),高电平有效gpios=<&gpiof10GPIO_ACTIVE_HIGH>;// PF10// 设置LED的标签名称label="User LED1";};};// 定义别名节点,为设备树中的节点提供简短的别名引用aliases{// 将"led0"别名指向led_0节点led0=&led_0;// 将"led1"别名指向led_1节点led1=&led_1;usart1=&usart1;// 将"w25q128"别名指向w25q128节点w25q128=&w25q128;};};&spi1{dmas=<&dma233STM32_DMA_PERIPH_TX STM32_DMA_FIFO_FULL>,<&dma232STM32_DMA_PERIPH_RX STM32_DMA_FIFO_FULL>;dma-names="tx","rx";status="okay";// clk、mosi、misopinctrl-0=<&spi1_sck_pb3&spi1_miso_pb4&spi1_mosi_pb5>;pinctrl-names="default";cs-gpios=<&gpiob14GPIO_ACTIVE_LOW>;w25q128:w25q128@0{compatible="jedec,spi-nor";size=<0x8000000>;reg=<0>;spi-max-frequency=<4000000>;status="okay";jedec-id=[ef4018];};};&dma2{status="okay";};// 引用并修改预定义的usart1节点&usart1{// 配置USART1的引脚控制,TX连接到PA9,RX连接到PA10pinctrl-0=<&usart1_tx_pa9>,<&usart1_rx_pa10>;// 定义引脚控制配置的名称pinctrl-names="default";// 设置串口通信波特率为115200current-speed=<115200>;// 启用此UART外设status="okay";};

测试主函数编写

/* * Copyright (c) 2025 Embeint Inc * * SPDX-License-Identifier: Apache-2.0 */#include<zephyr/kernel.h>#include<zephyr/device.h>#include<zephyr/net_buf.h>#include<zephyr/logging/log.h>#include<zephyr/drivers/flash.h>#include<stdio.h>#include<string.h>// SPI测试LOG_MODULE_REGISTER(test,LOG_LEVEL_DBG);#defineSPI_FLASH_TEST_REGION_OFFSET0xff000#defineSPI_FLASH_SECTOR_SIZE4096constuint8_terased[]={0xff,0xff,0xff,0xff};voidsingle_sector_test(conststructdevice*flash_dev){constuint8_texpected[]={0x55,0xaa,0x66,0x99};constsize_tlen=sizeof(expected);uint8_tbuf[sizeof(expected)];intrc;LOG_DBG("\nPerform test on single sector");/* Write protection needs to be disabled before each write or * erase, since the flash component turns on write protection * automatically after completion of write and erase * operations. */LOG_DBG("\nTest 1: Flash erase\n");/* Full flash erase if SPI_FLASH_TEST_REGION_OFFSET = 0 and * SPI_FLASH_SECTOR_SIZE = flash size */rc=flash_erase(flash_dev,SPI_FLASH_TEST_REGION_OFFSET,SPI_FLASH_SECTOR_SIZE);if(rc!=0){LOG_DBG("Flash erase failed! %d\n",rc);}else{/* Check erased pattern */memset(buf,0,len);rc=flash_read(flash_dev,SPI_FLASH_TEST_REGION_OFFSET,buf,len);if(rc!=0){LOG_DBG("Flash read failed! %d\n",rc);return;}if(memcmp(erased,buf,len)!=0){LOG_DBG("Flash erase failed at offset 0x%x got 0x%x\n",SPI_FLASH_TEST_REGION_OFFSET,*(uint32_t*)buf);return;}LOG_DBG("Flash erase succeeded!\n");}LOG_DBG("\nTest 2: Flash write\n");LOG_DBG("Attempting to write %zu bytes\n",len);rc=flash_write(flash_dev,SPI_FLASH_TEST_REGION_OFFSET,expected,len);if(rc!=0){LOG_DBG("Flash write failed! %d\n",rc);return;}memset(buf,0,len);rc=flash_read(flash_dev,SPI_FLASH_TEST_REGION_OFFSET,buf,len);if(rc!=0){LOG_DBG("Flash read failed! %d\n",rc);return;}if(memcmp(expected,buf,len)==0){LOG_DBG("Data read matches data written. Good!!\n");}else{constuint8_t*wp=expected;constuint8_t*rp=buf;constuint8_t*rpe=rp+len;LOG_DBG("Data read does not match data written!!\n");while(rp<rpe){LOG_DBG("%08x wrote %02x read %02x %s\n",(uint32_t)(SPI_FLASH_TEST_REGION_OFFSET+(rp-buf)),*wp,*rp,(*rp==*wp)?"match":"MISMATCH");++rp;++wp;}}}intmain(void){conststructdevice*flash_dev=DEVICE_DT_GET(DT_ALIAS(w25q128));if(!device_is_ready(flash_dev)){LOG_ERR("%s: device not ready.\n",flash_dev->name);return0;}LOG_DBG("\n%s SPI flash testing\n",flash_dev->name);LOG_DBG("==========================\n");single_sector_test(flash_dev);return0;}

测试结果

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/28 7:29:29

【计算机毕业设计案例】基于springboot的民宿房间预约管理系统设计与实现民宿客房管理系统(程序+文档+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/1/27 6:49:38

《P1939 矩阵加速(数列)》

题目描述已知一个数列 a&#xff0c;它满足&#xff1a;ax​{1ax−1​ax−3​​x∈{1,2,3}x≥4​求 a 数列的第 n 项对 1097 取余的值。输入格式第一行一个整数 T&#xff0c;表示询问个数。以下 T 行&#xff0c;每行一个正整数 n。输出格式每行输出一个非负整数表示答案。输入…

作者头像 李华
网站建设 2026/1/28 14:10:02

PX4中关于GPS质量检测和相关控制参数

一、PX4关于GPS质量检测的相关参数 PX4官方参数树&#xff1a;参数参照表 | PX4 Guide (main) 1、EKF2_GPS_CHECK (INT32)&#xff1a; Integer bitmask controlling GPS checks Comment: Each threshold value is defined by the parameter indicated next to the check. …

作者头像 李华
网站建设 2026/1/27 18:40:40

day162—递归—买卖股票的最佳时机Ⅱ(LeetCode-122)

题目描述给你一个整数数组 prices &#xff0c;其中 prices[i] 表示某支股票第 i 天的价格。在每一天&#xff0c;你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。然而&#xff0c;你可以在 同一天 多次买卖该股票&#xff0c;但要确保你持有的股票不…

作者头像 李华