美文网首页嵌入式操作系统那些事儿
VxWorks 7下TI AM57XX CPSW网口调试问题总结

VxWorks 7下TI AM57XX CPSW网口调试问题总结

作者: 古斟布衣 | 来源:发表于2022-08-13 11:39 被阅读0次

1. 概述

  1. MAC驱动
    • compatible字符串: "ti,cpsw-switch-controller"
    • 组件:DRV_END_FDT_TI_CPSW
    • 主要文件:
      • net\end-2.0.3.2\drv\src\end\vxbFdtTiCpswEnd.c
      • net\end-2.0.3.2\drv\src\end\vxbFdtTiCpswEnd.h
      • net\end-2.0.3.2\drv\cdf\40vxbFdtTiCpswEnd.cdf
  2. PHY驱动
    • 组件:INCLUDE_MICREL_PHY
    • 主要文件:
      • net\end-2.0.3.2\drv\src\mii\vxbMicrelPhy.c
      • net\end-2.0.3.2\drv\src\mii\vxbMicrelPhy.h
      • net\end-2.0.3.2\drv\cdf\10mii.cdf
  3. 测试方法
    • VIP中使能INCLUDE_IPWRAP_IFCONFIG,编译;

    • shell中使用ifconfig命令正确设置IP,从PC侧ping单板网口;

    • 使用VxWorks blaster测试代码进行测试:

      • blasteeTCPvx.c/blasterTCPux.c:
        1. 板子上执行sp blasteeTCP,5000,16000,16000:
          -> sp blasteeTCP,5000,16000,16000
          Task spawned: id = 0x204c6cf0, name = t2
          value = 541879536 = 0x204c6cf0
          
        2. Linux PC上执行:
          gcc -O -Wall -DLINUX -o blasterTCP blasterTCPux.c
          ./blasterTCP 192.168.200.100 5000 16000 16000
          
        3. 板子上输出:
          -> interrupt: 17218708 bytes/sec
          interrupt: 34957807 bytes/sec
          interrupt: 34494040 bytes/sec
          interrupt: 34287064 bytes/sec
          interrupt: 34222559 bytes/sec
          interrupt: 34279281 bytes/sec
          interrupt: 34666203 bytes/sec
          interrupt: 34975009 bytes/sec
          interrupt: 35631638 bytes/sec
          
        4. 板子上执行blasteeTCPQuit退出 测试:
          -> blasteeTCPQuit
          blasteeTCP end.
          value = -1 = 0xffffffff
          
      • blasteeUDPvx.c/blasterUDPux.c:
        1. 板子上执行sp blasteeUDP,5000,1000,1000:
          -> sp blasteeUDP,5000,1000,1000
          Task spawned: id = 0x204c6cf0, name = t3
          value = 541879536 = 0x204c6cf0
          
        2. Linux PC上执行:
          gcc -O -Wall -DLINUX -o blasterUDP blasterUDPux.c
          ./blasterUDP 192.168.200.100 5000 1000 1000
          
        3. 板子上输出:
          -> interrupt: 20837600 bytes/sec
          interrupt: 34809800 bytes/sec
          interrupt: 58092300 bytes/sec
          interrupt: 56292000 bytes/sec
          interrupt: 58101600 bytes/sec
          interrupt: 57401300 bytes/sec
          interrupt: 57939400 bytes/sec
          interrupt: 58106600 bytes/sec
          interrupt: 54710600 bytes/sec
          
        4. 板子上执行blasteeUDPQuit退出 测试:
          -> blasteeUDPQuit
          blasteeUDP end.
          
          value = -1 = 0xffffffff
          
      • 第二个网口可以使用如下命令进行初始化,并进行同样的测试:
        -> ipcom_drv_eth_init "cpsw",1
        value = 0 = 0x0
        -> ifconfig "cpsw0 down"
        value = 0 = 0x0
        -> ifconfig "cpsw1 192.168.200.101 up"
        value = 0 = 0x0
        -> sp blasteeTCP,5000,16000,16000
        Task spawned: id = 0x2050f7c8, name = t1
        value = 542177224 = 0x2050f7c8
        -> interrupt: 28898693 bytes/sec
        interrupt: 41184702 bytes/sec
        interrupt: 35248939 bytes/sec
        interrupt: 34481075 bytes/sec
        interrupt: 34425039 bytes/sec
        interrupt: 34852720 bytes/sec
        interrupt: 34491524 bytes/sec
        interrupt: 38869289 bytes/sec
        interrupt: 46467280 bytes/sec
        interrupt: 43134397 bytes/sec
        
        -> blasteeTCPQuit
        blasteeTCP end.
        value = -1 = 0xffffffff
        -> sp blasteeUDP,5000,1000,1000
        Task spawned: id = 0x2050f7c8, name = t3
        value = 542177224 = 0x2050f7c8
        -> interrupt: 6305000 bytes/sec
        interrupt: 56270700 bytes/sec
        interrupt: 49631900 bytes/sec
        interrupt: 48110500 bytes/sec
        interrupt: 46237700 bytes/sec
        interrupt: 38053500 bytes/sec
        interrupt: 29870100 bytes/sec
        interrupt: 31047100 bytes/sec
        interrupt: 30627800 bytes/sec
        interrupt: 35647000 bytes/sec
        
        -> blasteeUDPQuit
        blasteeUDP end.
        value = -1 = 0xffffffff
        

      注意:第二个网口也可以通过CDF参数来配置:

      ```
      Parameter IFCONFIG_2 {
      NAME        Interface configuration.
      SYNOPSIS    Specifies the interface parameters to be configured when the stack is initialized, as a list of attribute-value strings
      DEFAULT     "ifname cpsw1","devname cpsw1","inet 192.168.100.100/24", "gateway 192.168.100.1"
      }
      ```
      
  4. 问题列表
    • 网口灯有时不亮
    • 网口收包数为0
    • 网口不能runing

