qspi flash驱动开发记录

这篇博客详细记录了作者在Linux系统下开发QSPI Flash驱动的过程,从驱动框架的演变到QSPI Flash预备知识,包括Zynq QSPI Flash控制器的介绍、设备树的应用。博主介绍了QSPI协议,并探讨了在驱动开发中遇到的问题,如系统无法软重启,通过逐步排查最终发现是地址模式设置不正确导致的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

毕业也有两年了,从大一接触嵌入式以来快六年了,这六年学到的东西也有很多。以前都是看别人的博客,自有写博客想法以来也有一段时间,此博客作为博客的开端,接下来的工作学习中会把所见所学记录在博客中。希望以后能够多写博客,很多疏漏的地方还望大家指正,共同进步

驱动概括

以前在学校大多数嵌入式都是裸机跑起来,驱动非常简单;然后就是一些简单的嵌入式操作系统,比如说freeRtos,这些也都是裸机的驱动;linux驱动就比较复杂,有它自己的驱动框架,并且这个框架十分庞大。这个linux驱动程序就是:

裸机驱动 + linux驱动框架

即按照linux框架来组织驱动程序,所以学好裸机驱动之后,就需要画大功夫去学习linux驱动框架

驱动框架演变

1,设备和驱动在一起

设备相关的信息,比如寄存器地址、大小等信息都是在一个源文件中;以韦东山视频中最简单的led程序为例耦合性比较强。

2,设备和驱动分离

设备和驱动分离开来,设备信息放在一个文件中,驱动程序放在一个文件中;两个文件分别加载,在内核启动的时候根据名字匹配,匹配成功后就调用probe()函数,进行相关的初始化。

3,设备树的引入

由于之前的设备和驱动都是编译进内核中,且没修改一下设备地址就需要重新编译一下内核。并且平台信息太乱,所以后面就把设备信息单独放到一个文件中以文本的形式组织起来。并且单独编译,不与内核一起编译

设备树

1)前面的总线设备驱动模型中,硬件资源来自于leds_dev.c里面的信息,这样会导致不同的板子,会添加不同的硬件资源信息,造成内核的臃肿。
2)使用设备树后,内核不再包含硬件的描述,硬件描述放在单独的DTS里面,然后编译成二进制的DTB,在U-Boot启动的时候加载进去,然后内核进行解析。
3)DTS、DTC和DTB之间的关系:
DTS经过DTC编译得到DTB,DTB通过DTC反编译得到DTS.
4)ARM中,所有的DTS文件放在arch/arm/boot/dts目录中,为了简化,将Soc公用部分提取了出来作为dtsi,类似头文件。
5)DTC编译工具的源代码在scripts/dtc目录中,编译内核时,编译内核时,需要使能才能将源码编译成工具,对应于scripts/dtc/Makefile中"hostprogs-y:=dtc"。Ubuntu也可直接安装DTC工具:

例:

