Author: tz61

  • USB Related

    Reference

    USB in a Nutshell

    USB HID

    HID’s bDeviceClass in Device descriptor is 0, but class code is defined in Interface Descriptor, where bInterfaceClass is 3

    The USB Core Specification defines the HID class code. The bInterfaceClass
    member of an Interface descriptor is always 3 for HID class devices.

    Source: HID1_11.pdf from usb.org
    device info for HID is inside the interface descriptor like:

          bInterfaceClass         3 Human Interface Device
          bInterfaceSubClass      1 Boot Interface Subclass
          bInterfaceProtocol      1 Keyboard

    For HID devices, there is also a descriptor called Report Descriptor

    查询HID Report Descriptor:
    先unbind usbhid:

    meta@meta-desktop:~$ echo -n "1-2.2:1.0" | sudo tee /sys/bus/usb/drivers/usbhid/unbind

    然后

    meta@meta-desktop:~$ udevadm info -a -p /sys/bus/usb/devices/1-2.2
    
    Udevadm info starts with the device specified by the devpath and then
    walks up the chain of parent devices. It prints for every device
    found, all possible attributes in the udev rules key format.
    A rule to match, can be composed by the attributes of the device
    and the attributes from one single parent device.
    
      looking at device '/devices/platform/bus@0/3610000.usb/usb1/1-2/1-2.2':
        KERNEL=="1-2.2"
        SUBSYSTEM=="usb"
        DRIVER=="usb"
        ATTR{authorized}=="1"
        ATTR{avoid_reset_quirk}=="0"
        ATTR{bConfigurationValue}=="1"
        ATTR{bDeviceClass}=="00"
        ATTR{bDeviceProtocol}=="00"
        ATTR{bDeviceSubClass}=="00"
        ATTR{bMaxPacketSize0}=="64"
        ATTR{bMaxPower}=="100mA"
        ATTR{bNumConfigurations}=="1"
        ATTR{bNumInterfaces}==" 1"
        ATTR{bcdDevice}=="8891"
        ATTR{bmAttributes}=="e0"
        ATTR{busnum}=="1"
        ATTR{configuration}==""
        ATTR{devnum}=="7"
        ATTR{devpath}=="2.2"
        ATTR{devspec}=="(null)"
        ATTR{idProduct}=="0220"
        ATTR{idVendor}=="5000"
        ATTR{ltm_capable}=="no"
        ATTR{maxchild}=="0"
        ATTR{power/active_duration}=="6989392"
        ATTR{power/autosuspend}=="2"
        ATTR{power/autosuspend_delay_ms}=="2000"
        ATTR{power/connected_duration}=="6989392"
        ATTR{power/control}=="on"
        ATTR{power/level}=="on"
        ATTR{power/persist}=="1"
        ATTR{power/runtime_active_time}=="6988860"
        ATTR{power/runtime_status}=="active"
        ATTR{power/runtime_suspended_time}=="0"
        ATTR{power/wakeup}=="enabled"
        ATTR{power/wakeup_abort_count}=="0"
        ATTR{power/wakeup_active}=="0"
        ATTR{power/wakeup_active_count}=="0"
        ATTR{power/wakeup_count}=="0"
        ATTR{power/wakeup_expire_count}=="0"
        ATTR{power/wakeup_last_time_ms}=="0"
        ATTR{power/wakeup_max_time_ms}=="0"
        ATTR{power/wakeup_total_time_ms}=="0"
        ATTR{product}=="Bluetooth Keyboard"
        ATTR{quirks}=="0x0"
        ATTR{removable}=="unknown"
        ATTR{rx_lanes}=="1"
        ATTR{speed}=="12"
        ATTR{tx_lanes}=="1"
        ATTR{urbnum}=="35"
        ATTR{version}==" 2.00"
    meta@meta-desktop:~$ sudo lsusb -vvvd 5000:0220
    
    Bus 001 Device 007: ID 5000:0220  Bluetooth Keyboard
    Device Descriptor:
      bLength                18
      bDescriptorType         1
      bcdUSB               2.00
      bDeviceClass            0
      bDeviceSubClass         0
      bDeviceProtocol         0
      bMaxPacketSize0        64
      idVendor           0x5000
      idProduct          0x0220
      bcdDevice           88.91
      iManufacturer           0
      iProduct                2 Bluetooth Keyboard
      iSerial                 0
      bNumConfigurations      1
      Configuration Descriptor:
        bLength                 9
        bDescriptorType         2
        wTotalLength       0x0022
        bNumInterfaces          1
        bConfigurationValue     1
        iConfiguration          0
        bmAttributes         0xe0
          Self Powered
          Remote Wakeup
        MaxPower              100mA
        Interface Descriptor:
          bLength                 9
          bDescriptorType         4
          bInterfaceNumber        0
          bAlternateSetting       0
          bNumEndpoints           1
          bInterfaceClass         3 Human Interface Device
          bInterfaceSubClass      1 Boot Interface Subclass
          bInterfaceProtocol      1 Keyboard
          iInterface              0
            HID Device Descriptor:
              bLength                 9
              bDescriptorType        33
              bcdHID               1.11
              bCountryCode            0 Not supported
              bNumDescriptors         1
              bDescriptorType        34 Report
              wDescriptorLength     240
              Report Descriptor: (length is 240)
                Item(Global): Usage Page, data= [ 0x01 ] 1
                                Generic Desktop Controls
                Item(Local ): Usage, data= [ 0x06 ] 6
                                Keyboard
                Item(Main  ): Collection, data= [ 0x01 ] 1
                                Application
                Item(Global): Report ID, data= [ 0x01 ] 1
                Item(Global): Usage Page, data= [ 0x07 ] 7
                                Keyboard
                Item(Local ): Usage Minimum, data= [ 0xe0 ] 224
                                Control Left
                Item(Local ): Usage Maximum, data= [ 0xe7 ] 231
                                GUI Right
                Item(Global): Logical Minimum, data= [ 0x00 ] 0
                Item(Global): Logical Maximum, data= [ 0x01 ] 1
                Item(Global): Report Size, data= [ 0x01 ] 1
                Item(Global): Report Count, data= [ 0x08 ] 8
                Item(Main  ): Input, data= [ 0x02 ] 2
                                Data Variable Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Global): Report Count, data= [ 0x01 ] 1
                Item(Global): Report Size, data= [ 0x08 ] 8
                Item(Main  ): Input, data= [ 0x03 ] 3
                                Constant Variable Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Global): Report Count, data= [ 0x05 ] 5
                Item(Global): Report Size, data= [ 0x01 ] 1
                Item(Global): Usage Page, data= [ 0x08 ] 8
                                LEDs
                Item(Local ): Usage Minimum, data= [ 0x01 ] 1
                                NumLock
                Item(Local ): Usage Maximum, data= [ 0x05 ] 5
                                Kana
                Item(Main  ): Output, data= [ 0x02 ] 2
                                Data Variable Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Global): Report Count, data= [ 0x01 ] 1
                Item(Global): Report Size, data= [ 0x03 ] 3
                Item(Main  ): Output, data= [ 0x03 ] 3
                                Constant Variable Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Global): Report Count, data= [ 0x06 ] 6
                Item(Global): Report Size, data= [ 0x08 ] 8
                Item(Global): Logical Minimum, data= [ 0x00 ] 0
                Item(Global): Logical Maximum, data= [ 0x65 ] 101
                Item(Global): Usage Page, data= [ 0x07 ] 7
                                Keyboard
                Item(Local ): Usage Minimum, data= [ 0x00 ] 0
                                No Event
                Item(Local ): Usage Maximum, data= [ 0x65 ] 101
                                Keyboard Application (Windows Key for Win95 or Compose)
                Item(Main  ): Input, data= [ 0x00 ] 0
                                Data Array Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Main  ): End Collection, data=none
                Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
                                (null)
                Item(Local ): Usage, data= [ 0x02 ] 2
                                (null)
                Item(Main  ): Collection, data= [ 0x01 ] 1
                                Application
                Item(Global): Report ID, data= [ 0x02 ] 2
                Item(Global): Report Size, data= [ 0x08 ] 8
                Item(Global): Report Count, data= [ 0x01 ] 1
                Item(Global): Logical Minimum, data= [ 0x01 ] 1
                Item(Global): Logical Maximum, data= [ 0x64 ] 100
                Item(Local ): Usage, data= [ 0x20 ] 32
                                (null)
                Item(Main  ): Input, data= [ 0x00 ] 0
                                Data Array Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Main  ): End Collection, data=none
                Item(Global): Usage Page, data= [ 0x0c ] 12
                                Consumer
                Item(Local ): Usage, data= [ 0x01 ] 1
                                Consumer Control
                Item(Main  ): Collection, data= [ 0x01 ] 1
                                Application
                Item(Global): Report ID, data= [ 0x03 ] 3
                Item(Local ): Usage Minimum, data= [ 0x00 ] 0
                                Unassigned
                Item(Local ): Usage Maximum, data= [ 0x3c 0x02 ] 572
                                AC Format
                Item(Global): Logical Minimum, data= [ 0x00 ] 0
                Item(Global): Logical Maximum, data= [ 0x3c 0x02 ] 572
                Item(Global): Report Count, data= [ 0x01 ] 1
                Item(Global): Report Size, data= [ 0x10 ] 16
                Item(Main  ): Input, data= [ 0x00 ] 0
                                Data Array Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Main  ): End Collection, data=none
                Item(Global): Usage Page, data= [ 0x01 ] 1
                                Generic Desktop Controls
                Item(Local ): Usage, data= [ 0x80 ] 128
                                System Control
                Item(Main  ): Collection, data= [ 0x01 ] 1
                                Application
                Item(Global): Report ID, data= [ 0x04 ] 4
                Item(Local ): Usage Minimum, data= [ 0x81 ] 129
                                System Power Down
                Item(Local ): Usage Maximum, data= [ 0x83 ] 131
                                System Wake Up
                Item(Global): Logical Minimum, data= [ 0x00 ] 0
                Item(Global): Logical Maximum, data= [ 0x01 ] 1
                Item(Global): Report Size, data= [ 0x01 ] 1
                Item(Global): Report Count, data= [ 0x03 ] 3
                Item(Main  ): Input, data= [ 0x02 ] 2
                                Data Variable Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Global): Report Count, data= [ 0x05 ] 5
                Item(Main  ): Input, data= [ 0x03 ] 3
                                Constant Variable Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Main  ): End Collection, data=none
                Item(Global): Usage Page, data= [ 0x01 ] 1
                                Generic Desktop Controls
                Item(Local ): Usage, data= [ 0x02 ] 2
                                Mouse
                Item(Main  ): Collection, data= [ 0x01 ] 1
                                Application
                Item(Global): Report ID, data= [ 0x06 ] 6
                Item(Local ): Usage, data= [ 0x01 ] 1
                                Pointer
                Item(Main  ): Collection, data= [ 0x00 ] 0
                                Physical
                Item(Global): Usage Page, data= [ 0x09 ] 9
                                Buttons
                Item(Local ): Usage Minimum, data= [ 0x01 ] 1
                                Button 1 (Primary)
                Item(Local ): Usage Maximum, data= [ 0x03 ] 3
                                Button 3 (Tertiary)
                Item(Global): Logical Minimum, data= [ 0x00 ] 0
                Item(Global): Logical Maximum, data= [ 0x01 ] 1
                Item(Global): Report Size, data= [ 0x01 ] 1
                Item(Global): Report Count, data= [ 0x03 ] 3
                Item(Main  ): Input, data= [ 0x02 ] 2
                                Data Variable Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Global): Report Size, data= [ 0x05 ] 5
                Item(Global): Report Count, data= [ 0x01 ] 1
                Item(Main  ): Input, data= [ 0x01 ] 1
                                Constant Array Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Global): Usage Page, data= [ 0x01 ] 1
                                Generic Desktop Controls
                Item(Local ): Usage, data= [ 0x30 ] 48
                                Direction-X
                Item(Local ): Usage, data= [ 0x31 ] 49
                                Direction-Y
                Item(Local ): Usage, data= [ 0x38 ] 56
                                Wheel
                Item(Global): Logical Minimum, data= [ 0x81 ] 129
                Item(Global): Logical Maximum, data= [ 0x7f ] 127
                Item(Global): Report Size, data= [ 0x08 ] 8
                Item(Global): Report Count, data= [ 0x03 ] 3
                Item(Main  ): Input, data= [ 0x06 ] 6
                                Data Variable Relative No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Main  ): End Collection, data=none
                Item(Main  ): End Collection, data=none
                Item(Global): Usage Page, data= [ 0x01 ] 1
                                Generic Desktop Controls
                Item(Local ): Usage, data= [ 0x06 ] 6
                                Keyboard
                Item(Main  ): Collection, data= [ 0x01 ] 1
                                Application
                Item(Global): Report ID, data= [ 0x07 ] 7
                Item(Global): Usage Page, data= [ 0x07 ] 7
                                Keyboard
                Item(Local ): Usage Minimum, data= [ 0xe0 ] 224
                                Control Left
                Item(Local ): Usage Maximum, data= [ 0xe7 ] 231
                                GUI Right
                Item(Global): Logical Minimum, data= [ 0x00 ] 0
                Item(Global): Logical Maximum, data= [ 0x01 ] 1
                Item(Global): Report Size, data= [ 0x01 ] 1
                Item(Global): Report Count, data= [ 0x08 ] 8
                Item(Main  ): Input, data= [ 0x02 ] 2
                                Data Variable Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Global): Report Count, data= [ 0x07 ] 7
                Item(Global): Report Size, data= [ 0x08 ] 8
                Item(Main  ): Input, data= [ 0x03 ] 3
                                Constant Variable Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Global): Report Count, data= [ 0x06 ] 6
                Item(Global): Report Size, data= [ 0x08 ] 8
                Item(Global): Logical Minimum, data= [ 0x00 ] 0
                Item(Global): Logical Maximum, data= [ 0x65 ] 101
                Item(Global): Usage Page, data= [ 0x07 ] 7
                                Keyboard
                Item(Local ): Usage Minimum, data= [ 0x00 ] 0
                                No Event
                Item(Local ): Usage Maximum, data= [ 0x65 ] 101
                                Keyboard Application (Windows Key for Win95 or Compose)
                Item(Main  ): Input, data= [ 0x00 ] 0
                                Data Array Absolute No_Wrap Linear
                                Preferred_State No_Null_Position Non_Volatile Bitfield
                Item(Main  ): End Collection, data=none
          Endpoint Descriptor:
            bLength                 7
            bDescriptorType         5
            bEndpointAddress     0x81  EP 1 IN
            bmAttributes            3
              Transfer Type            Interrupt
              Synch Type               None
              Usage Type               Data
            wMaxPacketSize     0x0008  1x 8 bytes
            bInterval               1
    can't get device qualifier: Resource temporarily unavailable
    can't get debug descriptor: Resource temporarily unavailable
    Device Status:     0x0001
      Self Powered
    meta@meta-desktop:~$
  • Udev binding for device like can0, ttyUSB0 to prevent device number swapping.

    How-to

    For platform unique device like mttcan on Jetson Orin Nano

    meta@meta-desktop:/etc/udev/rules.d$ sudo udevadm info /sys/class/net/can0
    P: /devices/platform/bus@0/c310000.mttcan/net/can0
    L: 0
    E: DEVPATH=/devices/platform/bus@0/c310000.mttcan/net/can0
    E: INTERFACE=can0
    E: IFINDEX=2
    E: SUBSYSTEM=net
    E: USEC_INITIALIZED=10728608
    E: ID_MM_CANDIDATE=1
    E: ID_PATH=platform-c310000.mttcan
    E: ID_PATH_TAG=platform-c310000_mttcan
    E: ID_NET_DRIVER=mttcan
    E: ID_NET_LINK_FILE=/usr/lib/systemd/network/99-default.link
    E: ID_NET_NAME=can0
    E: SYSTEMD_ALIAS=/sys/subsystem/net/devices/can0
    E: TAGS=:systemd:
    E: CURRENT_TAGS=:systemd:

    So the core idea is, find what’s unique and immutable for this device, and then set its name
    Here the mttcan’s DEVPATH is unique and immutable, so we can use this as a handle to change its name.
    Modify /etc/udev/rules.d/01-nvcan.rules

    DEVPATH=="/devices/platform/bus@0/c310000.mttcan/net/*", NAME="can_mttcan"

    And then reload it by reboot, since it is a platform probed device, not something like usb ch340 device which can take effect immediately.
    After reboot we can see by running ip addr, can0 is now renamed to can_mttcan

    meta@meta-desktop:/etc/udev/rules.d$ ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
        inet6 ::1/128 scope host 
           valid_lft forever preferred_lft forever
    2: can_mttcan: <NOARP,ECHO> mtu 16 qdisc noop state DOWN group default qlen 10
        link/can 
    3: enP8p1s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
        link/ether 48:b0:2d:d8:c9:5e brd ff:ff:ff:ff:ff:ff
    5: l4tbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
        link/ether 3e:c7:e7:79:f3:87 brd ff:ff:ff:ff:ff:ff
        inet 192.168.55.1/24 brd 192.168.55.255 scope global l4tbr0
           valid_lft forever preferred_lft forever
        inet6 fe80::1/128 scope link noprefixroute 
           valid_lft forever preferred_lft forever
        inet6 fe80::3cc7:e7ff:fe79:f387/64 scope link 
           valid_lft forever preferred_lft forever
    6: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master l4tbr0 state UP group default qlen 1000
        link/ether 86:1b:04:83:56:29 brd ff:ff:ff:ff:ff:ff
        inet6 fe80::841b:4ff:fe83:5629/64 scope link 
           valid_lft forever preferred_lft forever
    7: usb1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master l4tbr0 state UP group default qlen 1000
        link/ether 86:1b:04:83:56:2b brd ff:ff:ff:ff:ff:ff
        inet6 fe80::841b:4ff:fe83:562b/64 scope link 
           valid_lft forever preferred_lft forever
    8: enxba144d3cc73b: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether ba:14:4d:3c:c7:3b brd ff:ff:ff:ff:ff:ff
        inet 172.20.10.6/28 brd 172.20.10.15 scope global dynamic noprefixroute enxba144d3cc73b
           valid_lft 85907sec preferred_lft 85907sec
        inet6 2409:8929:d29:93ae:bf1b:9b91:aab4:9339/64 scope global temporary dynamic 
           valid_lft 602677sec preferred_lft 83862sec
        inet6 2409:8929:d29:93ae:b6bb:8f67:c24c:c90d/64 scope global mngtmpaddr noprefixroute 
           valid_lft forever preferred_lft forever
        inet6 fe80::29e8:54a5:700d:59dd/64 scope link noprefixroute 
           valid_lft forever preferred_lft forever

    For usb-hub can and tty interface

    DEVPATH=="/devices/*.3:1.0/net/can*", NAME="can_chassis"
    DEVPATH=="/devices/*.4:1.0/net/can*", NAME="can_gimbal"

    Reference

    udevadm tool
    udev
    writing_udev_rules(obsolete)

  • RK3566 的 EMMC接口DS 怎么接?

    总结

    Rk3566的emmc接口最高支持hs200 (200MHz SDR)
    HPS SD/eMMC Timing Characteristics
    可以看到, DataStrobe是一个 emmc颗粒向rk3566主控发送的信号,而且只有在hs400模式下启用. 因此rk3566的datastrobe没有任何作用可以不接.

  • 为瑞芯微设备手动创建emmc镜像

    Device description

    设备:rk3566
    emmc:8GB/32GB Sandisk emmc
    Host: Ubuntu22.04(24.04’s qemu has problem when creating ubuntu base rootfs, so skip it)
    参考: 【每周学习摘要06(23/10/27-23/11/10)】

    制作过程

    编译组件

    DDR+SPL loader

    U-boot

    Kernel

    Image, ko and dtb files,TBD

    制作boot.img

    boot.img包含kernel以及设备树等,以及uboot保存的env(saveenv)
    预留63M空间足以(未压缩的Image最大50MiB), 如果要更大,请修改parameter.txt以防止烧录时干涉rootfs分区

    touch boot.img
    dd if=/dev/zero of=boot.img bs=1M count=63
    sync
    mkfs.fat boot.img
    sync
    sudo mount boot.img /mnt
    sudo cp -a -r boot/* /mnt
    sync
    sudo umount /mnt

    制作Ubuntu 2204 rootfs

    下载Ubuntu base 2204

    地址:https://cdimage.ubuntu.com/ubuntu-base/releases/jammy/release/

    wget https://cdimage.ubuntu.com/ubuntu-base/releases/jammy/release/ubuntu-base-22.04.5-base-arm64.tar.gz
    mkdir rootfs && tar --same-owner -xf ubuntu-base-22.04.5-base-arm64.tar.gz -C rootfs

    Note you shall
    添加dns解析

    echo nameserver 114.114.114.114 > rootfs/etc/resolv.conf

    以及apt源(vim rootfs/etc/apt/source.list)

    deb [trusted=yes] http://mirrors.aliyun.com/ubuntu-ports/ jammy main restricted
    deb [trusted=yes] http://mirrors.aliyun.com/ubuntu-ports/ jammy-updates main restricted
    deb [trusted=yes] http://mirrors.aliyun.com/ubuntu-ports/ jammy universe
    deb [trusted=yes] http://mirrors.aliyun.com/ubuntu-ports/ jammy-updates universe
    deb [trusted=yes] http://mirrors.aliyun.com/ubuntu-ports/ jammy multiverse
    deb [trusted=yes] http://mirrors.aliyun.com/ubuntu-ports/ jammy-updates multiverse
    deb [trusted=yes] http://mirrors.aliyun.com/ubuntu-ports/ jammy-backports main restricted universe multiverse
    deb [trusted=yes] http://mirrors.aliyun.com/ubuntu-ports/ jammy-security main restricted
    deb [trusted=yes] http://mirrors.aliyun.com/ubuntu-ports/ jammy-security universe
    deb [trusted=yes] http://mirrors.aliyun.com/ubuntu-ports/ jammy-security multiverse

    进入环境后更新apt 源并且下载必要包

    sudo chroot rootfs
    apt update
    apt upgrade
    apt install vim sudo kmod net-tools ethtool ifupdown language-pack-en-base rsyslog htop iputils-ping udev systemd network-manager -y

    change passwd for root

    passwd root

    create user meta

    adduser meta

    add meta to sudoers
    chmod +w /etc/sudoers
    vim /etc/sudoers
    on line 44

    # User privilege specification
    root    ALL=(ALL:ALL) ALL
    meta    ALL=(ALL:ALL) ALL

    Finally pack it
    return to the father of rootfs directory.
    Create a rootfs.img buffer with 1G size
    shrink its size by e2fsck and resize2fs

    touch rootfs.img
    dd if=/dev/zero of=rootfs.img bs=1M count=900
    sync
    mkfs.ext4 rootfs.img
    sudo mount rootfs.img /mnt
    sudo cp -a -r rootfs/* /mnt
    sync
    sudo umount /mnt
    e2fsck -f -p rootfs.img
    resize2fs -M rootfs.img

    You can adjust count in the second command by check fs usage by mounting it to /mnt and then check df -h. To achieve a smaller image size, better make the Available space to be less than 50M.
    example:

    ➜  my-emmc-image df -h
    Filesystem      Size  Used Avail Use% Mounted on
    tmpfs           6.3G  2.2M  6.3G   1% /run
    /dev/nvme1n1p3   60G   31G   27G  54% /
    tmpfs            32G  148M   32G   1% /dev/shm
    tmpfs           5.0M  4.0K  5.0M   1% /run/lock
    efivarfs        268K  144K  120K  55% /sys/firmware/efi/efivars
    /dev/nvme0n1p1  256M   49M  208M  19% /boot/efi
    tmpfs           6.3G   64K  6.3G   1% /run/user/1000
    /dev/nvme0n1p5  480G  405G   51G  89% /media/ztn/4ca5df7c-065c-4b2b-b868-bab13a2816b0
    /dev/loop10     868M  783M   24M  98% /mnt
    

    拷贝网卡驱动

    TBD, both kernel and user space

    拷贝Mali GPU 显卡驱动

    TBD, only mali so libs

    zju weblogin script

    if you want to accesss net after connecting to ZJUWLAN but lacks of a webbrowser to authenticate, you can use
    https://github.com/Mythologyli/zju-web-login

    First install python3

    apt install python3

    then follow https://pip.pypa.io/en/stable/installation/ to install pip
    By using host’s system’s wget, we can get rid of downloading wget and its dependency.

    su meta
    cd ~
    wget https://bootstrap.pypa.io/get-pip.py
    python3 get-pip.py

    In order to shrink the rootfs size, don’t install git but rather clone by downloading.
    Again, by using host’s system’s wget, to avoid downloading wget and its dependency. Then unzip it.

    wget https://github.com/Mythologyli/zju-web-login/archive/refs/heads/master.zip
    unzip master.zip
    cd master
    pip3 install -r requirements.txt
  • Add self compiled module into /lib/modules/`uname -r`

    after adding, use command sudo depmod -a to build a tree where you can call modprobe to find your module.

  • 全志A33修改默认调试串口

    tools/pack/chips/sun8iw5p1/configs/default/env.cfg

    Line5:

    # swap to uart2 by tz61 25/02/14
    console=ttyS2,115200

    tools/pack/chips/sun8iw5p1/configs/vstar/sys_config.fex

    Line112

    ; swap to uart2 debug by tz61. 25/02/14
    [uart_para]
    uart_debug_port = 2
    ;uart_debug_tx   = port:PF02<3><1><default><default>
    ;uart_debug_rx   = port:PF04<3><1><default><default>
    uart_debug_tx    = port:PB00<2><1><default><default>
    uart_debug_rx    = port:PB01<2><1><default><default>
    [force_uart_para]
    force_uart_port  = 2
    ;force_uart_tx    = port:PF02<3><1><default><default>
    ;force_uart_rx    = port:PF04<3><1><default><default>
    force_uart_tx    = port:PB00<2><1><default><default>
    force_uart_rx    = port:PB01<2><1><default><default>
  • FBTFT源码解析

    文件结构

    目录:drivers/staging/fbtft
    其中文件分为核心驱动与面板驱动

    • 核心(通用件,共性):fbtft-core.c, fbtft-bus.c, fbtft-sysfs.c, fbtft-io.c, fbtft.h
    • 面板驱动(下级,特性):(e.g.) fb_st7789v.c

      fbtftops

      write_reg -> fbtftops.write_register
      fbtftops.write_register -> fbtft_write_reg8_bus8 -> fbtft_write_buf_dc -> fbtftops.write
      fbtft_update_display -> fbtftops.write_vmem -> fbtft_write_vmem16_bus8 -> fbtftops.write
      reg,value对本质上就是两个u8参数.

      fbtft_merge_fbtftops

      用于覆盖默认的ops

      fbtft_update_display

      这个是更新整个屏幕的核心函数,首先调用特定的display驱动的set_addr_win,来指定行列起始(x start/end; y start/end)
      在设置完起始后write_reg(par, MIPI_DCS_WRITE_MEMORY_START);来直接写入屏幕的VRAM
      流程图如下(MIPI_DCS_WRITE_MEMORY_START)(0x2C)(RAMWR)

      deferred_io 上层接口

      deferred_io 每次调用会回调fbtftops.update_display来更新屏幕. deferred_io 是整个驱动的上层接口
      见https://docs.kernel.org/fb/deferred_io.html

      dirty机制以及局部更新

      TBD

      注册流程 registration process

      TBD
      fbtft.h有一个FBTFT_REGISTER_DRIVER宏,在每个display驱动里面调用这个.

  • 折腾全志T113-s3 Tina Linux

    编译

    第一次编译

    进入文件夹talowe-t113-linux-sdk然后运行./build.sh

    解压Buildroot rootfs

    在运行过一遍./build.sh后,将我编译的Mplayer1.5,以及测试视频,Qt5.12.6等等覆盖到默认的Buildroot下面,这样省得再重复上述操作重新编译一遍了.具体编译Qt和Mplayer的方法见后面

    tar -xzf ~/target.tar.gz -C /home/talowe/talowe-t113-linux-sdk/out/t113/evb1_auto/longan/buildroot

    运行完成后重新运行

    ./build.sh rootfs
    ./build.sh pack

    out/pack下面就能看到打包好的img文件

    如何烧录打包的emmc

    打开PheonixSuit,选择要烧录的img,然后usb连接开发板,先安卓emmc按钮,然后再按rst按钮(然后马上松开),然后观察PheonixSuit软件,如果看到左下角红色字显示Begin XXXX则立刻松开emmc按钮,如果不松开则烧录不了emmc(原理是这个按键拉低了emmc 的D2脚)
    烧录完成后T113s3会自动重启加载固件
    此时使用MobaXterm打开串口,串口连接至板子的UART3(杜邦线3Pin处)就能看到内核启动日志及其他信息,或者使用adb shell命令进入终端

    目标dts与配置

    SDK/evb1_auto/.BoardConfig.mk可知

    export DTS_NAME=talowe-t113-s3
    export UBOOT_DTS_NAME=talowe-t113-s3-uboot

    用的是kernel/arch/arm/boot/dts/talowe-t113-s3.dts
    kernel的defconfig请见SDK根目录下的.buildconfig
    可见

    export LICHEE_KERN_DEFCONF_ABSOLUTE=/home/talowe/talowe-t113-linux-sdk/kernel/linux-5.4/arch/arm/configs/sun8iw20p1smp_t113_auto_defconfig

    直接修改kernel下面的dts还有defconfig,不需要删除out下面的任何东西然后重新./build.sh然后./build.sh pack然后用Phoenix Suit烧录就行
    记得更新rootfs里面的modules,具体在pack前面运行./build.sh rootfs

    fex

    fex是t113_auto下面的sys_config.fex

    如果打包报错怎么办

    删除out下面的pack_out
    然后重新按照 ./build.sh kernel, ./build.sh rootfs, ./build.sh pack的顺序打包或者直接删除out重新·./build.sh(如果你不想保留buildroot rootfs里面放的东西)

    编译Mplayer-1.5

    ./configure --cc=arm-linux-gnueabi-gcc --enable-cross-compile --strip=arm-linux-gnueabi-strip --target=arm-linux --enable-alsa --enable-fbdev --prefix=/home/talowe/talowe-t113-linux-sdk/out/t113/evb1_auto/longan/buildroot/target/usr --extra-ldflags=--sysroot=/home/talowe/talowe-t113-linux-sdk/out/t113/evb1_auto/longan/buildroot/host/arm-buildroot-linux-gnueabi/sysroot --extra-cflags=-I/home/talowe/talowe-t113-linux-sdk/out/t113/evb1_auto/longan/buildroot/host/arm-buildroot-linux-gnueabi/sysroot/usr/include

    编译Qt 5.12.6

    1.下载源码
    2.编译脚本

    export PATH="$PATH:"

    mk.sh(不需要prefix,默认安装到sysroot/usr/local/Qt5.12.6):

    #!/bin/sh
    export PATH="$PATH:/home/talowe/talowe-t113-linux-sdk/out/gcc-linaro-5.3.1-2016.05-x86_64_arm-linux-gnueabi/bin"
    ./configure \
    -release \
    -opensource \
    -shared \
    -xplatform linux-arm-gnueabi-g++ \
    -optimized-qmake \
    -pch \
    -qt-sqlite \
    -qt-libjpeg \
    -qt-libpng \
    -qt-zlib \
    -no-opengl \
    -skip qt3d \
    -skip qtcanvas3d \
    -skip qtpurchasing \
    -skip qtlocation \
    -skip qttools \
    -no-sse2 \
    -no-openssl \
    -no-cups \
    -no-glib \
    -no-dbus \
    -no-xcb \
    -no-iconv \
    -no-separate-debug-info \
    -no-fontconfig \
    -tslib \
    -I /home/talowe/talowe-t113-linux-sdk/out/t113/evb1_auto/longan/buildroot/host/arm-buildroot-linux-gnueabi/sysroot/usr/include \
    -L /home/talowe/talowe-t113-linux-sdk/out/t113/evb1_auto/longan/buildroot/host/arm-buildroot-linux-gnueabi/sysroot/usr/lib \
    -sysroot /home/talowe/talowe-t113-linux-sdk/out/t113/evb1_auto/longan/buildroot/host/arm-buildroot-linux-gnueabi/sysroot \
    -recheck-all \
    -make examples

    记得把sysroot里面的/usr/include/vulkan文件夹重命名成别的否则会编译一坨vulkan的玩意然后卡报错
    编译完成后把sysroot/usr/local/Qt*拷贝到target/usr/local
    运行Qt程序前设置环境变量(fb0/fb1):

    export QT_PLUGIN_PATH=/usr/local/Qt-5.12.6/plugins
    export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0
    export LD_LIBRARY_PATH=/usr/local/Qt-5.12.6/lib

    参考:在全志V853开发板试编译QT测试

    添加CST816X驱动以及环境变量

    驱动:尚未合并主线
    input: add driver for Hynitron CST816X touchscreen

    export QT_QPA_GENERIC_PLUGINS=tslib:/dev/input/event5

    此处event5和event6为屏幕驱动事件.
    更多参数:How to configure Qt to use tslib instead of evdev?

    增加可用字体

    mkdir /usr/local/Qt-5.12.6/lib/fonts

    dejavu的所有ttf文件放到该目录下.

    开发

    参考 linux下如何利用QtCreator编译ARM版本的Qt程序

    播放视频

    mplayer -vo fbdev2:/dev/fb1 -ao alsa:device=hw=1.0 -fps 30 maimai240.mp4
    mplayer -vo fbdev2:/dev/fb0 -vf scale=360:212 -geometry 0:77 -ao alsa:device=hw=1.0 -fps 30 ba_360x212_30fps.mp4

    TSlib 测试

    首先设定要测试的input设备.

    export TSLIB_TSDEVICE=/dev/input/event5

    然后

    ts_print

    关于CST816X的问题

    这个屏幕貌似没有压力检测,所以tslib的pthres没有作用,要么上报0要么上报255(可以通过运行ts_print观察第三个参数)所以这个在屏幕上点击按钮需要长一点时间

    关于wlan0有时候没检测到怎么办?

    参考How to turn USB-connected device on and off in linux?
    也许有用,没试过,多数情况是kernel module和rootfs没更新导致驱动没加载

    使用Mplayer播放MaiMai

    mplayer -vo fbdev2:/dev/fb1 -ao alsa:device=hw=1.0 maimai240.mp4

    录音

    使用arecord,声卡是hw0, 由于只有单声道所以-c1

    arecord -d 10 -f S16_LE -c1 -r44100 -t wav -D "hw:0,0" test.wav

    上网

    vim /etc/wpa_supplicant.con

    输入密码和SSID
    然后

    wpa_supplicant -i wlan0 -B -c /etc/wpa_supplicant.conf

    最后观察ip

    ip addr
  • RIGOL DHO802/DHO804/DHO812/DHO814 示波器 东方启动

    1.联网

    插网线到电脑(或者路由器都可以,我直接直连PC,PC当NAT)
    参考用Windows通过网线共享网络给其他电脑(Windows、Ubuntu)

    2.下载桌面(Android 7.1.2 com.android.launcher3)

    Launcher3 of AOSP 7.1.2.apk

    3. 用adb 连接示波器并且install apk并启动桌面

    连接

    adb connect 192.168.137.35:55555

    下载完apk后安装launcher3

    adb install launcher3.apk

    启动设置(可以把桌面设成launcher3),在触摸屏里面手动设置

    adb shell monkey -p com.android.settings -c android.intent.category.LAUNCHER 1

    启动Launcher3的activity

    adb shell am start -n com.android.launcher3/com.android.launcher3.Launcher

    然后就ok了

    4.安装手势MyGesture(策划返回等等)

    MyGesture – 全面屏手势/导航手势操作扩展
    根据提示设置权限,然后在设置的无障碍里面开启这个服务.