Skip to content

ackPeng/jetson_develop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 

Repository files navigation

nvidia jetson 软件开发指南

1 概述

本文档主要介绍seeed nvidia jetson系列的载板固件开发流程。旨在帮助软件开发工程师快速上手jetson系列产品的开发及调试。初始版本由原 seeed studio 嵌入式软件工程师 熊健 所写.

适用于以下工程师:

  • 软件开发工程师(SE)
  • 技术支持工程师(AE)
  • 测试工程师(TE)

2 资源获取

名称 地址 用途
JetPack 4内部仓库地址 http://192.168.1.77:1080/awesome-se/jetson/JetPack4/Linux_for_Tegra JP4内部研发仓库
JetPack 5内部仓库地址 http://192.168.1.77:1080/awesome-se/jetson/Linux_for_Tegra JP5内部研发仓库
JetPack 6内部仓库地址 http://192.168.1.77:1080/awesome-se/jetson/jetpack/Linux_for_Tegra JP6内部研发仓库
Jetson官方SDK发布网站 https://developer.nvidia.com/embedded/jetson-linux-archive 获取最新的SDK
Jetson官方论坛 https://forums.developer.nvidia.com/ 寻找问题解决方法或者提问
Jetson下载中心 https://developer.nvidia.com/embedded/downloads 下载必要的设计文件或者配置文件
Jetson 开源仓库 https://github.com/Seeed-Studio/Linux_for_Tegra seeed对外开源窗口

3 SDK与硬件关系描述

3.1 核心板型号判断

由于同一款核心板存在不同的内存区分,不同内存使用的固件是不同的,所以需要会区分核心板具体型号

官方提供了区分教程,链接如下:https://developer.nvidia.com/embedded/faq#jetson-module-origin

下面以jetson orin nano 8g的核心板举例:

alt text

上图中红色箭头指出的3767-0030就对应前面链接中的型号编号,然后就可以知道该核心板的具体型号是orin nano 8g

3.2 软硬件支持关系

由于Jetson系列核心板众多。不同核心板所支持的SDK版本也各不相同,所以软件开发维护工作需要同时负责JP4/JP5/JP6三个大版本。这里我们只看seeed目前在生产和销售的硬件;详细的硬件支持列表如下:

SDK版本 支持的硬件
JP4 Jetson nano
Jetson Xavier nx
JP5 Jetson Xavier nx
Jetson orin nx
Jetson orin nano
Jetson AGX orin
JP6 Jetson orin nx
Jetson orin nano
Jetson AGX orin

4 SDK安装/编译