2. 网口灯不亮

  1. 拔掉电源,重新上电若干次后可解决;
  2. 客户反应不需要关心网口灯,SR0500版本起来后一段时间后会通,而SR0650不行,但是PHY寄存器dump出来内存是一致的;
  3. SR0500中PHY驱动probe阶段重复5遍,可能是MII接口有问题,需要进一步调查;
  4. 修改vxbMicrelPhy.c驱动micrelPhyProbe()函数,重复读取设备ID,连续2次结果一致时退出循环匹配设备,最多5次,但是网口灯仍然不能恢复,因此应当属于无效修改;
  5. 修复DTS管脚配置后,网口灯上电一段时间后正常点亮。

3. 收包问题

3.1 问题描述

  1. 单板侧使用igconfig查看网口状态,发现链路状态为UP即链路已经已经建立,但是只有发包,没收包:
    -> ifconfig "cpsw0 192.168.200.100 up"
    value = 0 = 0x0
    -> ifconfig
    lo0     Link type:Local loopback
          inet 127.0.0.1  mask 255.255.255.255
          inet6 unicast fe80::1%lo0  prefixlen 64  automatic
          inet6 unicast ::1  prefixlen 128
          UP RUNNING LOOPBACK MULTICAST NOARP ALLMULTI
          MTU:1500  metric:1  VR:0  ifindex:1
          RX packets:0 mcast:0 errors:0 dropped:0
          TX packets:0 mcast:0 errors:0
          collisions:0 unsupported proto:0
          RX bytes:0  TX bytes:0
    
    cpsw0   Link type:Ethernet  HWaddr 74:e1:82:ea:d3:04
          capabilities: VLAN_MTU
          inet 192.168.200.100  mask 255.255.255.0  broadcast 192.168.200.255
          inet6 unicast fe80::76e1:82ff:feea:d304%cpsw0  prefixlen 64  automatic
          UP RUNNING SIMPLEX BROADCAST MULTICAST
          MTU:1500  metric:1  VR:0  ifindex:2
          RX packets:0 mcast:0 errors:0 dropped:0
          TX packets:8 mcast:5 errors:0
          collisions:0 unsupported proto:0
          RX bytes:0  TX bytes:564
    
    value = 0 = 0x0
    
  2. 增加INCLUDE_IPWRAP_PING组件,从单板侧ping PC,PC侧使用wireshark抓包,发现可以收到单板发出来的ARP查询报文,PC侧也回复了报文,但是单板侧收包数一直为零。

