嵌入式设备有个天生赋予的重点任务,就是要成为自动控制整体方案中的一员。早期市场对自动控制的需求主要集中在单纯的“机电控制”上,而具备智能计算的Jetson系列产品相对与几十元的这类控制板来说,成本是高出一个阶位。
但是随着“智能+控制”的结合功能成为新工业主流需求之后,成本已经不是最首要的关键因素,因为智能设备所带来的价值已经远远超过先前的成本差异。NVIDIA Jetson设备就是在这样的风潮下逐渐崭露头角,为智能工业带来新的生命力。
透过“扩充引脚”的方式与机电控制设备进行对接,是绝大部分嵌入式设备所采用的方法。NVIDA在2015年的Jetson TK1产品就已经配置了这方面的引脚,经历了TX1/TX2到AGX Xavier的阶段,依旧保有这方面的接口(如下图),一直到2019年Jetson Nano推出之后,采用与树莓派兼容的40针引脚的设计,在战略上是个非常高明的设计。
过去10年是创客(maker)兴盛的年代,而树莓派凭借“硬件开源”的风潮吸引庞大的民间实力,开发了相当齐全的周边产品,下表是比较常用的一部分设备清单,全部都是基于树莓派40针引脚定义所设计。
如今Jetson Nano(含2GB)、Xavier NX等开发套件的引脚也兼容于树莓派的定义时,就表示上面列表中的周边设备,都能直接适用于现在主流的Jetson开发套件,不仅无需依赖中间的转换器,包括代码也可以不需要修改,就能将原本不具备深度学习能力的树莓派方案,立即移植到NVIDIA的智能Jetson设备上,马上变成是“智能控制”的应用设备,实用价值瞬间就提高一个档次。
本文属于Jetbot系列中的一环,不过在进入与周边设备(PiOLED、PCA9685等)对接之前,有必要让初学者对Jetson的40针引脚的细节与使用有进一步的了解,因为Jetbot是一个经典的项目,但更重要是要能初学者可以自行搭建更多的应用。
过去缺乏智能识别能力的创客项目,多属于较为单调的固定执行流程的应用,但是有了NVIDIA Jetson的智能识别能力之后,就能让这类项目变得非常多彩多姿,并且更加贴近生活或工作上的实用场景,例如根据垃圾分类识别后进行处理的机械手臂、根据猫脸识别后对特定猫开启喂食器、根据水果成熟度进行采摘等应用,都是实用价值非常高的,这才是真正智能设备的创造动力。
网上有不少探索Jetson这40根引脚的文章,但内容相对笼统并且有些部分的混淆,对初学者来说会产生障碍。本文的重点就是将以下三个部分讲解清楚:
只要将这三个关系捋清楚后,整个40针引脚的使用就会瞬间变得非常简单。假如上述三个关系您都很熟悉了,就可以跳过本文的内容;如果还没搞清楚的,请仔细阅读本文,能让您很有条理地掌握这些引脚的使用要领。
下图是Jetson的40帧引脚图的说明,适用于Nano(含2GB)、Xavier NX与AGX Xavier等开发套件。虽然上面满满的内容,乍看之下的确令人眼花缭乱,只要看完我们所作的分解之后,就会让这部分的内容变得非常简单。
首先,虽然大家平常时候习惯将这些引脚统称为GPIO,但事实上这40根引脚主要分成GPIO(General Purpose I/O)通用功能与SFIO(Special Function I/O)特定功能两大类,后者总共有18根与开发套件底板电子电力直连的脚位,这是不能重新定义的固定功能,主要分为以下三种:
这两个接脚也能对5.0V规格的周边设备进行供电,但是非常不推荐这样使用,因为Jetson本身的电力已经处于吃紧状态,如果再对其他设备提供5V输出,很可能影响整体稳定性。
这样一整理之后,是不是就变得很简单了?撇开电源相关的12根脚位之外,真正需要了解的,就是两组I2C与一组UART共6个脚位,这18根脚位的定义与树莓派是完全一致。在Jetbot项目中也就使用1组3.3V/GND电源与1组I2C的SDA/SCL而已,总共4根引脚就能完成智能车的任务。
如果原本树莓派创客项目中只使用这类的I2C或UART引脚的话,几乎不需修改代码就能将原本的应用移植到Jetson Nano(含2GB)设备上,立刻升级为智能识别的应用,所展现的价值就马上提高一个台阶。
至于另外22根“可重新定义”脚位,才是很多网上所探索的 ”GPIO” 内容,其实正确的说法应该是“Jetson的22根GPIO引脚使用”才对,不过这里就不去纠正这些小问题,重点在于让大家更清楚剩下这22根引脚的用法。
事实上这些引脚也有两种处理方式:
网上大部分的混淆就在这个Jetson-IO工具与Jetson.GPIO库,前者是Jetpack自带的底层系统引脚配置工具,后者是针对GPIO引脚的应用层开发库,二者之间是不仅完全独立的,甚至某种角度上还有些许“互斥”的关系。
接下去带着大家将这两个工具认识清楚,这样日后的开发就会非常简单。
前面已经清楚在40根引脚中有18根是固定好不能重新定义,剩下的问题就是如何处理这22根“可重新定义”的引脚,是否有什么工具可以协助我们确认目前所有脚位的状态呢?这就是Jetson-IO的主要工作了,请执行以下指令,看看显示怎样的结果?
$ |
sudo /opt/nvidia/jetson-io/config-by-pin.py |
是否看到显示从1到40的状态?核对一下,是不是除了前面所说18个SFIO位置之外的22个引脚,都显示 ”unused” 状态?这些呈现 ”unused” 的脚位就是GPIO的状态,能用Jetson.GPIO库直接指派与调用。
如果要对这22个脚位进行重新定义,该使用什么方法来操作?Jetson-IO工具就是扮演“配置脚位功能”的角色,这是NVIDIA从L4T 32.3版本开始,提供可以修改引脚定义的工具,在Jetpack烧录过程就编译到开发套件的 /opt/nvidia/jetsion-io目录下,这是属于系统底层的配置工具。
因为设备所有I/O的默认配置是静态定义的,早期要更改40针扩展引脚定义时置,必须使用相应平台的pinmux电子表格去更新管脚配置,然后将新配置烧回开发套件中,虽然这是更新系统的一种适当方法,但在开发的阶段,需要一种更方便的方法,来测试不同的管脚配置。
Jetson-IO工具就是要简化40针引脚I/O配置的修改任务,提供一套基于Python的简单代码,最终会将修改的内容写入设备树(DTB, Device Tree, Blob)固件,重启设备就能让新的设置生效,非常方便。
如果想要修改前面所提到的22根脚位定义,最轻松的方法就是执行以下步骤:
$ |
sudo /opt/nvidia/jetson-io/jetson-io.py |
进入主菜单后,选择下面的 ”Configure 40-pin expansion header”,就会出现以下选择菜单视窗,透过“上下键”与“空键”选择要设定的组:
这里是根据“功能”的提供脚位组合,所定义的脚位与前面40针引脚定义图是完全对应的,也就是说在18根SFIO以外的脚位,必须经过Jetson-IO的配置之后,才会具备引脚图中的功能,但这个步骤并未出现在任何说明文件或网上教程之中,导致很多初学者完全无法理会其中的奥秘,我们在这里为大家打开这个黑箱子。
现在试着启动spi1组设置,Jetson-IO工具会同时配置后面的5个脚位。设置完毕后选择 ”Save and reboot to reconfigure pins”,重启系统之后再执行:
$ |
sudo /opt/nvidia/jetson-io/config-by-pin.py |
是否看到脚位[ 19, 21, 23, 24, 26]的状态,现在都出现 ”spi1” 的标识了?
在/opt/nvidia/jetson-io/目录下还有config-by-function.py、config-by-pin.py与config-by-hardware.py三个工具,根据不同目的查询与设置GPIO接脚属性。详细的内容请至https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-325/index.html里 ”Hardware Setup” 的 ”Configuring the 40-Pin Expansion Header”,有完整的使用说明。
这是属于应用级的开发库,是针对“未被Jetson-IO设置为SPIO”的GPIO引脚进行配置与运作的应用库。
例如引脚19在前面Jetson-IO配置为spi1功能之前,就是作为GPIO功能,可以用Jetson.GPIO库去指派与调用;但是经过spi1配置并重启之后,引脚19已经属于SFIO而非GPIO,这时候如果用Jetson.GPIO库去指定这个引脚,就不会产生作用。
前面提过“从某种角度来说Jetson.GPIO与Jetson-IO是互斥的”,道理就在这个地方,一旦被Jetson-IO配置并启动的脚位,就不再属于GPIO的功能了。
这个Jetson.GPIO开发库并不在Jetpack安装包里,因此需要手动安装与从github上下载范例代码。下面指令可以简单安装这个库:
$ |
sudo pip3 install Jetson.GPIO |
如果想要获得这个开发库的范例,就执行以下指令:
$ $ |
cd ~ && git clone https://github.com/NVIDIA/jetson-gpio cd jetson-gpio/samples |
这里的范例都需要结合一些很基本的电子实验设备,例如面包板、LED灯、杜邦线、小电阻、小电容之类的设备,实验内容非常简单,请自行采购相关元件并跟着说明执行就可以,这里不做这些范例的讲解。
至于还有些环境变量配置问题,也请参考开源项目内的说明,不过在Jetbot项目中都已经调试好了。
这是最后一个容易造成混淆的部分,因为作为GPIO用途的脚位有四种调用的模式,这也是因为过去长年积累的兼容性问题所导致的,不过只要搞清楚之后也都不是大问题。
在代码一开始的时候,需要使用 ”GPIO.setmode(GPIO_MODE)” 指令进行模式的指定,其中 ”GPIO_MODE” 可以是以下四种:
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.IN) # 设置12号引脚为输入
GPIO.setup(13, GPIO.OUT, initial=GPIO.HIGH) # 设置13号引脚为输出
这是最直观而且简单的模式,推荐初学者使用!
下面是简单的调用方法,不过指定的脚位是根据BCM编码原则:
GPIO.setmode(GPIO.BCM)
GPIO.setup(12, GPIO.IN) # 设置D12(BOARD的32)脚位为输入
GPIO.setup(13, GPIO.OUT) # 设置D13(BOARD的33)脚位为输出
很多传统树莓派的项目里习惯使用BCM编码,仔细对照就能轻易理解。
GPIO.setmode(GPIO.TEGRA_SOC)
GPIO.setup('SPI1_SCK', GPIO.IN) # 设置BOARD的23脚位为输出
GPIO.setup('SPI1_MISO', GPIO.OUT) # 设置BOARD的21脚位为输出
过去大家对于NVIDIA Jetson系列产品的深度学习能力是比较熟悉的,但是要将使用价值再扩展到工业场景的时候,也必须对这个40针引脚的用法有足够的掌握。
本文将大部分困扰初学者的问题进行较更有逻辑的梳理,日后只要大家能弄清楚SFIO与GPIO之间的差异、Jetson-IO与Jetson.GPIO的不同,以及GPIO四种编码模式的对应脚位如何查找,其他的问题就是透过代码去熟练这些调用,也不必在乎是用Python库还是C语言库了。[完]
好文章,需要你的鼓励
临近年底,苹果公布了2024年App Store热门应用和游戏榜单,Temu再次成为美国下载量最多的免费应用。
云基础设施市场现在已经非常庞大,很难再有大的变化。但是,因为人们可以轻松地关闭服务器、存储和网络——就像开启它们那样,预测全球云基础设施开支可能非常困难。