tag 标签: imx6

相关博文
  • 2022-8-5 14:52
    147 次阅读|
    0 个评论
    正如学习C语言时写的第一段代码都是“HelloWorld!”,接触一款新的处理器时往往是从点亮一个LED开始;而点亮一个LED,则需要操作这款芯片的GPIO外设。 那么作为广受欢迎的i.MX6ULL处理器,它的GPIO外设应该如何配置呢?今天小编就将通过飞凌嵌入式的OKMX6ULL-S开发板来为大家详细介绍。 i.MX6ULL处理器的GPIO配置 i.MX6ULL运行的是Linux系统,众所周知Linux下一切皆文件。在Linux系统当中,有一个文件专门用于配置处理器的各个外设,包括GPIO,这个文件被称为 “设备树” ,i.MX6ULL的设备树在内核源码中的路径为: arch/arm/boot/dtbs/ 。 在这个路径下我们可以看到很多设备树文件,我们要使用的设备树是: okmx6ull-s-emmc.dts 以及 okmx6ull-s-nand.dts 。打开以上任意一个设备树文件,可以看到二者均引用了 imx6ull-14x14-evk.dts ,因此对设备树的修改都是基于imx6ull-14x14-evk.dts。 找到其中的 &iomuxc 节点,可以看到在 pinctrl_hog_1:hoggrp-1 节点下已有部分GPIO复用,内容如下: 1 硬件原理分析 查看硬件原理图,6ULL-S底板上有两个LED,以LED2为例,LED2的阴极接在了GPIO9引脚上,当GPIO9为低时,LED点亮。 打开硬件资料/用户手册/FETMX6ULx-S核心板管脚功能分配表20200624.xlsx,通过查表得知GPIO9对应的是i.MX6ULL的GPIO1_IO09。 2 设置引脚复用 前面我们提到了&iomuxc节点下增加引脚复用,参数我们先设置为0x17059,后面会解释配置方法。配置如下: 3 注释掉冲突部分 接下来打开内核源码中的: arch/arm/boot/dts/imx6ull-14x14-evk.dts 因接下来要对GPIO进行操作,为防止该节点影响,需要注释掉设备树中的LED节点,如下图红框中所示: 4 更新设备树 重新编译设备树,命令如下: /opt/fsl-imx-x11/4.1.15-2.0.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi //执行环境变量 make dtbs 这条命令会编译所有的设备树,编译后再次查看确认已经生成新的dtb文件。 接下来,我们将刚刚生成的设备树文件拷贝到OKMX6ULL-S开发板——可以通过U盘,也可以通过TFTP、NFS、FTP这样的网络服务将生成的dtb文件拷贝到开发板上。 以eMMC版本为例,我们可以直接将设备树文件:okmx6ull-s-emmc.dtb拷贝到/run/media/mmcblk1p1/路径下,替换掉该路径下的同名文件,之后重启开发板。 5 操作GPIO 1. 计算对应sys/class/gpio的值GPIOn_IOx= (n-1)*32 + x GPIO1_IO09=(1- 1)*32 + 9 = 9 2. 将GPIO1_IO09=设置为输出 /sys/class/gpio/export 用于通知系统需要导出控制的GPIO引脚编号 /sys/class/gpio/gpio9/direction 控制为输出 /sys/class/gpio/gpio9/value 输出为高电平,LED熄灭 /sys/class/gpio/gpio9/value输出为低电平,LED点亮 /sys/class/gpio/unexport 通知系统取消导出 6 GPIO参数详解 现在我们转过头来了解一下刚刚都用到了哪些参数: MX6UL_PAD_GPIO1_IO09__GPIO1_IO09 这一长串,是一个宏定义,可以在 imx6ul-pinfunc.h 文件当中查看,细心的小伙伴可能已经注意到了imx6ul-pinfunc.h这个文件是6UL的,这是因为 imx6ull-pinfunc.h引用了imx6ul-pinfunc.h,并且增加了部分内容 。 打开arch/arm/boot/dtbs/imx6ul-pinfunc.h文件,找到MX6UL_PAD_GPIO1_IO09的宏定义如下: 这些宏定义就是GPIO1_IO09这个引脚可以复用的功能。每一个宏定义后面都有5个参数,再加上刚刚我们在&iomuxc节点下配置的0x17059一共是6个参数,通过它们就可以完成一个GPIO的配置了,这6个参数分别为: mux_ctrl_ofs: MUX寄存器偏移地址 pad_ctrl_o fs: PAD寄存器偏移地址 sel_input_ofs: 输入选择寄存器偏移地址 mux_mode: MUX寄存器值 sel_input: 输入选择寄存器值 pad_ctrl: PAD寄存器值 以上6个参数对应了3个寄存器的偏移地址和寄存器值。我们接下来重点介绍一下MUX寄存器和PAD寄存器。 1. MUX寄存器 全名是SW_MUX_CTL_PAD_GPIO1_IO09,意为GPIO复用寄存器,在i.MX6ULL的数据手册有它的详细介绍,我们可以从飞凌官方提供的资料中找到:硬件资料/数据手册/i.MX6ULLRM.pdf。 打开32.6.16小节,可以看到寄存器偏移地址和我们官方提供的文件中是一致的。而ALT0-ALT8则分别对应了这个GPIO可以复用的功能, 0x5对应的就是将GPIO5_IO09复用成GPIO1_IO09 。 2. PAD寄存器 全称SW_PAD_CTL_PAD_GPIO1_IO09,意为GPIO电气参数配置寄存器,这个是我们需要重点关注的内容,因为无论是刚刚提到的MUX寄存器,还是输入选择寄存器,NXP官方都已经为我们写好了宏定义,但是这个寄存器的值,需要用户根据自身需求来设置,参考的资料依旧是i.MX6ULLRM.pdf,在32.6.162小节,有关于PAD寄存器每一位的详细解释。 HYS(bit16): 使能迟滞比较器,当IO作为输入功能的时候有效,开启迟滞比较器可以滤掉一些干扰。这一位为0时禁止迟滞比较器,为1时使能迟滞比较器。 PUS(bit15:14): 设置上下拉电阻,一共有四种选项可以选择: PUE(bit13): 当IO作为输入的时候,这一位用来设置IO使用上下拉还是状态保持器。当为0的时候使用状态保持器,当为1的时候使用上下拉。状态保持器在IO作为输入的时候才有用,顾名思义,就是当外部电路断电以后此IO口可以保持住以前的状态。 PKE(bit12): 此位用来使能或者禁止上下拉/状态保持器功能,这一位为0时禁止上下拉/状态保持器,为1时使能上下拉和状态保持器。 ODE(bit11): 开漏使能,当IO作为输出的时候,用来禁止或者使能开漏输出,这一位为0的时候禁止开漏输出,为1的时候就使能开漏输出功能。 SPEED(bit7:6): 当IO用作输出的时候,此位用来设置IO速度。 DSE(bit5:3): 当IO用作输出的时候用来设置IO的驱动能力,可以简单理解为IO口上串联的电阻大小,电阻越小驱动能力越强,总共有8个可选项: SRE(bit0): IO翻转速度,为1时IO电平跳变时间更快,对应波形更陡;为0时IO电平跳变时间要慢一些,波形也更平缓。 介绍完了PAD寄存器的每一位,我们再回头看一下刚刚配置的0x17059,将它展开成二进制为:0001 0111 0000 0101 1001。 bit15:14设置为01,对应的是100K上拉,这是因为LED的阴极接到了GPIO上,保持默认状态下LED为熄灭状态。 bit5:3,这里配置的是R0/6,小伙伴们也可以试一下配置成其他的值,观察LED的亮度会不会有变化。 以上就是为i.MX6ULL处理器配置GPIO的全过程,希望能够对屏幕前的各位工程师小伙伴有所帮助。想要了解更多有关FETMX6ULL-S详情和资料,可点击下方链接进入飞凌嵌入式官网。 https://forlinx.com/product/123.html<<
  • 热度 2
    2022-5-6 17:19
    400 次阅读|
    0 个评论
    i.MX6ULL 处理器开发设计,采用低功耗的ARM A7 架构,运行速度高达800MHz。原生支持8路UART 、 2路Ethernet、2路 CAN总线 、 2路USB 、LC D等常用接口。并采用超小尺寸设计, 核心板 尺寸仅 40*29mm,适应更多体积受限的应用场景 为了方便用户对核心板的性能及功能进行测试, 飞凌 提供了配套的功能评估板,将产品开发过程中常用的功能接口引出,比如说2路的Ethernet、2路的USB、2路的CAN以及4路的UART、2路的 SPI 和2路的IIC,同时这里还预留了显示的LCD接口以及4G模组、WIFI模组的插槽等。 本文以用户快速熟悉产品,了解接口功能和测试方法为目的,主要讲述了飞凌 iMX6ULL 开发板 WIFI接口功能的测试方法,以及使用过程中出现的一些问题如何排查。在测试过程中,对一些 命令 进行了注释,方便用户理解,以实用够用为主。 一、 iMX6 ULL开发板 WIFI 功能测试 WiFi支持: 模块 支持 RTL8188EUS WiFi RTL8723BU WiFi RTL8723DU WiFi 1、 USB WIFI RTL8188eus使用 说明: USBWIFI无线局域网卡是选配模块 ,如若有需求,请联系 飞凌嵌入式 官网在线客服。 以下对wifi模块在STA模式下,连接到 无线网络 的测试: 步骤1:iMX6ULL开发板上电,启动 Linux 系统。 步骤2:连接USB WIFI到飞凌iMX6ULL开发板的USB Host接口 步骤 3 :按照如下格式输入相应的参数: -i表示wifi型号; -s表示 wifi热点 名称; -p表示密码,若无密码输入-p NONE; 路由器采用wpa加密方式。具体操作指令可查看wifi.sh脚本。 连接打印内容如下: root@fl-imx6ull:~# fltest_cmd_wifi.sh -i 8188 -s forlinx -p xxxx 打印信息如下: wifi 8188 ssid forlinx pasw xxxx usbcore: deregistering interface driver rtl8723bu RTL871X: module exit start usbcore: deregistering interface driver rtl8188eu RTL871X: rtw_ndev_uninit(wlan1) usb 1-1.3: reset high-speed USB device number 7 using ci_hdrc RTL871X: module exit success RTL871X: module init start RTL871X: rtl8188eu v4.3.0.9_15178.20150907 RTL871X: build time: Mar 25 2020 02:23:46 bFWReady == _FALSE call reset 8051... RTL871X: rtw_ndev_init(wlan0) usbcore: registered new interface driver rtl8188eu RTL871X: module init ret=0 rtl8188e_iol_efuse_patch IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready ps: invalid option -- 'f' BusyBox v1.24.1 (2019-04-27 02:24:01 CST) multi-call binary. Usage: ps Successfully initialized wpa_supplicant rfkill: Cannot open RFKILL controRTL871X: set bssid:00:00:00:00:00:00 l device RTL871X: set ssid fw_state=0x00000008 ioctl : Operation not permitted ioctl : Resource temporarily unavailable ioctl : Resource temporarily unavailable RTL871X: indicate disassoc wlan0: Trying to associate with 04:d7:a5:84:fa:40 (SSID='forlinx' freq=2437 MHz) RTL871X: set ssid fw_state=0x00000008 RTL871X: set bssid:04:d7:a5:84:fa:40 RTL871X: start auth RTL871X: auth success, start assoc RTL871X: assoc success IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready RTL871X: recv eapol packet wlan0: Associated with 04:d7:a5:84:fa:40 RTL871X: send eapol packet RsvdPageNum: 8 udhcpc (v1.24.1) started RTL871X: recv eapol packet RTL871X: send eapol packet RTL871X: recv eapol packet RTL871X: send eapol packet RTL871X: set pairwise key camid:4, addr:04:d7:a5:84:fa:40, kid:0, type: AE S wlan0: WPA: Key negotiation completed with 04:d7:a5:84:fa:40 wlan0: CTRL-EVENT-CONNECTED - Connection to 04:d7:a5:84:fa:40 completed Sending discover... Sending select for 192.168.4.129... Lease of 192.168.4.129 obtained, lease time 36000 /etc/udhcpc.d/50default: Adding DNS 222.222.202.202 /etc/udhcpc.d/50default: Adding DNS 222.222.222.222 Finshed! 脚本运行完,能自动分配ip并添加DNS,则wifi连接成功。 步骤5:ping ip或者域名,命令如下。 root@fl-imx6ull:~# ping -c 4 www.baidu.com PING www.baidu.com (220.181.38.149): 56 data bytes 64 bytes from 220.181.38.149: seq=0 ttl=51 time=26.648 ms 64 bytes from 220.181.38.149: seq=1 ttl=51 time=13.529 ms 64 bytes from 220.181.38.149: seq=2 ttl=51 time=15.656 ms 64 bytes from 220.181.38.149: seq=3 ttl=51 time=26.249 ms --- www.baidu.com ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max = 13.529/20.520/26.648 ms 步骤6:卸载已经加入内核的模块。 root@fl-imx6ull:~# rmmod 8188eu 打印信息如下: RTL871X: module exit start usbcore: deregistering interface driver rtl8188eu RTL871X: indicate disassoc RTL871X: rtw_cmd_thread: DriverStopped(1) SurpriseRemoved(0) break at line 478 wlan0: CTRL-EVENT-DISCONNECTED bssid=04:d7:a5:84:fa:40 reason=3 locally_generated=1 RTL871X: rtw_ndev_uninit(wlan0) RTL871X: rtw_dev_unload: driver not in IPS usb 1-1.3: reset high-speed USB device number 7 using ci_hdrc RTL871X: module exit success 2、 板载WIFI的使用 说明: lwifi频率为2.4G l兼容8723bu和8723du两种wifi驱动 l默认路由器采用wpa加密方式。 如果开发板有板载的WIFI无线局域网卡,则焊接在评估板如图所示位置(下图为8723du): 步骤1:检查iMX6ULL开发板是否已经焊接该模块,正确焊接如上图。连接上天线。 步骤2:iMX6ULL开发板上电,启动Linux系统,先使用lsmod查看模块加载状态: root@fl-imx6ull:~# lsmod Module SizeUsed by mx6s_capture 148760 8723 du 13138930 //默认wifi自动加载,8723du已加载成功 ov9650_camera 124460 注意:若 飞凌iMX6ULL 开发板上焊接的是8723 b u,使用lsmod会显示8723 b u 以下以8723du为例进行测试描述: 步骤3:测试 ØSTA模式 该模式即作为一个站点,连接到无线网络中, 操作方法 如下: -i表示wifi型号;-s表示wifi热点名称;-p表示密码,若无密码输入-p NONE;路由器采用wpa加密方式,具体操作指令可查看wifi.sh脚本 root@fl-imx6ull:~# fltest_cmd_wifi.sh -i 8723du -s forlinx -p xxx //执行测试脚本 打印信息如下: wifi 8723du ssid forlinx pasw xxx usbcore: deregistering interface driver rtl8723du usbcore: registered new interface driver rtl8723du IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready Successfully initialized wpa_supplicant rfkill: Cannot open RFKILL control device udhcpc (v1.24.1) started Sending discover... wlan0: CTRL-EVENT-REGDOM-CHANGE init=BEACON_HINT type=UNKNOWN wlan0: Trying to associate with 04:d7:a5:f9:26:1d (SSID='forlinx' freq=2427 MHz) wlan0: Associated with 04:d7:a5:f9:26:1d IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready wlan0: WPA: Key negotiation completed with 04:d7:a5:f9:26:1d wlan0: CTRL-EVENT-CONNECTED - Connection to 04:d7:a5:f9:26:1d completed nf_conntrack: automatic helper assignment is deprecated and it will be removed soon. Use the iptables CT target to attach helpers instead. Sending discover... Sending select for 192.168.5.186... Lease of 192.168.5.186 obtained, lease time 1800 /etc/udhcpc.d/50default: Adding DNS 222.222.202.202 /etc/udhcpc.d/50default: Adding DNS 222.222.222.222 WLAN Finshed! 脚本运行完,能自动分配ip并生成DNS,则wifi连接成功。 ping ip或者域名,命令如下: root@fl-imx6ull:~# ping -c 5 www.baidu.com 打印信息如下: PING 192.168.4.1 (192.168.4.1): 56 data bytes 64 bytes from 192.168.4.1: seq=0 ttl=128 time=39.783 ms 64 bytes from 192.168.4.1: seq=1 ttl=128 time=81.529 ms 64 bytes from 192.168.4.1: seq=2 ttl=128 time=15.236 ms 64 bytes from 192.168.4.1: seq=3 ttl=128 time=12.076 ms 64 bytes from 192.168.4.1: seq=4 ttl=128 time=16.300 ms --- 192.168.4.1 ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max = 12.076/32.984/81.529 ms wifi信号 查看WiFi信号方法如下: root@fl-imx6ull:~# cat /proc/net/wireless | grep wlan0 | awk '{print $3}' //获取信号强度 78. root@fl-imx6ull:~# cat /proc/net/wireless | grep wlan0 | awk '{print $4}' //获取信号质量,单位dBm -68. root@fl-imx6ull:~# cat /proc/net/wireless | grep wlan0 | awk '{print $5}' //网口背景噪声,单位dBm -256. AP模式 说明: l本模块支持AP模式,理论最大连接用户为8个。 l本例为以太网eth0连接路由器说明,配置完以太网后,需要测试eth0是否可以连接外网,如果可以连接外网(方法参考 “有线网卡”章节),请继续按照操作步骤执行,如果不可以请检查以太网或者路由器连接是否正常。 工作在AP模式下,手机等设备可以直接连接模块。 设置以太网IP,配置网络防火墙: root@fl-imx6ull:~# udhcpc -i eth0 //自动分配IP,若以测试eth0网络正常,可不操作此步 /proc/sys/net/ipv4/ip_forward //打开 IP 转发 root@fl-imx6ull:~# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE//设置转发规则 设置WiFi的模式与IP 确保模块8723bu已经加载。 root@fl-imx6ull:~# ifconfig wlan0 up //打开WiFi root@fl-imx6ull:~# ifconfig wlan0 192.168.0.10 netmask 255.255.255.0//设置IP与子网掩码 root@fl-imx6ull:~# ifconfig wlan0 promisc //设置 wlan0 为混杂模式 开启AP root@fl-imx6ull:~# udhcpd /etc/udhcpd/udhcpd.conf & //WiFi 地址、 网关 等配置信息 root@fl-imx6ull:~# hostapd -d /etc/hostapd/hostapd.conf & //加密方式、用户名、密码等设置 hostapd.conf文件中:ssid为用户名,/为密码 手机等移动终端可以通过WiFi连接到开发板的AP热点,iMX6ULL开发板默认使用以下用户名和密码: 热点名:forlinxtest密码:1234567890 步骤4:卸载已经加入内核的模块: root@fl-imx6ull:~# rmmod 8723du usbcore: deregistering interface driver rtl8723du wlan0: CTRL-EVENT-DISCONNECTED bssid=04:d7:a5:f9:26:1d reason=0 够不够详细呢?希望能够帮助到你!
  • 热度 13
    2020-11-17 10:46
    973 次阅读|
    0 个评论
    By Toradex 胡珊逢 在使用嵌入式 Linux 系统的时,会出现由于设备意外断电引起文件系统损坏而最终使该设备无法启动的现象。为了应对这种情况,通常会从硬件设计如采用备用电源,无论是锂电池还是超级电容等,或者从系统软件设上加以规避。本文接下来将介绍如何使用 squashfs 只读文件系统制作 Linux 系统文件,并采用 overlayfs 为用户目录增加可写权限。演示采用 Colibri iMX6 计算机模块,该方法同样也适用于 Toradex 其他产品,如 iMX8 计算机模块。 Squashfs 是一种只读压缩文件系统,通常被用于数据备份或者系统资源受限的计算机系统上使用,如 Linux 发行版的 LiveCD , OpenWRT 系统也采用 squashfs 。 OverlayFS 一个结合其他文件系统的联合挂载,将多个挂载点叠加为一个目录。常见的应用是在一个只读的分区上叠加可读写的另一个分区。嵌入式 Linux 设备通常的功能都是被设计好的,极少需要在后期安装其他软件或更改 Linux 系统软件,更多的是更新设备应用程序和相关数据。因此基于 squashfs 的只读文件系统,结合 overlayfs 为用户应用和数据提供读写操作,能够提高嵌入式 Linux 文件系统可靠性。 在 Colibri iMX6 的 eMMC 上我们将使用以下分区规划。 BootFS 为 FAT32 格式,该分区上包含 Linux 内核文件, device tree 等启动文件,如果是 iMX8 ,则还包含一些其他固件文件。该分区通常只在文件系统烧写阶段被写入。 RootFS 分区是 Linux 运行的文件系统, usr, bin, lib, etc, home 等目录都在上面。一般该分区是 EXT3 , EXT4 格式,支持文件的写入和删除。而文件系统的损坏也常发生于此,最终导致设备启动失败。因此我们这里会采用只读格式的 squashfs 。 UserData 是能够读写的 EXT4 分区。该分区通过 overlayfs 会被挂载到原本位于只读 squashfs 中的 /home/root 目录。用户应用可以毫无察觉得使用该目录,在上面写入和删除文件,但不破坏只读 squashfs 文件系统,所有的操作都会被转移到 UserData 分区上。用户的应用也会存在 UserData 分区上,启动的时候从这里加载应用程序。该分区是可写的,所有这上面的文件是可以被更新。 ​ 下面我们会具体说明如何在 Yocto 环境生成符合上面规划的 BSP ,并通过 Toradex Easy Installer 工具实现这些分区和写入文件。 首先需要在 Yocto 环境中生成 squashfs 格式的系统文件 rootfs 。修改 build/conf/local.conf ,结尾添加以下内容。 ------------------------------------ IMAGE_FSTYPES_append = " squashfs" ------------------------------------ 默认 Linux 内核配置下 squahfs 是通过加载内核驱动模块实现对其支持,而模块驱动文件位于 rootfs 中,为了保证 Linux 内核在启动时能够正确处理该格式,需要将 squahfs 内核驱动模块配置为静态驱动,直接编译进内核中。为内核配置的文件系统支持添加 squahfs 和 overlay 格式。 ------------------------------------ $ MACHINE=colibri-imx6 bitbake -c menuconfig virtual/kernel → File systems Overlay filesystem support → File systems → Miscellaneous filesystems SquashFS 4.0 - Squashed file system support ------------------------------------ EXT4 格式的 UserData 分区会通过 overlay 机制挂载到只读的 rootfs 上的 /home/root ,但这之前需要通过 fstab 将该分区挂载到系统中, /home/root 。在 Yocto 中, layers/meta-toradex-demos/recipes-core/base-files/base-files/fstab 会被编译到 Colibri IMX6 BSP 中,在该文件中添加: ------------------------------------ /dev/mmcblk0p3 /media/data auto defaults,sync,noauto 0 0 ------------------------------------ 然后再添加一个开机自启动脚本,将 /media/data 使用 overlay 挂载到 /home/root 。 在 layers/meta-toradex-bsp-common/recipes-core 目录中添加 mount-overlayfs 文件夹,里面包含编译需要的 bb 文件和 systemd service 。 mount-overlayfs.bb 中 install -d ${D}/media/data 会在 /media 目录中创建 data 文件夹, FILES_${PN} = "/media/data" 将该空文件夹添加到 BSP 中。 mount-overlayfs.service 通过 RequiresMountsFor 保证 /media/data 目录通过 fstab 挂载后才运行。 Overlay 的目录结构如下, lowerdir 为 /home/root upperdir 为 /media/data/home/root/upper , workdir 为 /media/data/home/root/work 。这样应用可以在 /home/root 下直接读写文件, overlayfs 对应用和用户都是透明的。 ------------------------------------ Type=simple ExecStart=/bin/sh -c 'mount -t overlay -o lowerdir=/home/root,upperdir=/media/data/home/root/upper,workdir=/media/data/home/root/work overlay /home/root' ------------------------------------ 在 build/conf/local.conf 中将 mount-overlayfs 添加到 BSP 中。 ------------------------------------ IMAGE_INSTALL_append = " mount-overlayfs" ------------------------------------ 由于 rootfs 是只读格式,无法像之前一样直接在开发板上运行 systemctl 命令添加开机自启动脚本。我们需要像上面一样,在 Yocto 中增加一个 test-app 来开机自动运行位于 UserData 分区(该分区通过 overlay 会被最终挂载到 /home/root 目录)上的测试程序 test 。在 layers/meta-toradex-bsp-common/recipes-core 目录中添加 test-app 文件夹,里面包含编译需要的 bb 文件和 systemd service 。 在 build/conf/local.conf 中将 test-app 添加到 BSP 中。 ------------------------------------ IMAGE_INSTALL_append = " mount-overlayfs test-app" ------------------------------------ 至此我们已经通过修改 Yocto 能够生成所需结构的 BSP ,执行下面命令完成编译任务。 ------------------------------------ $ MACHINE=colibri-imx6 bitbake tdx-reference-minimal-image ------------------------------------ 在 build/deploy/images/colibri-imx6 有相关文件生成,我们需要下面两个文件,文件名字中的时间戳对应具体编译的日期。 Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0.tar Colibri-iMX6_Reference-Minimal-Image.rootfs.squashfs 解压 Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0.tar 。因为 rootfs 是 squahfs 格式,需要使用定制的 boot.src 来启动。 ------------------------------------ $ cd ~/ $ tar vxf Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0.tar $ cd Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0 $ tar vxf Reference-Minimal-Image-colibri-imx6.bootfs.tar.xz ------------------------------------ 修改其中的 emmcargs_set 参数。 ------------------------------------ env set emmcargs_set 'env set rootfsargs root=/dev/mmcblk0p2 rootfstype=squashfs ro rootwait' ------------------------------------ 可以使用该 boot.cmd 直接生成对应的 boot.src, 替换解压目录中同名文件 , 重新打包 Reference-Minimal-Image-colibri-imx6.bootfs.tar.xz ------------------------------------ $ cd Reference-Minimal-Image-colibri-imx6.bootfs $ rm boot.src $ mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "Distro boot script" -d boot.cmd boot.scr $ cd .. $ tar cJf Reference-Minimal-Image-colibri-imx6.bootfs.tar.xz -C Reference-Minimal-Image-colibri-imx6.bootfs . ------------------------------------ 将 squashfs 的 rootfs 文件系统复制到 Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0 目录中。 ------------------------------------ $ cp Colibri-iMX6_Reference-Minimal-Image.rootfs.squashfs Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0 ------------------------------------ 接下来创建需要复制到 UserData 分区中的文件。如上面提到的 overlay 挂载需要有对应目录结构,依次创建以下目录,并将测试程序 test 复制到 upper 目录中。这里的测试程序 test 是一个非常简单的 C 应用,它会输出“ Hello Toradex! ”到系统日志中。 ------------------------------------ $ cd ~/Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0 $ mkdir rootfs $ cd rootfs $ mkdir -p home/root/upper $ mkdir -p home/root/work $ cp ~/test home/root/upper $ tree ------------------------------------ 打包为 rootfs.tar.xz 。 ------------------------------------ $ cd .. $ sudo tar cJf rootfs.tar.xz -C rootfs . ------------------------------------ 修改 image.json 文件,在 blockdevs 中增加 RAW 格式分区用于直接写入 squashfs 系统文件,以及 EXT4 格式的 DATA 分区用于写入上面生成的 rootfs.tar.xz 。 Colibri-iMX6_Reference-Minimal-Image-Tezi_5.1.0-devel-20201112022057+build.0 目录下最终包含以下文件。 将上面的 BSP 通过 Toradex Easy Installer 重新安装到 Colibri iMX6 上,安装的时候注意需要点击 Erase 擦除 eMMC 上的内容。 烧写后重启模块。可以通过 mount 命令查看挂载分区的情况。 ------------------------------------ root@colibri-imx6:~# mount /dev/mmcblk0p2 on / type squashfs (ro,noatime) …… /dev/mmcblk0p3 on /media/data type ext4 (rw,relatime,sync) overlay on /home/root type overlay (rw,relatime,lowerdir=/home/root,upperdir=/media/data/home/root/upper,workdir=/media/data/home/root/work) ------------------------------------ mmcblk0p2 为写入 squashfs 只读文件系统的分区,例如在 /etc 目录无法创建文件。 ------------------------------------ root@colibri-imx6:/etc# mkdir test-folder mkdir: can't create directory 'test-folder': Read-only file system ------------------------------------ EXT4 格式的 /dev/mmcblk0p3 分区上是用户文件,被挂载到 /media/data 。而 /home/root 会通过 overlay 具有可读写权限。 ------------------------------------ root@colibri-imx6:~# cd ~/ root@colibri-imx6:~# pwd /home/root root@colibri-imx6:~# mkdir test-folder root@colibri-imx6:~# ls test test-folder root@colibri-imx6:~# ls -lh -rwxrwxr-x 1 1000 1000 11.3K Nov 11 2020 test drwxr-xr-x 2 root root 4.0K Feb 7 16:25 test-folder ------------------------------------ 位于 UserData 上的测试程序 test 也在开机的时候自动运行。 ------------------------------------ root@colibri-imx6:~# journalctl -u test-app -- Logs begin at Fri 2020-02-07 15:50:53 UTC, end at Fri 2020-02-07 16:11:49 UTC. -- Feb 07 15:50:57 colibri-imx6 systemd : Started start a demo on overlay mount folder. Feb 07 15:50:57 colibri-imx6 test : Hello Toradex! Feb 07 15:50:57 colibri-imx6 systemd : test-app.service: Succeeded. ------------------------------------ 总结 上面我们演示结合使用 squashfs 和 overlay ,将系统文件放在一个只读分区,把读写操作在单独的分区上进行。降低系统文件因意外断电受损从而导致无法启动的风险。在使用只读 squashfs 只读文件系统时需要保证 rootfs 尽量精简,建议在 Reference-Minimal-Image 基础上构建用户自己的 BSP ,甚至对其进行裁剪。
  • 热度 2
    2020-1-6 12:11
    3143 次阅读|
    1 个评论
    By Toradex 秦海 1). 简介 NXP iMX8 已经正式发布,相较于之前 NXP i.MX 系列的主力产品 iMX6 ,其性能有了大幅提升,本文就针对网络接口对 NXP iMX8 和 iMX6 两款 ARM 处理器进行对比测试。 本文演示所使用的 ARM 平台来自 Toradex 基于 NXP iMX8 SoC 的 Apalis iMX8 ARM 核心板和基于 NXP iMX6Q SoC 的 Apalis iMX6 ARM 核心板。 2). 准备 a). Apalis iMX8QM ARM 核心版配合 Apalis Evaluation Board 载板 , Apalis iMX8QM 安装 Toradex V3.0b2 Linux demo image ,同时连接调试串口 UART1 (载板 X29 )到开发主机方便调试。更多关于 Apalis iMX8 配合 Apalis Evaluation Board 载板的说明请参考 Datasheet 和 开发上手指南 。 b). Apalis iMX6Q ARM 核心版配合 Apalis Evaluation Board 载板 , Apalis iMX6Q 安装 Toradex V2.8 Linux demo image ,同时连接调试串口 UART1 (载板 X29 )到开发主机方便调试。更多关于 Apalis iMX6 配合 Apalis Evaluation Board 载板的说明请参考 Datasheet 和 开发上手指南 。 c). Ubuntu linux PC 主机, 用于分别和 Apalis iMX8 、 Apalis iMX6 进行收发测试。 d). 测试工具软件使用 iperf3 工具, Toradex Linux demo image 里面已经默认集成, Ubuntu 系统(这里以 18.04 为例)要通过 apt 命令来安装 iperf3 ---------------------- $ sudo apt update $ sudo apt install iperf3 ---------------------- e). 网络连接拓扑为 Apalis iMX8QM 、 Apalis iMX6Q 以及 Ubuntu PC 都通过千兆有线网络连接到同一个局域网。 3). TCP 网络传输性能测试对比 a). Apalis iMX6Q/Apalis iMX8QM 作为 Server 端接收, Ubuntu PC 作为 Client 端发送测试 ./ Apalis iMX6Q/Apalis iMX8QM Server 端运行下面命令 ---------------------- $ iperf3 -s ---------------------- ./ Apalis iMX6Q ---------------------- $ iperf3 -c -t 60 -i 10 -w 300K … Interval Transfer Bandwidth Retr 0.00-60.00 sec 4.01 GBytes 574 Mbits/sec 1 sender 0.00-60.00 sec 4.01 GBytes 574 Mbits/sec receiver ---------------------- ./ Apalis iMX8QM ---------------------- $ iperf3 -c -t 60 -i 10 … Interval Transfer Bandwidth Retr 0.00-60.00 sec 6.52 GBytes 934 Mbits/sec 0 sender 0.00-60.00 sec 6.52 GBytes 934 Mbits/sec receiver ---------------------- b). Apalis iMX6Q/Apalis iMX8QM 作为 Client 端发送, Ubuntu PC 作为 Sever 端接收测试 ./ Ubuntu PC server 端运行下面命令 ---------------------- $ iperf3 -s ---------------------- ./ Apalis iMX6Q Client 端连接测试 ---------------------- root@apalis-imx6:~# iperf3 -c -t 60 -i 10 … Interval Transfer Bitrate Retr 0.00-60.00 sec 2.84 GBytes 406 Mbits/sec 0 sender 0.00-60.00 sec 2.84 GBytes 406 Mbits/sec receiver ---------------------- ./ Apalis iMX8QM Client 端连接测试 ---------------------- root@apalis-imx8:~# iperf3 -c -t 60 -i 10 … Interval Transfer Bitrate Retr 0.00-60.00 sec 6.39 GBytes 915 Mbits/sec 0 sender 0.00-60.00 sec 6.39 GBytes 915 Mbits/sec receiver ---------------------- c). 测试结果汇总 项目 TCP 发送测试 TCP 接收测试 Apalis iMX6Q 406 Mb/s 574 Mb/s Apalis iMX8QM 915 Mb/s 934 Mb/s 4). UDP 网络传输性能测试对比 a). Apalis iMX6Q/Apalis iMX8QM 作为 Server 端接收, Ubuntu PC 作为 Client 端发送测试 ./ Apalis iMX6Q/Apalis iMX8QM Server 端运行下面命令 ---------------------- $ iperf3 -s ---------------------- ./ Apalis iMX6Q ---------------------- /* 100M 带宽测试 */ $ iperf3 -c -u -b 100M -t 60 -i 10 … Interval Transfer Bandwidth Jitter Lost/Total Datagrams 0.00-60.00 sec 714 MBytes 99.9 Mbits/sec 0.110 ms 0/91424 (0%) /* 400M 带宽测试 */ $ iperf3 -c -u -b 400M -t 60 -i 10 … Interval Transfer Bandwidth Jitter Lost/Total Datagrams 0.00-60.00 sec 2.79 GBytes 400 Mbits/sec 0.098 ms 4374/365993 (1.2%) /* 1000M 带宽测试 */ $ iperf3 -c -u -b 1000M -t 60 -i 10 … Interval Transfer Bandwidth Jitter Lost/Total Datagrams 0.00-60.00 sec 2.98 GBytes 426 Mbits/sec 0.167 ms 2304/390206 (0.59%) ---------------------- ./ Apalis iMX8QM ---------------------- /* 100M 带宽测试 */ $ iperf3 -c -u -b 100M -t 60 -i 10 … Interval Transfer Bandwidth Jitter Lost/Total Datagrams 0.00-60.00 sec 714 MBytes 99.9 Mbits/sec 0.078 ms 84/91416 (0.092%) /* 400M 带宽测试 */ $ iperf3 -c -u -b 400M -t 60 -i 10 … Interval Transfer Bandwidth Jitter Lost/Total Datagrams 0.00-60.00 sec 2.79 GBytes 400 Mbits/sec 0.092 ms 121/366076 (0.033%) /* 1000M 带宽测试 */ $ iperf3 -c -u -b 1000M -t 60 -i 10 … Interval Transfer Bandwidth Jitter Lost/Total Datagrams 0.00-60.00 sec 6.63 GBytes 949 Mbits/sec 0.064 ms 284/868752 (0.033%) ---------------------- b). Apalis iMX6Q/Apalis iMX8QM 作为 Client 端发送, Ubuntu PC 作为 Sever 端接收测试 ./ Ubuntu PC server 端运行下面命令 ---------------------- $ iperf3 -s ---------------------- ./ Apalis iMX6Q Client 端连接测试 ---------------------- /* 100M 带宽测试 */ root@apalis-imx6:~# iperf3 -c -u -b 100M -t 60 -i 10 … Interval Transfer Bitrate Jitter Lost/Total Datagrams 0.00-60.00 sec 715 MBytes 100 Mbits/sec 0.000 ms 0/517952 (0%) sender 0.00-60.00 sec 715 MBytes 100 Mbits/sec 0.005 ms 0/517952 (0%) receiver /* 400M 带宽测试 */ root@apalis-imx6:~# iperf3 -c -u -b 400M -t 60 -i 10 … Interval Transfer Bitrate Jitter Lost/Total Datagrams 0.00-60.00 sec 1.91 GBytes 273 Mbits/sec 0.000 ms 0/1413705 (0%) sender 0.00-60.00 sec 1.91 GBytes 273 Mbits/sec 0.021 ms 0/1413705 (0%) receiver /* 1000M 带宽测试 */ root@apalis-imx6:~# iperf3 -c -u -b 1000M -t 60 -i 10 … Interval Transfer Bitrate Jitter Lost/Total Datagrams 0.00-60.00 sec 1.92 GBytes 274 Mbits/sec 0.000 ms 0/1421514 (0%) sender 0.00-60.00 sec 1.92 GBytes 274 Mbits/sec 0.057 ms 0/1421509 (0%) receiver ---------------------- ./ Apalis iMX8QM Client 端连接测试 ---------------------- /* 100M 带宽测试 */ root@apalis-imx8:~# iperf3 -c -u -b 100M -t 60 -i 10 … Interval Transfer Bitrate Jitter Lost/Total Datagrams 0.00-60.00 sec 715 MBytes 100 Mbits/sec 0.000 ms 0/517950 (0%) sender 0.00-60.00 sec 715 MBytes 100 Mbits/sec 0.035 ms 0/517950 (0%) receiver /* 400M 带宽测试 */ root@apalis-imx8:~# iperf3 -c 10.20.1.126 -u -b 400M -t 60 -i 10 … Interval Transfer Bitrate Jitter Lost/Total Datagrams 0.00-60.00 sec 2.79 GBytes 400 Mbits/sec 0.000 ms 0/2071798 (0%) sender 0.00-60.00 sec 2.79 GBytes 400 Mbits/sec 0.026 ms 68/2071798 (0.0033%) receiver /* 1000M 带宽测试 */ root@apalis-imx8:~# iperf3 -c 10.20.1.126 -u -b 1000M -t 60 -i 10 … Interval Transfer Bitrate Jitter Lost/Total Datagrams 0.00-60.00 sec 4.71 GBytes 674 Mbits/sec 0.000 ms 0/3489592 (0%) sender 0.00-60.00 sec 4.71 GBytes 674 Mbits/sec 0.030 ms 103/3489586 (0.003%) receiver ---------------------- c). 测试结果汇总 UDP 发送测试 UDP 接收测试 100M 带宽 400M 带宽 1000M 带宽 100M 带宽 400M 带宽 1000M 带宽 Apalis iMX6Q 100 Mb/s 273 Mb/s 274 Mb/s 99.9 Mb/s 400 Mb/s * 426 Mb/s * Apalis iMX8QM 100 Mb/s 400 Mb/s 674 Mb/s 99.9 Mb/s 400 Mb/s 949 Mb/s * 注意此时丢包率已经到 1% 左右 5). 总结 本文对比测试了 NXP iMX6 和 NXP iMX8 处理器的网络性能,对于 iMX6 ,由于这个 Eratta 的限制, 400Mb/s 左右的性能也就把符合文档的描述, iMX8 则在大多数情况下能够接近千兆带宽。
  • 热度 2
    2019-10-21 11:05
    3048 次阅读|
    1 个评论
    By Toradex 秦海 1). 简介 随着 Python 在互联网人工智能领域的流行,大家也慢慢感受到 Python 开发的便利,本文就基于嵌入式 ARM 平台,介绍使用 Python 配合 PyQT5 模块来开发图形化应用程序。 本文所演示的 ARM 平台来自于 Toradex 基于 NXP iMX6 ARM 处理器的 Apalis iMX6 ARM 嵌入式平台。 2. 准备 a). Apalis iMX6Q ARM 核心版配合 Apalis Evaluation Board 载板 ,连接调试串口 UART1 (载板 X29 )到开发主机方便调试。更多关于 Apalis iMX6 配合 Apalis Evaluation Board 载板的说明请参考 Datasheet 和 开发上手指南 。 b). Apalis iMX6Q 默认的 Linux BSP 是不包含 Python , QT 等支持的,需要重新编译。 ./ 基于 Toradex Linux BSP release V2.8 ./ 参考 这里 搭建 Openembedded 编译环境,然后适配下面 patch ,用于使本文测试需要的 libsoc 适配 Python3 。 https://github.com/simonqin09/libsoc-examples/blob/master/python/0005-libsoc-python3-support.patch ./ 修改 build/conf/local.conf 文件,增加需要的组件 -------------------------- #IMAGE_INSTALL_append = " python3 python3-pip python3-libsoc python3-pyqt5 rng-tools " -------------------------- ./ 适配下面 patch ,在标准 image bb 文件中增加 QT5 的支持 https://github.com/simonqin09/libsoc-examples/blob/master/python/0003-angstrom-qt5-lxde-image.patch ./ 重新编译 image -------------------------- $ bitbake -k angstrom-qt5-lxde-image -------------------------- ./ 新生成的 image 位于 deploy/images/apalis-imx6/ 目录,参考 这里 的说明更新到 Apalis iMX6 模块上面 3). Python GPIO 中断测试程序 a). 首先我们先不包含图形界面,单独通过 Python 来完成简单的 GPIO 中断测试程序,本程序通过调用 libsoc 来完成 GPIO 控制,关于 libsoc 的使用和说明请参考 这里 。 b). Apalis Evaluation Board 载板硬件连接配置如下, X4 GPIO05(MXM3_11) 对应系统中的 GPIO 号码是 170 ,作为按键输入使用; X4 GPIO06(MXM3_13) 对应系统中的 GPIO 号码是 169 ,作为输出驱动 LED 使用。 X4 GPIO05 X34 SW5 X4 GPIO06 X34 LED1 c). 源代码请参考如下,分别实现了阻塞模式和非阻塞模式中断相应,实现功能就是按键交替点亮和关闭 LED 灯。 ./ 阻塞模式 – https://github.com/simonqin09/libsoc-examples/blob/master/python/gpiotest_block.py // main 函数作为主函数,实现打开 GPIOs ,同时设定初始化状态为高电平输出; test_interrupt_handler 函数实现中断相应,采用 gpio_in.wait_for_interrupt 为阻塞式中断,捕获中断才会继续进行,捕获中断后做了简单的防误触处理。 ./ 非阻塞模式 – https://github.com/simonqin09/libsoc-examples/blob/master/python/gpiotest_nonblock.py // main 函数作为主函数,实现打开 GPIOs ,同时设定初始化状态为高电平输出;另外,在 main 函数里面采用 gpio_in.start_interrupt_handler 来使能中断相应,为非阻塞式;在 main 函数最后通过 while 来接收键盘输入实现退出应用; gpio_in.wait_for_interrupt 依然作为中断处理函数相应中断并驱动 LED 状态改变。 d). 将 Python 代码直接复制到 Apalis iMX6 上面测试运行结果如下: ./ 阻塞模式下,最后是通过 Ctrl-C 强制退出程序 ----------------------- root@apalis-imx6:~# ./gpiotest_block.py The LED initial status is ON The LED turns OFF interrupt times is 1 The LED turns ON interrupt times is 2 ^Clibsoc-gpio-debug: Interrupted system call Traceback (most recent call last): File "./gpiotest_block.py", line 54, in main(gpio_input_id, gpio_output_id) File "./gpiotest_block.py", line 45, in main test_interrupt_handler(gpio_in, gpio_out) File "./gpiotest_block.py", line 12, in test_interrupt_handler gpio_in.wait_for_interrupt(-1) File "/usr/lib/python3.5/site-packages/libsoc/gpio.py", line 118, in wait_for_interrupt if api.libsoc_gpio_wait_interrupt(self._gpio, timeout) != 0: KeyboardInterrupt ----------------------- ./ 非阻塞模式下 ----------------------- root@apalis-imx6:~# ./gpiotest_nonblock.py The LED initial status is ON please enter 'Q' to quit The LED turns OFF The LED turns ON The LED turns OFF Q Do you really want to quit? yes or no yes root@apalis-imx6:~# ----------------------- 4). 使用 PyQt5 实现图形化界面 GPIO 中断程序 a). 硬件配置和连接和上面的测试场景一致。 b). 为了方便开发 PyQt5 界面,首先通过 Qtcreator 创建如下 QWidget 项目 UI 界面 // LED Status 右边的 QFrame 方框以及 QLable 用于显示 LED 当前的状态 // ‘Turn ON’ 和 ’Turn OFF’ 两个 PushButton 用于通过界面控制 LED 状态, ’Exit’ PushButton 用于退出程序 ./ 最终的 UI 源代码参考如下,将对应的 mainwindow.ui 文件复制到 Apalis iMX6 Python 应用相同路径下 https://github.com/simonqin09/libsoc-examples/blob/master/python/mainwindow.ui c). 程序源代码参考如下: https://github.com/simonqin09/libsoc-examples/blob/master/python/gpiotest_pyqt5.py 说明如下: ./ class ApplicationWindow 用于实现 Qt5 界面以及相关按键操作: // 首先通过 loadUi 函数来加载之前制作好的 UI 文件 mainwindow.ui ,然后初始化界面显示,连接各个按键对应的处理程序 // 最后开启一个新的 Qthread 线程 self.thread ,用于处理外部 GPIO 按键中断相应,连接新线程反馈信号的处理程序,最后启动新线程 // LedStatusChange 函数为处理新线程反馈回来的 LED 状态变化信号而同步改变界面显示状态的函数 // Button_On_clicked 和 Button_Off_clicked 函数用于根据界面按键的点击来对应改变 LED GPIO 输出以及界面显示的函数 // Button_Exit_clicked 和 closeEvent 函数用于处理退出程序包括子线程的退出等相关的函数 ./ class gpioInterrupt 为用于处理 GPIO 中断同时对于改变 LED GPIO 输出以及将 LED 状态变化反馈给界面主程序 // 首先定义反馈信号,并初始化所需要使用的 GPIO 引脚 // run 函数部分基本就是上面第 3 章节的阻塞模式 Python 应用的代码,这里就不做赘述了 d). 测试运行结果如下: ----------------------- root@apalis-imx6:~# ./gpiotest_pyqt5.py The LED initial status is ON set LOW set HIGH The LED turns OFF button clicked for setting LOW The LED turns ON button clicked for setting HIGH root@apalis-imx6:~# ----------------------- 5). 总结 如上述示例,使用 Python 和 PyQt5 非常方便了创建一个嵌入式界面应用程序示例,相对于传统 C 语言开机要配置交叉编译环境,整个流程更加快捷方便,同时在实现比较简单的控制的时候其运行效率也是可以接受的,另外 Python 还可以集成大量的组件方便开发,就更加简化了比如设计机器视觉、人工智能等领域的嵌入式应用开发流程。
相关资源