3.2 调试记录

  1. 接收中断处理增加打印信息:
    • vxbFdtTiCpswEnd.c中定义CPSW_DEBUG,使用DBG_MSG (DBG_ERR,"cpswEndRxInt\n");cpswEndRxInt()开头增加打印信息;
    • VSB中编译END_2_0_3_2
    • VIP中使能INCLUDE_DEBUG_KPRINTF并重新编译;
    • 无打印信息
  2. 发送中断(cpswEndTxInt())处理增加打印信息,无打印信息
  3. cpswPortAttach()中断挂接处检查vxbIntConnect返回值,无错误
  4. cpswPortAttach()中断挂接处打印vxbIntConnect参数即pSwCtrl,然后在shell中使用该参数手工调用cpswEndRxInt 0x2008e178,网口可ping通,因此可以确认是中断问题
  5. VIP中使能INCLUDE_ISR_SHOW并重新编译,shell中查看ISR信息,timer和串口的ISR均有调用,而网口的ISR未调用:
    -> isrShow
    ISR ID     Name                        Tag        HandlerRtn
    ---------- --------------------------- ---------- ------------------------------
    0x20083590 isr1                        106        tiAm3SiovxbInt
    0x200895e8 isr2                        70         299de8
    ...
    0x2008f110 isr9                        147        cpswEndRxInt
    0x2008f1b8 isr10                       148        cpswEndTxInt
    0x2008f260 isr11                       149        cpswEndMiscInt
    ...
    value = 0 = 0x0
    -> isrShow 0x2008f1b8
    ID                   : 0x2008f1b8
    Name                 : isr10
    Interrupt Tag        : 148
    Count                : 0
    Service Count        : 0
    Options              : 0x0
    Handler Routine      : cpswEndTxInt
    Argument             : 0x2008e178
    
    value = 0 = 0x0
    -> isrShow 0x2008f110
    ID                   : 0x2008f110
    Name                 : isr9
    Interrupt Tag        : 147
    Count                : 0
    Service Count        : 0
    Options              : 0x0
    Handler Routine      : cpswEndRxInt
    Argument             : 0x2008e178
    
    value = 0 = 0x0
    -> isrShow 0x20083590
    ID                   : 0x20083590
    Name                 : isr1
    Interrupt Tag        : 106
    Count                : 203
    Service Count        : 203
    Options              : 0x0
    Handler Routine      : tiAm3SiovxbInt
    Argument             : 0x200833f8
    
    value = 0 = 0x0
    -> isrShow 0x200895e8
    ID                   : 0x200895e8
    Name                 : isr2
    Interrupt Tag        : 70
    Count                : 30209
    Service Count        : 30209
    Options              : 0x0
    Handler Routine      : 299de8
    Argument             : 0x20089440
    
    value = 0 = 0x0
    
  6. 根据am572x_branson_ca15.dts文件,中断类型相同,因此应该不是中断控制器的问题
    dmtimer2: dmtimer@48032000     /* DM Timer 2 */
          {
          ...
          interrupts      = <70 0 4>;
          };
    cpsw_port1: port@1             /* port device*/
              {
              ...
              interrupts = <147 0 4>,    /* c0_rx_pend */
                           <148 0 4>,    /* c0_tx_pend */
                           <149 0 4>;    /* c0_misc_pend */
             ...
              };
    serial3: serial@48020000
          {
          ...
          interrupts  = <106 0 4>;
          ...
          };
    
  7. cpswEndStart()中断使能处检查vxbIntEnable返回值,无错误;
  8. 中断控制器驱动vxbFdtArmGenIntCtlr.c使能调试信息ARM_GIC_DBG,并在使能函数vxbArmGicIntEnableMethod()和中断入口vxbArmGicPreempISR()增加打印信息,中断号没有问题,并且在中断使能后没有打印,因此应该是网口驱动问题
  9. 对齐到572x参考BSPti_sitara_a15-2.0.4.1,未发现MAC相关问题,无改进;
  10. 对比SR0500版本vxbFdtTiCpswEnd.cvxbFdtTiCpswEnd.h,无特殊改动;
  11. 查看中断使能和状态寄存器以及中断机制:
  • 接收中断使能方法

    24.11.4.5.1 Receive Packet Completion Pulse Interrupt (RX_PULSE)
    The RX_PULSE interrupt is a pulse interrupt selected from the GMAC_SW RX_PEND[7:0] interrupts. The receive DMA controller has eight channels with each channel having a corresponding (RX_PEND[7:0]).
    The following steps will enable the receive packet completion interrupt:
    1. Enable the required channel interrupts of the DMA engine by setting 1 to the appropriate bit in the
    CPDMA_RX_INTMASK_SET register.
    1. The receive completion interrupt(s) to be routed to RX_PULSE is selected by setting one or more bits
    in the receive interrupt enable register (WR_C0_RX_EN) . The masked interrupt status can be read in
    the address location of RX_STAT bit in the WR_C0_RX_STAT register.

  • 发送中断使能方法

    24.11.4.5.2 Transmit Packet Completion Pulse Interrupt (TX_PULSE)
    The TX_PULSE interrupt is a pulse interrupt selected from the GMAC_SW TX_PEND[7:0] interrupts. The transmit DMA controller has eight channels with each channel having a corresponding (TX_PEND[7:0]).
    To enable the transmit packet completion interrupt:
    1. Enable the required channel interrupts of the DMA engine by setting 1 to the appropriate bit in the
    CPDMA_TX_INTMASK_SET register.
    1. The transmit completion interrupt(s) to be routed to TX_PULSE is selected by setting one or more bits
    in the transmit interrupt enable register WR_C0_TX_EN .The masked interrupt status can be read in
    the address location of TX_STAT bit in the WR_C0_TX_STAT register.

  • 相关寄存器偏移
    名称 地址
    CPDMA_TX_INTSTAT_RAW 0x4848 4880
    CPDMA_TX_INTSTAT_MASKED 0x4848 4884
    CPDMA_TX_INTMASK_SET 0x4848 4888
    CPDMA_TX_INTMASK_CLEAR 0x4848 488C
    CPDMA_IN_VECTOR 0x4848 4890
    CPDMA_EOI_VECTOR 0x4848 4894
    CPDMA_RX_INTSTAT_RAW 0x4848 48A0
    CPDMA_RX_INTSTAT_MASKED 0x4848 48A4
    CPDMA_RX_INTMASK_SET 0x4848 48A8
    CPDMA_RX_INTMASK_CLEAR 0x4848 48AC
    WR_C0_RX_EN 0x4848 5214
    WR_C0_TX_EN 0x4848 5218
    WR_C0_RX_STAT 0x4848 5244
    WR_C0_TX_STAT 0x4848 5248
  • cpswSwCtrlAttach()寄存器映射处打印pSwCtrl->regBase,得到虚拟地址为0x2213e000,对应于物理地址0x4848 4000
  • shell中查看寄存器内容,中断使能且收发中断状态均已置位:
    -> d 0x2213e880,16,4
      NOTE: memory values are displayed in hexadecimal.
      0x2213e880:  00000001 00000001 00000003 00000003  *................*
      0x2213e890:  00010001 00000000 00000000 00000000  *................*
      0x2213e8a0:  00000001 00000001 00000003 00000003  *................*
      0x2213e8b0:  00000000 00000000 00000002 00000002  *................*
      -> d 0x2213F200
      NOTE: memory values are displayed in hexadecimal.
      0x2213f200:  4edb1902 00000000 0000000a 00000000  *...N............*
      0x2213f210:  00000000 00000003 00000003 0000001f  *................*
      0x2213f220:  00000000 00000000 00000000 00000000  *................*
      0x2213f230:  00000000 00000000 00000000 00000000  *................*
      value = 0 = 0x0
      -> d 0x2213F240
      NOTE: memory values are displayed in hexadecimal.
      0x2213f240:  00000000 00000001 00000001 00000000  *................*
      0x2213f250:  00000000 00000000 00000000 00000000  *................*
      0x2213f260:  00000000 00000000 00000000 00000000  *................*
      0x2213f270:  00000000 00000000 00000000 00000000  *................*
      value = 0 = 0x0
    
  • 问题应当出在MAC驱动和中断控制器驱动之间的配合上
  1. BSP基于ti_sitara_a15-2.0.4.1修改,差别不大,因此基于该BSP创建VSB和VIP,注意VIP中使能INCLUDE_STANDALONE_DTB,启动后网口中断正常,因此应当是BSP配置问题,尤其是DTS问题
  • MAC和PHY设备中板子相关配置如下所示:
    cpsw_switch_controller: ethernet@48484000       /* ethernet system */
           {
           ....
    
           clocks            = <&gmac_rft_clk_mux>, <&gmac_gmii_ref_clk_div>;
           clock-names       = "gmac_rft_clk_mux","gmac_gmii_ref_clk_div";
           pinmux-0          = <&cpsw_pads>;       /* pinmux setting */
    
           cpsw_port1: port@4a002514             /* port device*/
               {
               ...
               cpsw-mac-save-way = <1>;
               local-mac-address = [ 00 40 47 E0 A8 32 ];
    
               phy-handle = <&phy1>;      /* port1 use phy1 */
               phy1: ethernet-phy@0       /* phy of port0 */
                   {
                   compatible     = "micrel,phy";
                   reg            = <0>;  /* phy address : 0 */
                   ...
                   };
               };
    
           cpsw_port2: port@4a00251c             /* port device*/
               {
               ...
               };
           };
    
    其中,
    • 时钟配置位于am572x_clock.dtsi中,对比ti_sitara_a15-2.0.4.1后发现dpll_mpu_ck: dpll_mpu_ck@4a005160节点的compatible字符串无效,应当从ti,omap5-mpu-dpll-clock修改为ti,omap4-dpll-mpu-clock,但是应当无MAC无关,尝试修改后没有影响
    • 管脚配置位于主dts文件中,对比后发现管脚复用节点多了一层pads0封装,如下所示:
      cm@4a002000     /* control module */
            {
            /* this device provide pads config */
            compatible = "ti,am5-pads";
            reg = <0x4a002000 0x2000>;
            #address-cells = <1>;
            #size-cells = <0>;
            pads@0
               {
               uart3_pads: uart0pads
                  {
                  pin-set = <
                              0x1648 0x4000e   /* rxd */
                              0x164c 0x4000e   /* txd */
                              >;
                  };
               ...
               };
      
  • 进一步检查os\drv\vxbus\subsystem\src\pinmux\vxbPinMuxLib.c中的vxbPinMuxEnable()->vxbPinMuxEnable()调用流程后发现,管脚复用节点的上一级被默认为管脚复用控制器即cm@4a002000,而不是pads@0因此导致管脚复用没有生效;下次遇到类似问题时,可以修改os\drv\vxbus\subsystem\src\pinmux\vxbPinMuxLib.c文件,将PINMUX_DBG打开,从而尽快发现错误;
  • 删除pads0封装后,中断可以正常上报,网口可以ping通。

4. 网口不能runing

  1. 网口起来后ifconfig查看网口状态不能runing:
    -> ifconfig
    lo0     Link type:Local loopback
          inet 127.0.0.1  mask 255.255.255.255
          inet6 unicast fe80::1%lo0  prefixlen 64  automatic
          inet6 unicast ::1  prefixlen 128
          UP RUNNING LOOPBACK MULTICAST NOARP ALLMULTI
          MTU:1500  metric:1  VR:0  ifindex:1
          RX packets:0 mcast:0 errors:0 dropped:0
          TX packets:0 mcast:0 errors:0
          collisions:0 unsupported proto:0
          RX bytes:0  TX bytes:0
    
    cpsw0   Link type:Ethernet  HWaddr 74:e1:82:ea:d3:04
          capabilities: VLAN_MTU
          inet 192.168.200.100  mask 255.255.255.0  broadcast 192.168.200.255
          inet6 unicast fe80::76e1:82ff:feea:d304%cpsw0  prefixlen 64  tentative  automatic
          UP SIMPLEX BROADCAST MULTICAST
          MTU:1500  metric:1  VR:0  ifindex:2
          RX packets:0 mcast:0 errors:0 dropped:0
          TX packets:0 mcast:0 errors:0
          collisions:0 unsupported proto:0
          RX bytes:0  TX bytes:0
    
  2. vxbFdtTiCpswEnd.c中定义CPSW_DEBUG并在VIP中使能INCLUDE_DEBUG_KPRINTF,网口正常工作
  3. SR0650基于ti_sitara_a15-2.0.4.1创建VSB和VIP,问题类似
  4. SR0500客户VIP版本中去除vxbFdtTiCpswEnd.c调试打印信息,网口无法runing
  5. SR0500客户VIP版本中恢复vxbFdtTiCpswEnd.c调试打印信息,网口可以runing
  6. shell中使用vxbDevShow查看设备状态,发现PHY设备未正确匹配驱动
    -> vxbDevShow
    mainbus-0 at root nexus level(0)
    mainbus-0: <TI_AM572X_BRANSON - Cortex-A15 (ARMV7A)>
       fdtBus-0 (refs: 2) on mainbus0 (refs: 2)
       fdtBus-0: <FDT bus controller> (0x20237808) level(1)
          simpleBus-0 (refs: 26) on fdtBus0 (refs: 2)
          simpleBus-0: <simple bus controller> (0x202378e8) level(2)
             ...
             cpsw switch controller-0 (refs: 2) on simpleBus0 (refs: 26)
             cpsw switch controller-0: <cpsw switch controller> (0x2029fba0) level(3)
                cpsw port-0 (refs: 1) on cpsw switch controller0 (refs: 2)
                cpsw port-0: <cpsw port> (0x2029fe08) level(4)
                   ▒4 -0 (refs: 0) on cpsw port0 (refs: 1)
                   ▒4 -0: <(no driver attached)> (0x202a9c90) level(5)
                cpsw port-1 (refs: 1) on cpsw switch controller0 (refs: 2)
                cpsw port-1: <cpsw port> (0x202a9ed8) level(4)
                   -0 (refs: 0) on cpsw port1 (refs: 1)
                   -0: <(no driver attached)> (0x2034fc50) level(5)
             ...
          cpus-0 (refs: 0) on fdtBus0 (refs: 2)
          cpus-0: <(no driver attached)> (0x205edb40) level(2)
       virtBus-0 (refs: 0) on mainbus0 (refs: 2)
       virtBus-0: <(no driver attached)> (0x205edc30) level(1)
    value = 543087664 = 0x205edc30
    
  7. 修改vxbMicrelPhy.c驱动micrelPhyProbe()函数,probe次数改为SR500的5次,问题依旧
  8. 修改vxbMicrelPhy.c驱动micrelPhyProbe()函数,probe次数改为无限次,问题消失
  9. 修改vxbMicrelPhy.c驱动micrelPhyProbe()函数,probe次数改为无限次,并记录最大peobe次数,CPSW0的probe次数为114~117次, CPSW1的probe次数为1次,因此应该是PHY设备的MII接口时序不稳定,只能workaround;SR0500只需要5次是因为使能调试后在网口驱动和PHY驱动之间加入了延时,从而大多数情况只需要1次就可以probe成功,偶尔需要4次才能成功;
  10. 修改vxbMicrelPhy.c驱动micrelPhyProbe()函数,probe次数改为128次问题解决:
    LOCAL STATUS micrelPhyProbe
      (
      VXB_DEV_ID pDev
      )
      {
      ...
      pPhyDev = vxbDevIvarsGet(pDev);
      for(i = 0; i < 128; i++)
         {
         ...
         if( miiOui == MICREL_OUI_ID )
               {
               /* match Micrel PHY ID exactly */
    
               return OK;
               }
         }
    
      return ERROR;
      }
    

相关文章

网友评论

    本文标题:VxWorks 7下TI AM57XX CPSW网口调试问题总结

    本文链接:https://www.haomeiwen.com/subject/wldqgrtx.html