openwrt下复用SPI挂载SD卡(Расширенный моддинг MMC)

       本人完全不懂俄文尴尬,靠谷歌和自己瞎猜翻译,必然有很多错误之处,请不吝指教!

       原文链接:http://wiki.openwrt.org/ru/toh/tp-link/tl-mr3420/deep.mmc.hack

       正文开始:


Способ подключения

连接方法

Способ подключения

Схема подключения успешно опробована на шине питания GPIO = 2.6V

当GPIO=2.6V时,测试布线方案成功。


Используется QSS светодиод как внутренний CS1: 

QSS LED被用作内部的CS1:


Резисторы 10кОм были подобраны опытным путем: 

凭经验选择10k电阻:


Существует два способа модификации с использованием разных GPIO для CS1, а также два варианта установки необходимого ПО для непосредственного использования карточки памяти подключенной к устройству.

为了在设备上直接是用内存卡,有两种GPIO作为CS的方法,同时,也有两个所需软件的安装选项。

Примечание: Эта модификация, как и модификация mmc_over_gpio - не поддерживает SDHC карточки памяти на уровне драйвера.

注意:这种方式以及修改mmc_over_gpio,在驱动级别不支持SDHC存储卡。


Подключение MMC/SD карты памяти к шине spi0.1

MMC/SD连接spi0.1

Основные изменения в прошивке

固件中的变化(需修改的地方)


Первый способ.

方式一:

Вариант GPIO как CS1

将GPIO配置成CS1

В качестве CS для MMC/SD карты памяти, предпочтительнее использовать любой свободный GPIO пин.

最好选择不用的GPIO作为MMC/SD的CS

Использование GPIO 7 - как CS1 для общей шины:

使用GPIO7作为CS1:

(终于不用借助谷歌翻译了,下面是需要修改的源文件,第一行是文件名和位置,之后,行前有+的表示增加该行,-表示删除该行)

Index: target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c
===================================================================
--- target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c	(revision 34914)
+++ target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c	(working copy)
@@ -50,7 +50,7 @@
 void __init ath79_register_m25p80(struct flash_platform_data *pdata)
 {
 	ath79_spi_data.bus_num = 0;
-	ath79_spi_data.num_chipselect = 1;
+	ath79_spi_data.num_chipselect = 2;
 	ath79_spi0_cdata.is_flash = true;
 	ath79_spi_info[0].platform_data = pdata;
 	ath79_register_spi(&ath79_spi_data, ath79_spi_info, 1);
Index: target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c
===================================================================
--- target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c	(revision 34914)
+++ target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c	(working copy)
@@ -9,6 +9,9 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/mmc_spi.h>
 
 #include <asm/mach-ath79/ath79.h>
 
@@ -16,12 +19,14 @@
 #include "dev-ap9x-pci.h"
 #include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
+#include "dev-spi.h"
 #include "dev-m25p80.h"
 #include "dev-usb.h"
 #include "machtypes.h"
 
 #define TL_MR3X20_GPIO_LED_QSS		0
 #define TL_MR3X20_GPIO_LED_SYSTEM	1
+#define TL_MR3X20_GPIO_CS1_MMC		7
 #define TL_MR3X20_GPIO_LED_3G		8
 
 #define TL_MR3X20_GPIO_BTN_RESET	11
@@ -32,6 +37,26 @@
 #define TL_MR3X20_KEYS_POLL_INTERVAL	20	/* msecs */
 #define TL_MR3X20_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3X20_KEYS_POLL_INTERVAL)
 
+static struct mmc_spi_platform_data ath79_mmc_data = {
+       .get_ro = NULL,
+       .get_cd = NULL,
+       .detect_delay = 100, /* msecs */ 
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+};
+
+static struct ath79_spi_controller_data ath79_spi1_cdata = {
+	.cs_type = ATH79_SPI_CS_TYPE_GPIO,
+	.cs_line = TL_MR3X20_GPIO_CS1_MMC,
+};
+
+static struct spi_board_info ath79_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 1,
+		.max_speed_hz	= 25000000,
+		.modalias	= "mmc_spi",
+		.platform_data	= &ath79_mmc_data,
+		.controller_data = &ath79_spi1_cdata,
+	}
+};
+
 static const char *tl_mr3x20_part_probes[] = {
 	"tp-link",
 	NULL,
@@ -97,6 +122,9 @@
 	ath79_register_eth(0);
 
 	ap91_pci_init(ee, mac);
+
+	spi_register_board_info(ath79_spi_info,
+				ARRAY_SIZE(ath79_spi_info));
 }
 
 static void __init tl_mr3x20_usb_setup(void)