我们以JP6.2举例,其代码细节可以查看gitlab中的CI源码(http://192.168.1.77:1080/awesome-se/jetson/jetpack/Linux_for_Tegra/-/blob/R36.4.3/.gitlab-ci.yml)

4.1 编译步骤描述

  • 1 下载submodules源码
  - git submodule sync
  - git submodule update --init --recursive
  • 2 部署rootfs
  - wget  http://192.168.1.77/jetson/$ROOTFS_NAME -q
  - tar xpf $ROOTFS_NAME -C rootfs
  • 3 安装nvidia jetson定制的软件包
- ./apply_binaries.sh
  • 4 在目标镜像的rootfs里面记录版本信息
  - echo "# Seeed Image Name mfi_$CI_JOB_STAGE-$JETPACKVER-$JETSONVER-$DATE_STR.tar.gz" >> ./rootfs/etc/nv_tegra_release
  - echo "# branch $CI_COMMIT_REF_NAME" >> ./rootfs/etc/nv_tegra_release
  - echo "# commit ID $CI_COMMIT_SHA" >> ./rootfs/etc/nv_tegra_release
  • 5 配置内核编译工具链
  - wget  http://192.168.1.77/jetson/aarch64--glibc--stable-2022.08-1.tar.bz2 -q
  - mkdir -p l4t-gcc
  - tar xf aarch64--glibc--stable-2022.08-1.tar.bz2 -C ./l4t-gcc
  - export ARCH=arm64
  - export CROSS_COMPILE=`realpath .`/l4t-gcc/aarch64--glibc--stable-2022.08-1/bin/aarch64-buildroot-linux-gnu-
  • 6 编译linux内核,设备树以及nvidia定制的驱动
  - cd source/
  - ./nvbuild.sh
  • 7 安装设备树和内核以及驱动
  - ./do_copy.sh
  - export INSTALL_MOD_PATH=`realpath ../rootfs/`
  - ./nvbuild.sh -i
  • 8 编译专门供核心板烧录固件使用的QSPI固件
sudo BOARDID=$BOARDID BOARDSKU=$BOARDSKU FAB=$FAB BOARDREV=$BOARDREV CHIP_SKU=$CHIP_SKU ./tools/kernel_flash/l4t_initrd_flash.sh -p "-c bootloader/generic/cfg/flash_t234_qspi.xml --no-systemimg" --no-flash --massflash 5 --network usb0 $CONFIG external
  • 9 安装定制化需要的软件
  - sed -i "s/<SOC>/t234/g" rootfs/etc/apt/sources.list.d/nvidia-l4t-apt-source.list
  - mount --bind /sys ./rootfs/sys
  - mount --bind /dev ./rootfs/dev
  - mount --bind /dev/pts ./rootfs/dev/pts
  - mount --bind /proc ./rootfs/proc
  - cp /usr/bin/qemu-aarch64-static rootfs/usr/bin/
  - cp extra_scripts/rootfs_magic.sh rootfs
  - >
    if [ $INSTALL_NV_JP == "1" ]; then
      chroot rootfs /rootfs_magic.sh || true
    fi
  #update kernel module dependencies
  - KER_NUM=`basename $(find ./rootfs/lib/modules -mindepth 1 -maxdepth 1 -type d)`
  - >
    if [ $UPDATE_DRV_DEPEND == "1" ]; then
      echo "current kernel number $KER_NUM"
      sudo chroot rootfs depmod -a  $KER_NUM
    fi
  - umount ./rootfs/sys
  - umount ./rootfs/dev/pts
  - umount ./rootfs/dev
  - umount ./rootfs/proc
  - rm rootfs/rootfs_magic.sh
  - rm rootfs/usr/bin/qemu-aarch64-static
  • 10 编译供QSPI和nvme固件烧录的镜像
sudo BOARDID=$BOARDID BOARDSKU=$BOARDSKU FAB=$FAB BOARDREV=$BOARDREV CHIP_SKU=$CHIP_SKU ./tools/kernel_flash/l4t_initrd_flash.sh --external-device nvme0n1p1 -c tools/kernel_flash/flash_l4t_nvme.xml -S 80GiB -p "-c bootloader/generic/cfg/flash_t234_qspi.xml --no-systemimg" --no-flash --massflash 5 --network usb0 $CONFIG external

4.2 特殊处理解释

  • 1 chip_info.bin_bak
  - >
    if [[ $BOARDID == "3767" && $BOARDSKU == "0004" ]]; then
      cp -v extra_scripts/chip_info.bin_bak bootloader/chip_info.bin_bak
    fi

这个步骤是针对orin nano 4g的一个特殊处理,具体原因未知,如果不添加这个文件的话会导致编译出来的orin nano 4g的固件无法启动.

  • 2 kernel log level
  - >
    if [ -f rootfs/etc/sysctl.conf ]; then
      sed -i '/^kernel\.printk/s/^/#/' rootfs/etc/sysctl.conf
      echo "kernel.printk = 5 6 1 7" >> rootfs/etc/sysctl.conf
    fi

这个处理是针对J501上面GMSL摄像头的日志数据做的特殊处理,如果不处理的话会在J501 GMSL版本启动的过程中出现很多摄像头驱动的细节日志。

  • 3 内核驱动依赖关系更新
  - KER_NUM=`basename $(find ./rootfs/lib/modules -mindepth 1 -maxdepth 1 -type d)`
  - >
    if [ $UPDATE_DRV_DEPEND == "1" ]; then
      echo "current kernel number $KER_NUM"
      sudo chroot rootfs depmod -a  $KER_NUM
    fi

这个步骤是可选的,默认是开启的。在某些特殊情况下:比如recomputer super J401这种无法通过USB device模式配置账户密码的情况下,我们关闭这个步骤,这样就让用户可以通过调试串口来配置账户密码。

  • 4 远程硬盘挂载与镜像上传
  - mkdir -p deploy
  - mount -t cifs -o username=$SMB_USER,password=$SMB_PWD,vers=3.0,uid=`id -u`,gid=`id -g`,rw,file_mode=0664 //192.168.1.77/red_2t/jetson deploy 
  - cp mfi_$CONFIG.tar.gz deploy/mfi_$CI_JOB_STAGE-$JETPACKVER-$JETSONVER-$DATE_STR.tar.gz || true
  - cp chksum-$CI_JOB_STAGE-$DATE_STR.txt deploy/ || true
  - umount deploy

这里需要注意一个点:远程硬盘如果被重复挂载了,会远程硬盘中该目录下的所有文件被删除.为了避免这种情况,我们会保证硬盘挂载与卸载之间的命令都能成功运行。具体是通过|| true来实现的。

  • 5 不同平台下apt source内容的区别
  - sed -i "s/<SOC>/t234/g" rootfs/etc/apt/sources.list.d/nvidia-l4t-apt-source.list

jetson中不同核心板的SOC编号是不同的,想JP6.2里面ORIN系列的编号就是这里的t234.更多核心板的编号信息如下表:

核心板名称 SOC编号
jetson nano t210
jetson xavier nx t194
jetson orin t234

5 外设调试开发

这里我按照目前已有的载板为单位进行功能解析。列表如下:

编号 载板名称
1 recomputer classic
2 recomputer industrial
3 reserver industrial
4 recomputer mini
5 recomputer super
6 recomputer robotics

5.1 recomputer classic

recomputer classic的载板与官方的development kit几乎一致,因此在设备树上差别很小。

5.1.1 设备树文件位置

Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-recomputer-common.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0000-recomputer.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0001-recomputer.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0003-recomputer.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0004-recomputer.dts

5.1.2 设备树功能点

        bus@0 {
                padctl@3520000 {
                        ports {
                                usb2-0 {
                                       connector {
                                               compatible = "usb-b-connector", "gpio-usb-b-connector";
                                               label = "micro-USB";
                                               type = "micro";
                                               vbus-gpio = <&gpio TEGRA234_MAIN_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
                                       };
                                };
                        };
                };
        };

这个配置使能了recover USB口的USB device功能。这样可以在第一次开机时通过这个USB口来配置账户。

5.2 recomputer industrial

recomputer industrial与官方的development kit就有非常大的差别了,添加了很多新的接口(新增网口,4G/5G,POE,RS232/RS485/RS422,CAN,DI/DO,WIFI/BT,RTC,TPM)。

5.2.1 设备树文件位置

Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j201-p3768-0000+p3767-recomputer-indu-common.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j201-p3768-0000+p3767-0000-recomputer-indu.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j201-p3768-0000+p3767-0001-recomputer-indu.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j201-p3768-0000+p3767-0003-recomputer-indu.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j201-p3768-0000+p3767-0004-recomputer-indu.dts

5.2.2 设备树功能点

  • IO拓展芯片

通过I2C拓展的IO。

                i2c@c240000 {
                        gpio_xten: gpio_xten@21 {
                                compatible = "nxp,pca9535";
                                reg = <0x21>;
                                gpio-controller;
                                #gpio-cells = <2>;

                                interrupt-controller;
                                #interrupt-cells=<2>;

                                interrupt-parent = <&gpio>;
                                interrupts = <TEGRA234_MAIN_GPIO(N, 1) IRQ_TYPE_EDGE_FALLING>;

                                gpio-line-names =
                                        "wl_dis"                ,"hst_wake_wl",
                                        "wl_wake_hst"   ,"bt_dis",
                                        "hst_wake_bt"   ,"bt_wake_hst",
                                        "spi0_rst_3v3"  ,"gpio_pin7",
                                        "can_120R_en"   ,"M2B_PCIe_rst",
                                        "USB_HUB_rst"   ,"PCIe_ETH_rst",
                                        "M2B_WOWWAN"    ,"M2B_DPR_3V3",
                                        "SIM_MUX_SEL"   ,"gpio_pin15";

                                gpio-line-offsets = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>, <8>, <9>, <10>, <11>, <12>, <13>, <14>, <15>;
                        };
                };
  • EEPROM

这个EEPROM在设备启动的早期阶段会读取它的内容,如果没有它的话会导致启动卡住。

                gen1_i2c: i2c@3160000 {
                        #address-cells = <1>;
                        #size-cells = <0>;

                        eeprom@57 {
                                compatible = "atmel,24c256";
                                reg = <0x57>;
                                /*16 bit*/
                                address-width = <0x10>;
                                /*32768 bytes */
                                size = <0x8000>;
                                /delete-property/ read-only;
                        };
                };
  • TPM
                spi@3210000 {
                        #address-cells = <0x01>;
                        #size-cells = <0x00>;

                        status = "okay";
                        cs-gpios = <&gpio TEGRA234_MAIN_GPIO(Z, 6) GPIO_ACTIVE_HIGH>;
                        num-cs = <1>;

                        spi@0 {
                                status = "disabled";
                        };

                        spi@1 {
                                status = "disabled";
                        };

                        slb9670@0 {
                                compatible = "infineon,slb9670";
                                status = "okay";
                                reg = <0x0>;
                                spi-max-frequency = <10000000>;
                                controller-data {
                                        nvidia,cs-setup-clk-count = <0x1e>;
                                        nvidia,cs-hold-clk-count = <0x1e>;
                                        nvidia,rx-clk-tap-delay = <0x7>;
                                        nvidia,tx-clk-tap-delay = <0x0>;
                                        nvidia,cs-inactive-cycles = <0x6>;
                                };
                        };
                };
  • USB device on recovery usb ports
                padctl@3520000 {
                        ports {
                                usb2-0 {
                                       connector {
                                               compatible = "usb-b-connector", "gpio-usb-b-connector";
                                               label = "micro-USB";
                                               type = "micro";
                                               vbus-gpio = <&gpio TEGRA234_MAIN_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
                                       };
                                };
                        };
                };
  • IO pinmux CONFIG

这里会根据外设的实际需要去修改引脚的功能,但是要注意,这种方法无法适用于所有的引脚,如果发现无法修改的情况下,需要去修改板级的pinmux文件。

                pinmux@2430000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&jetson_io_pinmux>;

                        jetson_io_pinmux: exp-header-pinmux {
                                hdr40-pin19 {
                                        nvidia,pins = HDR40_PIN19;
                                        nvidia,function = HDR40_SPI;
                                        nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                        nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                        nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                                };
....
  • fixed power setup

这种配置一般是对于某些引脚需要开机后就固定某个电平进行的。

        wl_dis: gpio_xten_pin@0 {
                compatible = "regulator-fixed";
                regulator-name = "wl_dis";
                gpios = <&gpio_xten 0 GPIO_ACTIVE_HIGH>;
                enable-active-high;
                regulator-always-on;
        };

5.3 reserver industrial

reserver industrial在recomputer industrial的基础上进一步增强了连接能力,增加4个千兆网口,SATA接口。

5.3.1 设备树文件位置

Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-reserver-indu-common.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0000-reserver-indu.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0001-reserver-indu.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0003-reserver-indu.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0004-reserver-indu.dts

5.3.2 设备树功能点

  • IO拓展芯片
                i2c@c240000 {
                        #address-cells = <1>;
                        #size-cells = <0>;

                        gpio_xten: gpio_xten@21 {
                                compatible = "nxp,pca9535";
                                reg = <0x21>;
                                gpio-controller;
                                #gpio-cells = <2>;

                                interrupt-controller;
                                #interrupt-cells=<2>;

                                interrupt-parent = <&gpio>;
                                interrupts = <TEGRA234_MAIN_GPIO(N, 1) IRQ_TYPE_EDGE_FALLING>;

                                gpio-line-names =
                                        "PSE_PG"        ,"PSE_INTB",
                                        "gpio_pin2"     ,"gpio_pin3",
                                        "pcie_wake_3v3" ,"pcie_sx1261_rst_3v3",
                                        "spi0_rst_3v3"  ,"uart1_en_3v3",
                                        "can_120R_en"   ,"M2B_PCIe_rst",
                                        "USB_HUB_rst"   ,"PCIe_ETH_rst",
                                        "M2B_WOWWAN"    ,"M2B_DPR_3V3",
                                        "SIM_MUX_SEL"   ,"PSE_PWR_EN";

                                gpio-line-offsets = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>, <8>, <9>, <10>, <11>, <12>, <13>, <14>, <15>;
                        };
                };
  • EEPROM
                i2c@3160000 {
                        #address-cells = <1>;
                        #size-cells = <0>;

                        eeprom@57 {
                                compatible = "atmel,24c256";
                                reg = <0x57>;
                                /*16 bit*/
                                address-width = <0x10>;
                                /*32768 bytes */
                                size = <0x8000>;
                                /delete-property/ read-only;

                        };
                };
  • TPM
                spi@3210000 {
                        #address-cells = <0x01>;
                        #size-cells = <0x00>;

                        status = "okay";
                        cs-gpios = <&gpio TEGRA234_MAIN_GPIO(Z, 6) GPIO_ACTIVE_HIGH>;
                        num-cs = <1>;

                        spi@0 {
                                status = "disabled";
                        };

                        spi@1 {
                                status = "disabled";
                        };

                        slb9670@0 {
                                compatible = "infineon,slb9670";
                                status = "okay";
                                reg = <0x0>;
                                spi-max-frequency = <10000000>;
                                controller-data {
                                        nvidia,cs-setup-clk-count = <0x1e>;
                                        nvidia,cs-hold-clk-count = <0x1e>;
                                        nvidia,rx-clk-tap-delay = <0x7>;
                                        nvidia,tx-clk-tap-delay = <0x0>;
                                        nvidia,cs-inactive-cycles = <0x6>;
                                };
                        };
                };
  • 串口
                serial@3110000 {
                        status = "okay";
                };
  • pcie 2x1 channel(default is 1x2 channel)
                pcie@141e0000 {
                        status = "okay";
                        phys = <&p2u_gbe_0>;
                        phy-names = "p2u-0";
                };

                pcie@140c0000 {
                        status = "okay";
                        phys = <&p2u_gbe_1>;
                        phy-names = "p2u-0";
                };
  • usb device on recovery usb ports
                padctl@3520000 {
                        ports {
                                usb2-0 {
                                       connector {
                                               compatible = "usb-b-connector", "gpio-usb-b-connector";
                                               label = "micro-USB";
                                               type = "micro";
                                               vbus-gpio = <&gpio TEGRA234_MAIN_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
                                       };
                                };
                        };
                };
  • fixed power setup

                spi0_rst_3v3: gpio_xten_pin@6 {
                        compatible = "regulator-fixed";
                        regulator-name = "spi0_rst_3v3";
                        gpios = <&gpio_xten 6 GPIO_ACTIVE_HIGH>;
                        enable-active-low;
                        regulator-always-on;
                };
  • pinmux setup
                pinmux@2430000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&jetson_io_pinmux>;

                        jetson_io_pinmux: exp-header-pinmux {
                                hdr40-pin19 {
                                        nvidia,pins = HDR40_PIN19;
                                        nvidia,function = HDR40_SPI;
                                        nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                        nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                        nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                                };
...

5.4 recomputer mini

recomputer mini采用了板级堆叠的方式设计了全新的硬件,有丰富的外设连接接口(UART,I2C,SPI,USB,CAN,DP)

5.4.1 设备树文件位置

Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j40mini-p3768-0000+p3767-recomputer-common.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j40mini-p3768-0000+p3767-0000-recomputer.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j40mini-p3768-0000+p3767-0001-recomputer.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j40mini-p3768-0000+p3767-0003-recomputer.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j40mini-p3768-0000+p3767-0004-recomputer.dts

5.4.2 设备树功能点

  • EEPROM
                i2c@3160000 {
                        #address-cells = <1>;
                        #size-cells = <0>;

                        eeprom@57 {
                                compatible = "atmel,24c02";
                                reg = <0x57>;
                                /*16 bit*/
                                address-width = <0x08>;
                                /*32768 bytes */
                                size = <0x100>;
                                /delete-property/ read-only;
                        };
                };
  • USB

对比之前的USB配置,这里会复杂一些,因为除了开启了USB3-2这个新口,此外还需要修改USB2.0和USB3.0之间的对应关系。

                padctl@3520000 {
                        ports {
                                usb2-0 {
                                       connector {
                                               compatible = "usb-b-connector", "gpio-usb-b-connector";
                                               label = "micro-USB";
                                               type = "micro";
                                               vbus-gpio = <&gpio TEGRA234_MAIN_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
                                       };
                                };

                                usb3-2 {
                                        nvidia,usb2-companion = <2>;
                                        status = "okay";
                                };

                                usb3-1 {
                                        nvidia,usb2-companion = <1>;
                                        status = "okay";
                                };

                                usb3-0 {
                                        nvidia,usb2-companion = <2>;
                                        status = "okay";
                                };
                        };

                        pads {
                                usb3 {
                                        lanes {
                                                usb3-2 {
                                                        nvidia,function = "xusb";
                                                        status = "okay";
                                                };
                                        };
                                };
                        };
                };

                usb@3610000 {
                        status = "okay";

                        phys = <&{/bus@0/padctl@3520000/pads/usb2/lanes/usb2-0}>,
                               <&{/bus@0/padctl@3520000/pads/usb2/lanes/usb2-1}>,
                               <&{/bus@0/padctl@3520000/pads/usb2/lanes/usb2-2}>,
                               <&{/bus@0/padctl@3520000/pads/usb3/lanes/usb3-0}>,
                               <&{/bus@0/padctl@3520000/pads/usb3/lanes/usb3-1}>,
                               <&{/bus@0/padctl@3520000/pads/usb3/lanes/usb3-2}>;
                        phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0",
                                    "usb3-1", "usb3-2";
                };
  • CAN
                can_clock: can_clock {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
                        clock-frequency = <40000000>;
                        clock-accuracy = <100>;
                };

                spi@3230000 {
                        #address-cells = <0x01>;
                        #size-cells = <0x00>;

                        status = "okay";

                        spi@0 {
                                compatible = "microchip,mcp2518fd";
                                reg = <0x0>;
                                spi-max-frequency = <2000000>;
                                interrupt-parent = <&gpio>;
                                interrupts = <TEGRA234_MAIN_GPIO(R, 4) IRQ_TYPE_LEVEL_LOW>;
                                clocks = <&can_clock>;
                                nvidia,enable-hw-based-cs;
                                controller-data {
                                        nvidia,enable-hw-based-cs;
                                        nvidia,rx-clk-tap-delay = <0x10>;
                                        nvidia,tx-clk-tap-delay = <0x0>;
                                };
                        };
                };
  • fixed power setup
                m2_key_b_enable {
                        compatible = "regulator-fixed";
                        regulator-name = "M.2 KEY-B PWR ENABLE";
                        gpios = <&gpio TEGRA234_MAIN_GPIO(AC, 6) GPIO_ACTIVE_HIGH>;
                        enable-active-high;
                        regulator-always-on;
                };
  • pinmux setup
                pinmux@2430000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&jetson_io_pinmux>;

                        jetson_io_pinmux: exp-header-pinmux {
                                hdr40-pin13 {
                                        nvidia,pins = HDR40_PIN13;
                                        nvidia,function = "spi3";
                                        nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                        nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                        nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                                };
...
  • new fan
        fan1: pwm-fan1 {
                compatible = "pwm-fan";
                pwms = <&pwm7 0 45334>;
                cooling-levels = <0 88 128 192 255>;
                #cooling-cells = <2>;
        };

        thermal-zones {
                tj-thermal {
                        trips {
                                tj_trip_active3: active-3 {
                                        temperature = <45000>;
                                        hysteresis = <4000>;
                                        type = "active";
                                };
                                tj_trip_active4: active-4 {
                                        temperature = <55000>;
                                        hysteresis = <4000>;
                                        type = "active";
                                };
                                tj_trip_active5: active-5 {
                                        temperature = <65000>;
                                        hysteresis = <4000>;
                                        type = "active";
                                };
                        };
                        cooling-maps {
                                map-active-3 {
                                        trip = <&tj_trip_active0>;
                                        cooling-device = <&fan1 0 1>;
                                };

                                map-active-4 {
                                        trip = <&tj_trip_active3>;
                                        cooling-device = <&fan1 1 2>;
                                };

                                map-active-5 {
                                        trip = <&tj_trip_active4>;
                                        cooling-device = <&fan1 2 3>;
                                };

                                map-active-6 {
                                        trip = <&tj_trip_active5>;
                                        cooling-device = <&fan1 3 4>;
                                };
                        };
                };
        };

5.5 recomputer super

5.5.1 设备树文件位置

Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-recomputer-super-common.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0000-recomputer-super.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0001-recomputer-super.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0003-recomputer-super.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0004-recomputer-super.dts

5.5.2 设备树功能点

  • EEPROM
                        eeprom@57 {
                                compatible = "atmel,24c256";
                                reg = <0x57>;
                                /*16 bit*/
                                address-width = <0x10>;
                                /*32768 bytes */
                                size = <0x8000>;
                                /delete-property/ read-only;
                        };
  • IO拓展芯片
                        seeed_io_exp:io_exp@38 {
                                compatible = "nxp,pca9554";
                                reg = <0x38>;
                                status = "okay";
                                gpio-controller;
                                #gpio-cells = <2>;

                                interrupt-parent = <&gpio>;
                                interrupts = <TEGRA234_MAIN_GPIO(AG, 4) IRQ_TYPE_LEVEL_LOW>;

                                gpio-line-names =
                                "CSI3_PWDN"     ,"CAM_MUX1_SEL",
                                "M2B_PCIe_Reset","PCIe_ETH_Reset",
                                "CSI1_PWDN"     ,"not_used",
                                "not_used"      ,"not_used";
                        };

5.6 recomputer robotics

5.6.1 设备树文件位置

Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-recomputer-robo-common.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0000-recomputer-robo.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0001-recomputer-robo.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0003-recomputer-robo.dts
Linux_for_Tegra/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-j401-p3768-0000+p3767-0004-recomputer-robo.dts

5.6.2 设备树功能点

  • EEPROM
                i2c@3160000 {
                        #address-cells = <1>;
                        #size-cells = <0>;

                        eeprom@57 {
                                compatible = "atmel,24c02";
                                reg = <0x57>;
                                /*8 bit*/
                                address-width = <0x08>;
                                /*256 bytes */
                                size = <0x100>;
                                /delete-property/ read-only;
                        };
                };
  • CAN
                can_clock: can_clock {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
                        clock-frequency = <40000000>;
                        clock-accuracy = <100>;
                };

                spi@3230000 {
                        #address-cells = <0x01>;
                        #size-cells = <0x00>;

                        status = "okay";

                        spi@0 {
                                compatible = "microchip,mcp2518fd";
                                reg = <0x0>;
                                spi-max-frequency = <2000000>;
                                interrupt-parent = <&gpio>;
                                interrupts = <TEGRA234_MAIN_GPIO(Y, 4) IRQ_TYPE_LEVEL_LOW>;
                                clocks = <&can_clock>;
                                nvidia,enable-hw-based-cs;
                                controller-data {
                                        nvidia,enable-hw-based-cs;
                                        nvidia,rx-clk-tap-delay = <0x10>;
                                        nvidia,tx-clk-tap-delay = <0x0>;
                                };
                        };
                };
  • IO拓展芯片
                i2c@c250000 {
                        status = "okay";
                        #address-cells = <1>;
                        #size-cells = <0>;

                        gpio_xten: gpio_xten@21 {
                                compatible = "nxp,pca9535";
                                reg = <0x21>;
                                gpio-controller;
                                #gpio-cells = <2>;

                                interrupt-controller;
                                #interrupt-cells=<2>;

                                interrupt-parent = <&gpio>;
                                interrupts = <TEGRA234_MAIN_GPIO(R, 4) IRQ_TYPE_EDGE_FALLING>;

                                gpio-line-names =
                                        "LED_RED_3V3"   ,"LED_BLUE_3V3",
                                        "LED_GREEN_3V3" ,"CAN0_STBY_3V3",
                                        "CAN1_STBY_3V3" ,"UART1_EN_3V3",
                                        "CAM_VDD_EN_3V3","AP_WAKE_BT_3V3",
                                        "USB_HUB_RST_3V3","PCIe_RST_3V3",
                                        "PCIe_ETH_RST_3V3","M2B_W_DISABLE2#_3V3",
                                        "M2B_W_DISABLE1#_3V3","M2B_DPR_3V3",
                                        "M2B_PCIe_RST_3V3","not_used";

                                gpio-line-offsets = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>, <8>, <9>, <10>, <11>, <12>, <13>, <14>, <15>;
                        };
                };
  • pinmux CONFIG
                pinmux@2430000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&jetson_io_pinmux>;

                        jetson_io_pinmux: exp-header-pinmux {
                                hdr40-pin13 {
                                        nvidia,pins = HDR40_PIN13;
                                        nvidia,function = "spi3";
                                        nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
                                        nvidia,tristate = <TEGRA_PIN_DISABLE>;
                                        nvidia,enable-input = <TEGRA_PIN_DISABLE>;
                                };
...

6 固件开发流程

jetson固件开发流程会随着Jetpack版本的不同而有所变化,下面按照版本对固件开发的流程进行细节描述。

6.1 JetPack 6固件开发流程

6.1.1 开发步骤

  • 1 上传官方SDK

    这一步主要上传了官方的BSP以及rootfs到我们内部的gitlab上,其中BSP解压缩后上传到gitlab仓库,rootfs上传到我们的nas上,供CI编译固件时下载使用。

  • 2 上传submodules

    JP6中,内核,设备树,以及nvidia定制的一些驱动,都是通过submodules的形式进行管理。我们需要先手动拉取到所有submodule的代码后,在上传到gitlab中。

  • 3 添加一些通用的文件

    诸如.gitignore,do_copy.sh这种文件,基本上来说是通用的。

  • 4 对官方SDK做一些通用的修改

    比如修改EXT_NUM_SECTORS 这种东西,不同版本之间也基本通用,可以使用git cherry-pick的方式去同步改动。

  • 5 上传seeed载板的设备树代码
  • 6 同步老版本中submodules的修改

    诸如linux内核,nvidia-oot这种东西的修改点,小版本升级时一般是可以直接cherry-pick过来的。

  • 7 上传seeed载板的板级配置文件和pinmux配置文件

    拿recomputer-orin-robotics-j401.conf举例,我们除了上传robotics本身的配置文件外,还需要上传引脚的pinmux配置文件。这些pinmux配置文件是通过一个excel的表格自动生成出来的。表格本身在jetson官方的下载中心里面可以下载,具体链接如下:https://developer.nvidia.com/embedded/downloads

    具体使用方法: alt text

    通过microsoft office打开下载到的pinmux excel配置表格。

    • 绿色箭头标记的编号,通过它可以将pinmux配置和原理图对应起来,原理图上核心板每个引脚的数字编号和这里一一对应。
    • 蓝色箭头标出的区域,是orin系列核心板会根据显示接口的不同,有不同的pinmux配置,我们根据原理图设计中的具体情况来进行选择。
    • 红色箭头标出的区域,在修改引脚的pinmux配置后,用来生成pinmux配置文件的按钮;点击后会让输入pinmux名称,然后会生成下面三个文件:
    Orin-jetson orin nano&nx pinmux hdmi-gpio-default.dtsi
    Orin-jetson orin nano&nx pinmux hdmi-padvoltage-default.dtsi
    Orin-jetson orin nano&nx pinmux hdmi-pinmux.dtsi
    
  • 8 上传CI代码
  • 9 上传readme

6.1.2 commit ID内容解析

这里以最新的JP6.2的提交历史进行介绍

内容 commit ID
提交官方SDK ab36fae7c21a6a1897920e927ee3ae02203cfa75
添加gitignore a69a6bdc9f73c06fd724e3ca2c822304ef2b9db8
上传submodules 602ec8b7e737ab778c26f055aacf404883f3ed46
修改ssd固件中rootfs的默认大小 1faa992270449430f3804c1362356dbd21018f64
上传recomputer classic载板设备树代码 6dd8581e8a991671cf4435194ae4586ba87ed925
上传载板设备树文件到主工程 3ea64b0ac3368d8212a47def2b6afedd688c2d02
上传一些配套文件 60f440d8f79e16cfbf705b0379f0d626ae05405c
上传载板的板级配置文件 7ae1f3f8b96d0e639994c57f65bc3ec011067995
上传CI和相关的文件 3e2fd1a0a8b41bba672408d8e9f07d0f03b4e444
上传readme 7abf15910c800e46dcc6ac067cfc448e6319aa67

到这里我们就可以触发CI来编译recomputer classic的固件编译了。

内容 commit ID
同步JP6.1中linux内的改动点 c0e3daf41d0eecdd15f396f313d929e444de3b9a
上传recomputer mini的设备树代码 ecbce55137e895dacf5830cfe801a6e833d192be
上传recomputer mini的板级配置文件 b5e11336d549ac6a613daa554af3212f1eb825f4
上传recomputer industrial的板级配置文件 03b6b231174c0709e97f7f8da99ebcd248acc93e
上传reserver industrial的板级配置文件 aa5324a98e730dc616d7abb5a25eec3b73d01302

到这里我们就可以触发CI去编译recomputer mini/recomputer industrial/reserver industrial的固件了。

内容 commit ID
上传J501的pinmux配置文件 a80b211fb8744c43804defe68c05453d5c47b31c
上传J501的板级配置文件 d40c2b7a6bcb204928f824bd3cdc601943a83c36
添加J501的CI代码 9904d347521d9e6344c8eec8875001dc410b22f9
上传J501的设备树 91fd2ebfd90770573c1fd2c443d7e816695bf113
给J501更新submodules 61d7e96a3a5b9258b03e90f43c63d3cdd93c5f06

到这里我们就可以触发CI去编译reserver industrial J501的固件了。

6.1.3 github开源代码开发流程

由于github仓库空间限制,我们无法直接将内部gitlab的代码直接上传过去。这里我们采用打包所有修改过的文件的方式去上传代码。

  • 1 获取自第一次修改以来的所有提交中所修改过的文件列表
git diff --name-only commit_id_before_oldest_change HEAD > files.txt
  • 2 将所有修改过的文件打包
tar -czvf update_from_abc123_to_latest.tar.gz -T files.txt
  • 3 在github上面的BSP开源仓库中新建空白分支
git checkout --orphan r36.4.3
  • 4 将第2步中打包的文件解压缩到新的空白分支并提交
  • 5 对所有的submodule重复执行1~4中的操作
  • 6 更新readme的版本信息并上传。

6.2 JetPack 5固件开发流程

大体流程与JP6一致,这里说明下不同点:

  • 1 JP5中是通过设备树overlay的形式去添加外设驱动的。
  • 2 JP5中没有用submodule来管理代码

6.3 JetPack 4固件开发流程

JP4的固件目前只对jetson nano这个核心板做了开发,载板与官方载板基本一致。所以开发的点只有以下3点:

  • 1 使能SD卡座的功能

    这里我们通过直接修改反编译的主设备树来使能SD卡座的功能,具体操作如下:

    dtc -I dtb -O dts tegra210-p3448-0002-p3449-0000-b00.dtb -o tegra210-p3448-0002-p3449-0000-b00.dts
    

    在修改tegra210-p3448-0002-p3449-0000-b00.dts后,我们再将其编译为dtb

    dtc -I dts -O dtb tegra210-p3448-0002-p3449-0000-b00.dts -o tegra210-p3448-0002-p3449-0000-b00-new.dtb
    
  • 2 安装nvidia-jetpack软件

    这个跟JP6/JP5中的做法一样,通过qemu来实现

  • 3 修改DP0_HPD这个上拉功能

    操作细节同上面的第一个功能点

7 测试方法介绍

这个软件测试那边有写详细的操作文档,找他们拿文档就行。

8 固件发布流程

8.1 固件编译

通过触发CI的方法编译固件,生成的固件会自动上传到nas上面,这里需要账号密码登录,nas地址:http://192.168.1.77:5000/ 具体路径:red_2t/jetson/

如果要分享给公司内部没有nas账号的人看,地址如下:https://192-168-1-77.awesome-se.direct.quickconnect.cn:5001/sharing/pYuCmkvql

8.2 自测试

自己烧录固件,按照测试那边的测试文档完整的过一遍测试。

8.3 提测

联系测试人员协调资源后安排时间进行测试

8.4 修复问题

测试人员测试后如果有问题需要及时修复问题。然后复测。

8.5 固件发布

固件测试没有问题后,测试人员会发布固件,具体操作是将固件移动到release文件夹下面。但是由于工厂端硬盘容量的限制,测试人员会定期将release下面工厂用不到的文件根据版本分别转移到JP4-release/JP5-release/JP6-release下面。

9 研发调试技巧

  • 1 正式固件下载

    由于正式固件一般都有十几个G大小,我们通过浏览器去下载会比较麻烦,这里可以通过在自己电脑上挂载远程硬盘的方式来下载。挂载命令如下:

    sudo mount -t cifs -o username='username',password='userpwd',vers=3.0,uid=1000,gid=1000,rw,file_mode=0664 //192.168.1.77/red_2t/jetson  ./xj
    
  • 2 外设调试提速

在一个新载板的调试阶段,我们可以直接在官方development kit的基础上通过overlay的方式快速的使能外设驱动。具体方法官方有说明:https://docs.nvidia.com/jetson/archives/r36.4/DeveloperGuide/HR/ConfiguringTheJetsonExpansionHeaders.html#creating-a-simple-device-tree-overlay

  • 3 快速烧录固件

正常情况下,我们都是先编译生成固件包,然后解压缩,再连接设备进行烧录。如果想快速烧录,我们将BSP和rootfs准备好,让设备进入recovery模式后,通过下面的命令就可以直接烧录固件:

官方JP6固件烧写命令:
sudo ./tools/kernel_flash/l4t_initrd_flash.sh --external-device nvme0n1p1   -c tools/kernel_flash/flash_l4t_t234_nvme.xml -p "-c bootloader/generic/cfg/flash_t234_qspi.xml"   --showlogs --network usb0 jetson-orin-nano-devkit internal

官方JP5固件烧写命令:
sudo ./tools/kernel_flash/l4t_initrd_flash.sh --external-device nvme0n1p1   -c tools/kernel_flash/flash_l4t_t234_nvme.xml -p "-c bootloader/t186ref/cfg/flash_t234_qspi.xml"   --showlogs --network usb0 jetson-orin-nano-devkit internal
  • 4 如何知道硬件I2C与软件I2C的对应关系
    • 1 通过原理图查看I2C上面挂载的外设,通过i2cdetect -y -r x扫描后进行对应
    • 2 I2C信号线连接逻辑分析仪,运行i2cdetect命令后查看是否有波形
    • 3 通过核心板原理图中的I2C编号判断,不过这种方法有风险,软件编号可能随着系统版本而变化

10 特殊需求

10.1 磁盘加密

注意:宿主机器一定要下载以下包,否则无法正常用: $ sudo apt-get install python3-cryptography python3-cffi-backend libxml2-utils $ sudo apt-get install cryptsetup python3-pycryptodome python3-crypto

1、修改 tools/kernel_flash/flash_l4t_t234_nvme_rootfs_enc.xml 与 tools/kernel_flash/flash_l4t_t234_nvme.xml 文件,将NUM_SECTORS 设置为使用的磁盘大小(比实际磁盘大小要小一些)

2、需要特别需要两个文件:eks_t234.img,sym2_t234.key;通过下载optee源码,使用example.sh脚本可以生成,生成后将eks_t234.img放入bootloader目录,sym2_t234.key放入工程目录

3、执行 sudo ./tools/kernel_flash/l4t_initrd_flash.sh --network usb0 --no-flash --showlogs -p "-c bootloader/t186ref/cfg/flash_t234_qspi.xml" jetson-orin-nano-devkit internal,然后 sudo cp bootloader/eks_t234_sigheader.img.encrypt ./tools/kernel_flash/images/internal/.

4、生成固件并烧录:sudo ROOTFS_ENC=1 ./tools/kernel_flash/l4t_initrd_flash.sh --external-device nvme0n1p1 -i ./sym2_t234.key -c tools/kernel_flash/flash_l4t_t234_nvme_rootfs_enc.xml -S 80GiB -p "-c bootloader/generic/cfg/flash_t234_qspi.xml" --showlogs --network usb0 recomputer-orin internal

10.2 预设账号密码

sudo ./tools/l4t_create_default_user.sh -u nvidia -p nvidia -n PrasselMagicBox --accept-license即可

10.3 在jetson中编译内核模块

要设置的内核源码目录可以在:/usr/src/linux-headers-5.15.148-tegra-ubuntu22.04_aarch64/中找到

10 疑难解析

这里会列出我以往开发jetson固件过程中碰到过的比较麻烦点的问题,作为备忘录:

问题描述 相关链接 结论
AGX orin上面SPI一次发送
超过256字节时驱动崩溃
https://forums.developer.nvidia.com/t/agx-orin-spi-tegra114-c260000-spi-crashed-when-sending-large-amounts-of-data-in-jetpack-6-0/300237 使用SPI的应用中每次最多发送256字节
orin nx上面使用vl805时会出现U盘识别异常 https://forums.developer.nvidia.com/t/can-jetson-orin-nx-8g-disable-config-pci-iov-in-kernel-config/305519 放弃VL805的PCIE转USB方案
orin nx的super mode实测可以工作在VDD_IN为5V的情况下,但是官方推荐8V https://forums.developer.nvidia.com/t/vdd-in-voltage-issue-about-orin-nx-16g-with-super-mode/321245 短时间测试没问题,但是有损坏板子的风险,所以对外口径一致说不支持VDD_IN是5V的板子
是否可以通过USB3.0给设备烧录固件 https://forums.developer.nvidia.com/t/can-i-flash-jetson-orin-with-usb3-0-port/323261 是可以的,并且在JP6固件下速度对比USB2.0有明显提升:JP5下USB2.0烧录15分钟,USB3.0烧录7分钟;JP6下USB2.0烧录7分钟,USB3.0S烧录3分钟。
orin nano在super模式下功率无法跑满(25W) https://forums.developer.nvidia.com/t/maxmium-power-of-super-mode-on-jetson-orin-nano-4g/323432 测试方法问题,使用新方法功率可以跑满
recomputer super的4摄像头功能无法同时运行 https://forums.developer.nvidia.com/t/four-camera-with-orin-nx-8g/327345/11 设备树节点配置问题,修改配置后4个摄像头可以同时工作
jetson平台下USB-bus无法同时开启多个USB摄像头 https://forums.developer.nvidia.com/t/use-gstreamer-to-open-two-usb-cameras-failed-to-allocate-required-memory/122843 https://developer.ridgerun.com/wiki/index.php?title=Birds_Eye_View/Getting_the_Code/Building_and_Installation_Guide#Patch_to_support_4_USB_cameras 增加uvc驱动补丁可以解决
设置用户的nv-oem会导致黑屏 https://forums.developer.nvidia.com/t/jp6-0-0-sometimes-black-screen-while-running-ubiquity-dm-in-nv-oem-config-firstboot-when-using-hdmi-dcb-image/307937/19 把链接中的deb包安装
禁止UEFI按下ESC或者f11进入shell https://forums.developer.nvidia.com/t/how-to-disable-uefi-setup-screen/257990 https://forums.developer.nvidia.com/t/disabling-bios-screen/246557/4 修改UEFI源码然后重新编译,编译后的名称为images/uefi_t23x_general_RELEASE.bin,放到bootloader/uefi_jetson.bin即可

About

jetson开发笔记

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published