Navigation

    全志在线开发者论坛

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • 在线文档
    • 社区主页

    在uboot下调用spi的sf_dataflash驱动报错

    MR Series
    2
    5
    1971
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      haiqianghuang69 LV 3 last edited by

      基于 韦东山的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 ###
      
      1 Reply Last reply Reply Quote Share 0
      • H
        haiqianghuang69 LV 3 last edited by

        尝试在D1的uboot上实现一个nor flash的读写的功能,想直接用drivers/mtd/spi/sf_dataflash.c的驱动程序,但调用失败。求问各位大佬怎么在uboot下实现一个nor flash的读写

        whycan 1 Reply Last reply Reply Quote Share 0
        • whycan
          whycan晕哥 LV 9 @haiqianghuang69 last edited by

          @haiqianghuang69
          是怎么失败的呢,有没有日志信息呢?

          H 2 Replies Last reply Reply Quote Share 0
          • H
            haiqianghuang69 LV 3 @whycan last edited by 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, , 
            
            
            1 Reply Last reply Reply Quote Share 1
            • H
              haiqianghuang69 LV 3 @whycan last edited by

              @whycan 刚开始贴的log打印,应该是程序的一些空指针的操作导致系统挂了

              1 Reply Last reply Reply Quote Share 0
              • 1 / 1
              • First post
                Last post

              Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

              行为准则 | 用户协议 | 隐私权政策