“Linux内核-eMMC驱动移植”的版本间的差异

来自华清远见研发中心
跳转至: 导航搜索
实验原理
实验原理
 
(未显示同一用户的1个中间版本)
第1行: 第1行:
 
==实验原理==
 
==实验原理==
 
参考原理图可知eMMC使用的是sdmmc2总线,当前所使用的设备树文件中没有sdmmc2的支持,所以需要增加相关内容才能正常驱动eMMC。<br>
 
参考原理图可知eMMC使用的是sdmmc2总线,当前所使用的设备树文件中没有sdmmc2的支持,所以需要增加相关内容才能正常驱动eMMC。<br>
[[Image:49-1-1-1.png|640px]] <br>
+
<center>[[Image:49-1-1-1.png|640px]]</center> <br>
  
 
由于在使STM32MP1芯片很多管脚为多功能复用管脚,且很多管脚具备同样的功能,所以移植eMMC时需要确认硬件设计是使用的是那些管脚,根据原理图确认后管脚对应关系为:<br>
 
由于在使STM32MP1芯片很多管脚为多功能复用管脚,且很多管脚具备同样的功能,所以移植eMMC时需要确认硬件设计是使用的是那些管脚,根据原理图确认后管脚对应关系为:<br>
{|class="wikitable"
+
{|align=center border=1
 
|-
 
|-
 
! 原理图网络编号 !!对应管脚 !!管脚功能 !! 管脚功能码
 
! 原理图网络编号 !!对应管脚 !!管脚功能 !! 管脚功能码
第235行: 第235行:
 
华清远见开发环境,FS-MP1A平台;<br>
 
华清远见开发环境,FS-MP1A平台;<br>
 
==实验步骤==
 
==实验步骤==
*添加eMMC设备树配置<br>
+
<ol>
 +
<li>导入交叉编译工具链</li>
 +
 
 +
linux@ubuntu:$ source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
 +
 
 +
<li>添加eMMC设备树配置</li><br>
  
修改arch/arm/dts/stm32mp15xx-fsmp1x.dts文件<br>
+
修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件<br>
  
 
在原有sdmmc1节点下添加如下内容:
 
在原有sdmmc1节点下添加如下内容:
第257行: 第262行:
 
};
 
};
 
</nowiki></pre>
 
</nowiki></pre>
*配置内核<br>
+
 
 +
<li>配置内核</li>
 +
 
  
 
由于内核源码默认配置已经支持eMMC,本节列出主要选项,如下:
 
由于内核源码默认配置已经支持eMMC,本节列出主要选项,如下:
第266行: 第273行:
 
[*]    STMicroelectronics STM32 SDMMC Controller
 
[*]    STMicroelectronics STM32 SDMMC Controller
 
</nowiki></pre>
 
</nowiki></pre>
*编译内核级设备树:
+
<li>编译内核级设备树:</li>
 
  linux@ubuntu:$ make -j4 uImage dtbs LOADADDR=0xC2000040
 
  linux@ubuntu:$ make -j4 uImage dtbs LOADADDR=0xC2000040
*重启测试<br>
+
<li>重启测试</li><br>
  
 
将编译好的设备树和内核镜像拷贝到/tftpboot目录下,通过tftp引导内核,重启设备后可以看到如下启动信息:
 
将编译好的设备树和内核镜像拷贝到/tftpboot目录下,通过tftp引导内核,重启设备后可以看到如下启动信息:
第277行: 第284行:
  
 
[[Image:49-1-4-2.png]] <br>
 
[[Image:49-1-4-2.png]] <br>
 +
</ol>

2021年3月24日 (三) 15:07的最新版本

实验原理

参考原理图可知eMMC使用的是sdmmc2总线,当前所使用的设备树文件中没有sdmmc2的支持,所以需要增加相关内容才能正常驱动eMMC。

49-1-1-1.png

由于在使STM32MP1芯片很多管脚为多功能复用管脚,且很多管脚具备同样的功能,所以移植eMMC时需要确认硬件设计是使用的是那些管脚,根据原理图确认后管脚对应关系为:

原理图网络编号 对应管脚 管脚功能 管脚功能码
SD2_DATA0 PB14 SDMMC2_D0 AF9
SD2_DATA1 PB15 SDMMC2_D1 AF9
SD2_DATA2 PB3 SDMMC2_D2 AF9
SD2_DATA3 PB4 SDMMC2_D3 AF9
SD2_DATA4 PA8 SDMMC2_D4 AF9
SD2_DATA5 PA9 SDMMC2_D5 AF10
SD2_DATA6 PE5 SDMMC2_D6 AF9
SD2_DATA7 PD3 SDMMC2_D7 AF9
SD2_CLK PE3 SDMMC2_CK AF9
SD2_CMD PG6 SDMMC2_CMD AF10
  1. eMMC设备树节点
  2. 参考文档:

    Documentation/devicetree/bindings/mmc/mmc-controller.yaml
    Documentation/devicetree/bindings/mmc/mmci.txt
    

    内核中ST对STM32MP15x系列芯片的设备树资源了做了定义,可参见:

    arch/arm/boot/dts/stm32mp151.dtsi
    

    stm32mp151中sdmmc2定义如下:

    sdmmc2: sdmmc@58007000 {
    	compatible = "arm,pl18x", "arm,primecell";
    	arm,primecell-periphid = <0x00253180>;
    	reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
    	interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
    	interrupt-names = "cmd_irq";
    	clocks = <&rcc SDMMC2_K>;
    	clock-names = "apb_pclk";
    	resets = <&rcc SDMMC2_R>;
    	cap-sd-highspeed;
    	cap-mmc-highspeed;
    	max-frequency = <120000000>;
    	status = "disabled";
    };
    

    上述代码只对sdmmc2做了基本的初始化,并没有针对不同的硬件设计做适配,所以需结合硬件补全设备树节点信息。

    eMMC有8根数据线,且eMMC无需热插拔等功能,结合硬件信息添加sdmmc2节点信息,也可参考内核中其他设备树文件中相关描述,比如stm32mp15xx-edx.dtsi关于sdmmc2的描述符合我们的要求,内容如下:

    &sdmmc2 {
    	pinctrl-names = "default", "opendrain", "sleep";
    	pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
    	pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>;
    	pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>;
    	non-removable;
    	no-sd;
    	no-sdio;
    	st,neg-edge;
    	bus-width = <8>;
    	vmmc-supply = <&v3v3>;
    	vqmmc-supply = <&vdd>;
    	mmc-ddr-3_3v;
    	status = "okay";
    };
    
  3. 管脚定义
  4. 在内核中STM32MP1默认管脚定义在文件arch/arm/dts/stm32mp15-pinctrl.dtsi中,查看文件中是否有需要的管脚定义:

    查看后确认有sdmmc2的管脚定义,且与FS-MP1A硬件使用情况一致,定义如下:

    sdmmc2_b4_pins_a: sdmmc2-b4-0 {
    		pins1 {
    			pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
    				 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
    				 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
    				 <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
    				 <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
    			slew-rate = <1>;
    			drive-push-pull;
    			bias-pull-up;
    		};
    		pins2 {
    			pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
    			slew-rate = <2>;
    			drive-push-pull;
    			bias-pull-up;
    		};
    	};
    
    	sdmmc2_b4_od_pins_a: sdmmc2-b4-od-0 {
    		pins1 {
    			pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
    				 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
    				 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
    				 <STM32_PINMUX('B', 4, AF9)>; /* SDMMC2_D3 */
    			slew-rate = <1>;
    			drive-push-pull;
    			bias-pull-up;
    		};
    		pins2 {
    			pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
    			slew-rate = <2>;
    			drive-push-pull;
    			bias-pull-up;
    		};
    		pins3 {
    			pinmux = <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
    			slew-rate = <1>;
    			drive-open-drain;
    			bias-pull-up;
    		};
    	};
    
    	sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 {
    		pins {
    			pinmux = <STM32_PINMUX('B', 14, ANALOG)>, /* SDMMC2_D0 */
    				 <STM32_PINMUX('B', 15, ANALOG)>, /* SDMMC2_D1 */
    				 <STM32_PINMUX('B', 3, ANALOG)>, /* SDMMC2_D2 */
    				 <STM32_PINMUX('B', 4, ANALOG)>, /* SDMMC2_D3 */
    				 <STM32_PINMUX('E', 3, ANALOG)>, /* SDMMC2_CK */
    				 <STM32_PINMUX('G', 6, ANALOG)>; /* SDMMC2_CMD */
    		};
    	};
    
    	sdmmc2_b4_pins_b: sdmmc2-b4-1 {
    		pins1 {
    			pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
    				 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
    				 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
    				 <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
    				 <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
    			slew-rate = <1>;
    			drive-push-pull;
    			bias-disable;
    		};
    		pins2 {
    			pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
    			slew-rate = <2>;
    			drive-push-pull;
    			bias-disable;
    		};
    	};
    
    	sdmmc2_b4_od_pins_b: sdmmc2-b4-od-1 {
    		pins1 {
    			pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
    				 <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
    				 <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
    				 <STM32_PINMUX('B', 4, AF9)>; /* SDMMC2_D3 */
    			slew-rate = <1>;
    			drive-push-pull;
    			bias-disable;
    		};
    		pins2 {
    			pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
    			slew-rate = <2>;
    			drive-push-pull;
    			bias-disable;
    		};
    		pins3 {
    			pinmux = <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
    			slew-rate = <1>;
    			drive-open-drain;
    			bias-disable;
    		};
    	};
    
    	sdmmc2_d47_pins_a: sdmmc2-d47-0 {
    		pins {
    			pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
    				 <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
    				 <STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */
    				 <STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */
    			slew-rate = <1>;
    			drive-push-pull;
    			bias-pull-up;
    		};
    	};
    
    	sdmmc2_d47_sleep_pins_a: sdmmc2-d47-sleep-0 {
    		pins {
    			pinmux = <STM32_PINMUX('A', 8, ANALOG)>, /* SDMMC2_D4 */
    				 <STM32_PINMUX('A', 9, ANALOG)>, /* SDMMC2_D5 */
    				 <STM32_PINMUX('E', 5, ANALOG)>, /* SDMMC2_D6 */
    				 <STM32_PINMUX('D', 3, ANALOG)>; /* SDMMC2_D7 */
    		};
    	};
    