Второй способ.

方式二:

Вариант Int. CS1

(不懂)

内部CS

AR724X

AR933X

CS1

QSS LED (GPIO0)

UART In (GPIO9)

CS2

SYS LED (GPIO1)

UART Out (GPIO10)


На устройствах AR724X: Для того, чтобы использовать внутренний CS1 - необходимо отключить QSS LED.

在AR724X上:使用内部CS1需禁用QSS LED

На устройствах AR933X: Для того, чтобы использовать внутренний CS1 - необходимо отключить UART.

在AR933X上:是用内部CS1需禁用UART

Index: target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c
===================================================================
--- target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c	(revision 34914)
+++ target/linux/ar71xx/files/arch/mips/ath79/dev-m25p80.c	(working copy)
@@ -50,7 +50,7 @@
 void __init ath79_register_m25p80(struct flash_platform_data *pdata)
 {
 	ath79_spi_data.bus_num = 0;
-	ath79_spi_data.num_chipselect = 1;
+	ath79_spi_data.num_chipselect = 2;
 	ath79_spi0_cdata.is_flash = true;
 	ath79_spi_info[0].platform_data = pdata;
 	ath79_register_spi(&ath79_spi_data, ath79_spi_info, 1);
Index: target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c
===================================================================
--- target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c	(revision 34914)
+++ target/linux/ar71xx/files/arch/mips/ath79/mach-tl-mr3x20.c	(working copy)
@@ -9,13 +9,19 @@
  */
 
 #include <linux/gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/mmc_spi.h>
 
 #include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
 
+#include "common.h"
 #include "dev-eth.h"
 #include "dev-ap9x-pci.h"
 #include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
+#include "dev-spi.h"
 #include "dev-m25p80.h"
 #include "dev-usb.h"
 #include "machtypes.h"
@@ -32,6 +38,26 @@
 #define TL_MR3X20_KEYS_POLL_INTERVAL	20	/* msecs */
 #define TL_MR3X20_KEYS_DEBOUNCE_INTERVAL (3 * TL_MR3X20_KEYS_POLL_INTERVAL)
 
+static struct mmc_spi_platform_data ath79_mmc_data = {
+	.ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+};
+
+static struct ath79_spi_controller_data ath79_spi1_cdata = {
+	.cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
+	.cs_line = 1,
+}; 
+
+static struct spi_board_info ath79_spi_info[] = {
+	{
+		.bus_num	= 0,
+		.chip_select	= 1,
+		.max_speed_hz	= 25000000,
+		.modalias	= "mmc_spi",
+		.platform_data	= &ath79_mmc_data,
+		.controller_data = &ath79_spi1_cdata,
+	}
+};
+
 static const char *tl_mr3x20_part_probes[] = {
 	"tp-link",
 	NULL,
@@ -80,6 +106,9 @@
 	u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00);
 	u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
 
+	/* Enabling internal CS1, disable GPIO 0 */
+	ath79_gpio_function_enable(AR724X_GPIO_FUNC_SPI_CS_EN1);
+
 	ath79_register_m25p80(&tl_mr3x20_flash_data);
 
 	ath79_register_gpio_keys_polled(-1, TL_MR3X20_KEYS_POLL_INTERVAL,
@@ -97,6 +126,9 @@
 	ath79_register_eth(0);
 
 	ap91_pci_init(ee, mac);
+
+	spi_register_board_info(ath79_spi_info,
+				ARRAY_SIZE(ath79_spi_info));
 }
 
 static void __init tl_mr3x20_usb_setup(void)
Переключение GPIO0 (QSS LED) в CS1 на AR724X:

(翻译不出来)

/* Enabling internal CS1, disable GPIO 0 */
ath79_gpio_function_enable(AR724X_GPIO_FUNC_SPI_CS_EN1);

(Уже используется в верхнем примере.)

(已在上面例子中使用)


Отключение UART и переключение GPIO 9(Rx) в CS1 на AR933X:

AR933X芯片上禁用UART和GPIO9(Rx)作为CS1:

/* Disable UART, enabling GPIO 9 and GPIO 10 */
ath79_gpio_function_disable(AR933X_GPIO_FUNC_UART_EN);
/* Enabling internal CS1, disable GPIO 9 */
ath79_gpio_function_enable(AR933X_GPIO_FUNC_SPI_CS_EN1);

Модули

模块

Первый вариант.

第一种方式:

Использование внешних модулей kmod-mmc и kmod-mmc-spi - пока не позволяет корректно смонтировать /overlay или / разделы через extroot, данная ошибка описана в https://dev.openwrt.org/ticket/7768. Это даже с учетом того, что использование этих модулей, позволяет полноценно использовать карточку памяти и монтировать ее в другие точки монтирования (кроме extroot).

注意:使用外部的kmod-MMC和的kmod-MMC-SPI模块,不允许通过extroot正确的安装/叠加/或部分,这个错误是在https://dev.openwrt.org/ticket/7768描述。它甚至没有考虑到一个事实,即使用这些模块可以充分利用存储卡和其他挂载点安装它(extroot除外)。

Обновление: Проблема сохранилась по состоянию ревизии прошивки r37142.

更新:这个问题在固件r37142中依然存在

Для extroot, используйте Второй вариант.

对于extroot使用第二种方式


Второй вариант.

第二种方式:

На уровне ядра (kernel):

在内核层(kernel):

Index: target/linux/ar71xx/config-3.7
===================================================================
--- target/linux/ar71xx/config-3.7	(revision 35363)
+++ target/linux/ar71xx/config-3.7	(working copy)
@@ -240,6 +240,10 @@
 # CONFIG_SPI_RB4XX is not set
 # CONFIG_SPI_RB4XX_CPLD is not set
 # CONFIG_SPI_VSC7385 is not set
+CONFIG_EXT4_FS=y
+CONFIG_MMC=y
+CONFIG_MMC_SPI=y
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_TIFM_SD=n
 CONFIG_SWCONFIG=y
 CONFIG_SWCONFIG_LEDS=y
 CONFIG_SYS_HAS_CPU_MIPS32_R2=y
Помимо MMC модулей, здесь дополнительно включена возможность использовать EXT4 файловую систему на уровне ядра.

除了的MMC模块,这里还包括在内核级使用EXT4文件系统的能力。

Также следует учесть, что Linux-ядро регулярно обновляется, а этот конфигурационный файл в названии носит версию ядра.

还需要注意的是,linux内核定期更新,但这个配置文件是在特定的内核版本内的

В конечном счете, если ядро Trank'а обновилось, необходимо найти этот же конфиг. файл (но уже новый, например: config-3.8) и изменить его в соответствии с представленными здесь изменениями.

最后,如内核已经更新,则需要找到新内核中对应的文件再次修改

Интеграция необходимых модулей в ядро, позволяет использовать обнаруженную карточку памяти на ровне с флеш-памятью.

所有模块集成到内核中,可是用存储卡的闪存水平检测

При этом, можно использовать карточку памяти в качестве расширенной файловой системы - extroot.

在这种情况下,可以使用存储卡作为扩展文件系统 - extroot。


Измерения

测试

Тест скоростей spi0.1:

spi0.1速度测试:

Скорость чтения/записи утилитой dd:

利用dd测试读/写速度

root@OpenWrt:~# /usr/bin/dd count=14 bs=1M if=/dev/mmcblk0p1 of=/dev/null
14+0 records in
14+0 records out
14680064 bytes (15 MB) copied, 20.9663 s, 700 kB/s
root@OpenWrt:~# /usr/bin/dd count=14 bs=1M if=/dev/zero of=/dev/mmcblk0p1
14+0 records in
14+0 records out
14680064 bytes (15 MB) copied, 25.2994 s, 580 kB/s
root@OpenWrt:~#
Результат утилиты hdparm:

结果工具hdparm的:

root@OpenWrt:~# hdparm -Tt /dev/mmcblk0p1

/dev/mmcblk0p1:
 Timing cached reads:     2 MB in  2.96 seconds = 691.37 kB/sec
 Timing buffered disk reads:   2 MB in  3.05 seconds = 670.43 kB/sec
root@OpenWrt:~#
Нагрузка на CPU во время чтения/записи:

读写时占用的CPU资源:

root@OpenWrt:~# top
Mem: 28224K used, 1120K free, 0K shrd, 5784K buff, 5592K cached
CPU:   0% usr  99% sys   0% nic   0% idle   0% io   0% irq   0% sirq
Load average: 1.21 0.88 0.60 2/60 28540
  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
 2230     2 root     RW       0   0%  55% [kworker/u:2]
 2180     2 root     SW       0   0%  36% [kworker/u:0]
  559     2 root     RW       0   0%   6% [mmcqd/0]
...
Итог: Скорость чтения/записи по шине SPI, прямо зависит от скорости CPU.

通过SPI读写速度直接取决于CPU速度


Тест одновременного использования spi0.0 и spi0.1:

测试同时使用spi0.0和spi0.1:

Здесь стоит уточнить способ выполнения теста. 

未测试指定一种方法是有必要的

Посылается две параллельные команды чтение\запись с разделительным command оператором "&" (запуск команды в фоне). 

发送两个平行的读写命令到后台运行(包含&)

Результат следующий: при одновременном чтении или записи spi0.0 и spi0.1 (процесс не имеет значения), предпочтение дается шине spi0.1, т.е. пока не закончится операция чтении/записи блока на шине spi0.1 - на шине spi0.0 не начнется запрашиваемая операция, выполнение происходит в приоритетном порядке и не является ошибкой.

其结果是:在读取或写入spi0.0 spi0.1时(过程无所谓),总线spi0.1优先,即直到读/写单元spi0.1结束前,总线spi0.0都无法启动请求的操作,执行的地方作为优先事项而非一个错误。

Питание:

Food:(不知道是什么)

模式

睡眠模式(简单)

~1mA

读取数据

~18mA

写入数据

~23mA


Логи

日志:

Лог загрузки и инициализации карточки:

登陆并加载Card:

...
[    0.730000] ath79-spi ath79-spi: master is unqueued, this is deprecated
[    0.740000] m25p80 spi0.0: found en25f32, expected m25p80
[    0.750000] m25p80 spi0.0: en25f32 (4096 Kbytes)
[    0.750000] 5 tp-link partitions found on MTD device spi0.0
[    0.760000] Creating 5 MTD partitions on "spi0.0":
[    0.760000] 0x000000000000-0x000000020000 : "u-boot"
[    0.770000] 0x000000020000-0x00000013de00 : "kernel"
[    0.770000] mtd: partition "kernel" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only
[    0.790000] 0x00000013de00-0x0000003f0000 : "rootfs"
[    0.790000] mtd: partition "rootfs" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only
[    0.810000] mtd: partition "rootfs" set to be root filesystem
[    0.810000] mtd: partition "rootfs_data" created automatically, ofs=370000, len=80000
[    0.820000] 0x000000370000-0x0000003f0000 : "rootfs_data"
[    0.830000] 0x0000003f0000-0x000000400000 : "art"
[    0.840000] 0x000000020000-0x0000003f0000 : "firmware"
[    0.860000] libphy: ag71xx_mdio: probed
[    0.860000] eth0: Atheros AG71xx at 0xba000000, irq 5, mode:GMII
[    1.420000] eth0: Found an AR7240/AR9330 built-in switch
[    2.450000] eth1: Atheros AG71xx at 0xb9000000, irq 4, mode:MII
[    3.000000] ag71xx ag71xx.0 eth1: connected to PHY at ag71xx-mdio.1:04 [uid=004dd041, driver=Generic PHY]
[    3.050000] mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff
[    3.060000] TCP: cubic registered
[    3.060000] NET: Registered protocol family 17
[    3.070000] 8021q: 802.1Q VLAN Support v1.8
[    3.080000] VFS: Mounted root (squashfs filesystem) readonly on device 31:2.
[    3.090000] Freeing unused kernel memory: 268k freed
[    3.310000] mmc0: host does not support reading read-only switch. assuming write-enable.
[    3.320000] mmc0: new SD card on SPI
[    3.480000] mmcblk0: mmc0:0000 00000 1.90 GiB
[    3.490000]  mmcblk0: p1
...
Вид ошибки в случае НЕ обнаружения карточки памяти на уровне ядра:

未能在内核中找到存储卡的情况下的错误:

...
[    6.070000] mmc_spi spi0.1: SD/MMC host mmc0, no DMA, no WP, no poweroff
...
[    8.710000] mmc0: error -145 whilst initialising SD card
...
[   10.710000] mmc0: error -145 whilst initialising MMC card
...
Обнаруженные разделы:

设备发现:

root@OpenWrt:~# ls /dev/mmc*
/dev/mmcblk0    /dev/mmcblk0p1
root@OpenWrt:~#
Debug информация:

调试信息:

root@OpenWrt:~# cat /sys/kernel/debug/mmc0/ios
clock:          25000000 Hz
vdd:            20 (3.2 ~ 3.3 V)
bus mode:       2 (push-pull)
chip select:    1 (active high)
power mode:     2 (on)
bus width:      0 (1 bits)
timing spec:    0 (legacy)
signal voltage: 1 (3.30 V)
root@OpenWrt:~#

原文于2013/12/06 09:37更新。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值