在uboot下调用spi的sf_dataflash驱动报错
-
基于 韦东山的neza-d1-buildroot源码
1.make menuconfig,选择spi以及允许DM
2.配置dts+ spi1: spi@04026000 { + //#address-cells = <1>; + //#size-cells = <0>; + compatible = "allwinner,sun20i-spi"; + device_type = "spi1"; + reg = <0x0 0x04026000 0x0 0x1000>; + //interrupts-extended = <&plic0 31 IRQ_TYPE_LEVEL_HIGH>; + //clocks = <&ccu CLK_PLL_PERIPH0>, <&ccu CLK_SPI0>, <&ccu CLK_BUS_SPI0>; + //clock-names = "pll", "mod", "bus"; + //resets = <&ccu RST_BUS_SPI0>; + clock-frequency = <100000000>; + pinctrl-names = "default", "sleep"; + spi1_cs_number = <1>; + spi1_cs_bitmap = <1>; + spi_slave_mode = <0>; + //dmas = <&dma 22>, <&dma 22>; + //dma-names = "tx", "rx"; + pinctrl-0 = <&spi1_pins_a &spi1_pins_b>; + pinctrl-1 = <&spi1_pins_c>; + status = "okay"; + spi-nor { + compatible = "jedec,spi-nor"; + spi-max-frequency=<0x5F5E100>; + reg = <0x0>; + spi-rx-bus-width=<0x01>; + spi-tx-bus-width=<0x01>; + status="okay"; + }; + }; + + + spi1_pins_a: spi1@0 { + allwinner,pins = "PD11", "PD12", "PD13","PD14", "PD15"; + allwinner,pname = "spi1_sclk", "spi1_mosi","spi1_miso", "spi1_hold", "spi1_wp"; + allwinner,function = "spi1"; + allwinner,muxsel = <4>; + allwinner,drive = <1>; + allwinner,pull = <0>; + }; + + spi1_pins_b: spi1@1 { + allwinner,pins = "PD10"; + allwinner,pname = "spi1_cs0"; + allwinner,function = "spi1"; + allwinner,muxsel = <4>; + allwinner,drive = <1>; + allwinner,pull = <1>; // only CS should be pulled up + }; + + spi1_pins_c: spi1@2 { + allwinner,pins = "PD10", "PD11", "PD12", "PD13","PD14", "PD15"; + allwinner,function = "gpio_in"; + allwinner,muxsel = <0>; + allwinner,drive = <1>; + allwinner,pull = <0>; + };
3.自定义一个cmd/hello程序,通过uclass_get_device_by_name获取device。执行write方法,串口输出有报错,
Unhandled exception: Load access fault EPC: 000000005ff2d380 TVAL: 00000002e3035e0a ### ERROR ### Please RESET the board ###
-
尝试在D1的uboot上实现一个nor flash的读写的功能,想直接用drivers/mtd/spi/sf_dataflash.c的驱动程序,但调用失败。求问各位大佬怎么在uboot下实现一个nor flash的读写
-
@haiqianghuang69
是怎么失败的呢,有没有日志信息呢? -
@whycan
1.追查下来发现在绑定udevice的时候,probe没有获取到一个size,导致没有给一个parent_priv分配内存空间,尝试在U_BOOT_DRIVER上面添加一个per_child_auto_alloc_size,但没有生效,就直接在源码上赋值了(从其他地方打印这个size值为48)181 U_BOOT_DRIVER(spi_flash_std) = { 182 .name = "spi_flash_std", 183 .id = UCLASS_SPI_FLASH, 184 .of_match = spi_flash_std_ids, 185 .probe = spi_flash_std_probe, 186 .remove = spi_flash_std_remove, 187 .priv_auto_alloc_size = sizeof(struct spi_flash), + 188 .per_child_auto_alloc_size = sizeof(struct spi_slave),//在这里赋值没有生效 189 .ops = &spi_flash_std_ops, 190 }; //drivers/core/device.c 343 if (dev->parent) { + 344 printf("device_probe, get parent size\n"); 345 size = dev->parent->driver->per_child_auto_alloc_size; 346 if (!size) { ~ 348 size = dev->parent->uclass->uc_drv->per_child_auto_alloc_size; 349 } + 350 if (!size){ + 352 //size = sizeof(struct spi_slave);//有报错 + 353 size = 48;//通过其他地方打印的spi_slave大小 + 354 } + 355 357 if (size && !dev->parent_priv) {//分配parent_priv空间 358 dev->parent_priv = alloc_priv(size, drv->flags); 360 if (!dev->parent_priv) { 362 ret = -ENOMEM; 363 goto fail; 364 } 365 } 366
2.搞完第一步后,发现上电后就卡住了,经加log发现是在spi_claim_bus这里运行不下去
//drivers/mtd/spi/sf_probe.c 25 static int spi_flash_probe_slave(struct spi_flash *flash) 26 { 27 struct spi_slave *spi = flash->spi;//通过打印,flash传进来的是udevice ,spi@04026000 28 int ret; 29 30 /* Setup spi_slave */ 31 if (!spi) { 33 return -ENODEV; 34 } 35 37 /* Claim spi bus */ ~ 38 ret = spi_claim_bus(spi);//这里是调用到drivers/spi/spi-uclass.c的实现 39 if (ret) { 40 debug("SF: Failed to claim SPI bus: %d\n", ret); 41 return ret; 42 } //drivers/spi/spi-uclass.c int spi_claim_bus(struct spi_slave *slave) { return log_ret(dm_spi_claim_bus(slave->dev)); } 50 int dm_spi_claim_bus(struct udevice *dev) 51 { + 52 pr_err("spi/spi-uclass, spi_claim_bus->dm_spi_claim_bus\n\n"); + 53 54 struct udevice *bus = dev->parent; ~ 55 if (bus == NULL){ + 56 pr_err("debug, is null pointer\n"); + 57 }else{ + 58 pr_err("debug, spi_get_ops, bus = dev->parent, , \n");//貌似不能直接获取结构体内容 + 61 struct dm_spi_ops *ops = spi_get_ops(bus);//这里的bus应该是一个父设备,这里获取父设备的ops,最终是卡在这里,spi_get_ops是获取bus->driver->ops + 62 } + 63
分析代码是spi_claim_bus函数里面想拿执行spi_get_opt(bus),但程序跑到这里就卡住没往下执行了,应该是一个空的内容
串口打印如下:
[02.207]debug, spi_claim_bus, [02.210]spi/spi-uclass, spi_claim_bus->dm_spi_claim_bus [02.215]debug, spi_get_ops, bus = dev->parent, ,
-
@whycan 刚开始贴的log打印,应该是程序的一些空指针的操作导致系统挂了
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号