实验目的

熟悉基于Linux操作系统下的块设备驱动移植配置过程。

实验平台

华清远见开发环境,FS-MP1A平台;

实验步骤

  1. 导入交叉编译工具链
  2. linux@ubuntu:$ source /opt/st/stm32mp1/3.1-openstlinux-5.4-dunfell-mp1-20-06-24/environment-setup-cortexa7t2hf-neon-vfpv4-ostl-linux-gnueabi
    
  3. 添加eMMC设备树配置

  4. 修改arch/arm/boot/dts/stm32mp15xx-fsmp1x.dtsi文件

    在原有sdmmc1节点下添加如下内容:

    &sdmmc2 {
    	pinctrl-names = "default", "opendrain", "sleep";
    	pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
    	pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>;
    	pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>;
    	non-removable;
    	no-sd;
    	no-sdio;
    	st,neg-edge;
    	bus-width = <8>;
    	vmmc-supply = <&v3v3>;
    	vqmmc-supply = <&vdd>;
    	mmc-ddr-3_3v;
    	status = "okay";
    };
    
  5. 配置内核

  6. 由于内核源码默认配置已经支持eMMC,本节列出主要选项,如下:

    linux@ubuntu:$ make menuconfig
    Device Drivers  --->
    	<*> MMC/SD/SDIO card support  --->
    	[*]     STMicroelectronics STM32 SDMMC Controller
    
  7. 编译内核级设备树:
  8. linux@ubuntu:$ make -j4 uImage dtbs LOADADDR=0xC2000040
    
  9. 重启测试

  10. 将编译好的设备树和内核镜像拷贝到/tftpboot目录下,通过tftp引导内核,重启设备后可以看到如下启动信息:

    49-1-4-1.png

    由于eMMC中有出厂预装的FS-MP1A系统,所以可以正常完成文件系统挂载进入系统:

    49-1-4-2.png