/include/ “skeleton.dtsi”
/ {
compatible = “xlnx,zynq-7000”;

cpus {
	#address-cells = <1>;
	#size-cells = <0>;

	cpu@0 {
		compatible = "arm,cortex-a9";
		device_type = "cpu";
		reg = <0>;
		clocks = <&clkc 3>;
		clock-latency = <1000>;
		cpu0-supply = <&regulator_vccpint>;
		operating-points = <
			/* kHz    uV */
			666667  1000000
			333334  1000000
		>;
	};

	cpu@1 {
		compatible = "arm,cortex-a9";
		device_type = "cpu";
		reg = <1>;
		clocks = <&clkc 3>;
	};
};

pmu {
	compatible = "arm,cortex-a9-pmu";
	interrupts = <0 5 4>, <0 6 4>;
	interrupt-parent = <&intc>;
	reg = < 0xf8891000 0x1000 0xf8893000 0x1000 >;
};

regulator_vccpint: fixedregulator@0 {
	compatible = "regulator-fixed";
	regulator-name = "VCCPINT";
	regulator-min-microvolt = <1000000>;
	regulator-max-microvolt = <1000000>;
	regulator-boot-on;
	regulator-always-on;
};

amba: amba {
	compatible = "simple-bus";
	#address-cells = <1>;
	#size-cells = <1>;
	interrupt-parent = <&intc>;
	ranges;

	adc: adc@f8007100 {
		compatible = "xlnx,zynq-xadc-1.00.a";
		reg = <0xf8007100 0x20>;
		interrupts = <0 7 4>;
		interrupt-parent = <&intc>;
		clocks = <&clkc 12>;
	};

	can0: can@e0008000 {
		compatible = "xlnx,zynq-can-1.0";
		status = "disabled";
		clocks = <&clkc 19>, <&clkc 36>;
		clock-names = "can_clk", "pclk";
		reg = <0xe0008000 0x1000>;
		interrupts = <0 28 4>;
		interrupt-parent = <&intc>;
		tx-fifo-depth = <0x40>;
		rx-fifo-depth = <0x40>;
	};

	can1: can@e0009000 {
		compatible = "xlnx,zynq-can-1.0";
		status = "disabled";
		clocks = <&clkc 20>, <&clkc 37>;
		clock-names = "can_clk", "pclk";
		reg = <0xe0009000 0x1000>;
		interrupts = <0 51 4>;
		interrupt-parent = <&intc>;
		tx-fifo-depth = <0x40>;
		rx-fifo-depth = <0x40>;
	};

	gpio0: gpio@e000a000 {
		compatible = "xlnx,zynq-gpio-1.0";
		#gpio-cells = <2>;
		#interrupt-cells = <2>;
		clocks = <&clkc 42>;
		gpio-controller;
		interrupt-controller;
		interrupt-parent = <&intc>;
		interrupts = <0 20 4>;
		reg = <0xe000a000 0x1000>;
	};

	i2c0: i2c@e0004000 {
		compatible = "cdns,i2c-r1p10";
		status = "disabled";
		clocks = <&clkc 38>;
		interrupt-parent = <&intc>;
		interrupts = <0 25 4>;
		reg = <0xe0004000 0x1000>;
		#address-cells = <1>;
		#size-cells = <0>;
	};

	i2c1: i2c@e0005000 
### FPGA与QSPI Flash配置、编程及使用教程 #### 1. QSPI Flash概述 QSPI (Quad-SPI) 是一种四线串行接口标准,用于连接微控制器或其他主机处理器到外部存储器。这种类型的Flash支持高达4条数据线的同时传输,在提高速度方面具有显著优势[^1]。 #### 2. 系统搭建及启动流程 对于基于Zynq MPSoC平台上的Linux基础开发环境而言,构建一个能够正常工作的QSPI Flash系统涉及多个环节的工作。这包括但不限于硬件设计阶段对PS/PL端口分配合理规划;软件层面则需编写相应的驱动程序以便操作系统能识别并操作外设。具体来说: - **硬件设置**:确保FPGA板卡上已正确安装好兼容的QSPI Flash芯片,并通过管脚定义将其接入至MPSoC PS部分指定引脚组。 - **初始化过程**:当系统加电后,ARM Cortex-A53内核会依据预设引导模式自动加载BootROM代码片段执行初步检测工作,随后按照既定顺序尝试从不同介质获取后续指令集直至找到合法映像文件为止。其中就包含了可能存在的QSPI Flash路径选项。 ```bash # 设置U-Boot环境中变量以指向正确的boot.bin位置 setenv bootcmd 'sf probe; sf read ${loadaddr} 0x0 ${filesize}; source ${loadaddr}' saveenv reset ``` #### 3. 编程方式介绍 针对FPGA内部集成或扩展出来的QSPI Flash资源实施编程活动时,通常有两种主要途径可供选择——借助专用工具完成离线烧录任务或是利用在线调试手段动态更新固件版本号等信息。前者往往依赖于厂商提供的GUI应用程序配合物理连接线路实现高效稳定的数据灌装作业;后者则是依靠JTAG/SWD接口以及配套API函数库达成远程控制目的[^2]。 ```c // C语言示例:向QSPI Flash写入数据前先擦除特定扇区 #include "xil_spi.h" void erase_sector(u8 *base_addr, u32 sector_num){ XSpi_WriteReg(base_addr,XSP_DGIER_OFFSET, XSP_GINTR_ENABLE); // 更多细节省略... } ``` #### 4. 数据完整性保障措施 为了防止因意外断电等原因造成重要资料丢失损坏的情况发生,在实际应用场合下建议采取必要的防护策略。比如可以在每次修改之前预留备份副本保存于其他分区当中;另外就是引入循环冗余检验(CRC)算法计算待存对象特征值并与之共同记录下来供后期验证对比使用,以此增强整个系统的健壮性水平。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值