英伟达TX2的刷机和I2C传感器(无寄存器)通信
TX2刷机
最近入坑英伟达TX2进行实验,先是对TX2进行了刷机。网上有关刷机的教程很多,但是我还是踩了许多坑,这里和大家总结一下。
首先是ubuntu是采用虚拟机还是双系统的问题。这里我建议大家用虚拟机。
1.双系统的问题
我之前在双系统上安装过ubuntu16和18版本的,他们有个大问题就是无法驱动我的无线网卡,我的无线网卡是AX200的,后来我去找如何解决驱动问题,发现要升级linux内核,然后去下载linux内核,发现速度不超过20k/s且试了几种方法都没有加快下载速度,遂放弃。然后我又装了个ubuntu20版本的,结果wifi是能驱动了,但是安装完SDKMANAGER又出现不支持该版本Ubuntu的提示了,于是我转而用虚拟机的18.04版本来下载。
2.虚拟机
其实我一开始就是用虚拟机下载的,但是虚拟机的vm-tools工具我每次安装了都仍然无法其作用改变页面大小,所以我才转向双系统的刷机方法。这里给个代码建议。
打开终端,输入以下命令。
即通过安装VMtools实现了Windows与Ubuntu跨系统复制粘贴,也实现了Ubuntu窗口自适应
sudo apt-get autoremove open-vm-tools
sudo apt-get install open-vm-tools
sudo apt-get install open-vm-tools-desktop
窗口自适应是一定有效的,跨系统复制粘贴我就不太清楚了。
接下来如何刷机参考这篇文章:
NVIDIA Jetson TX2 上手指南。
其中host machine一定不要勾选,不然后面可能会出现错误。反正我勾选以后后面刷机总是出现了一个问题。至于要不要换源,我反正没换源也可以完成刷机,建议不要换源。
I2C传感器(有寄存器)通信
首先我可以肯定的是绝大多数传感器都是有寄存器的传感器,什么意思呢,就是说在数据手册里会给出类似这样子的说明。以下为mpm259传感器。
如果你的传感器是这样子(有寄存器)的,有大量的代码可以供你参考。
如果你想直接利用i2c-tools测试传感器,你可以参考这篇
Beaglebone Black–I2C 接 BMP280 获取当前温度
如果你想要参考代码,你可以参考
NVIDIA TX2开发板的I2C(IIC)通信
I2C传感器(无寄存器)通信
如果该传感器的数据手册上没有寄存器的任何说明,说明该传感器只能被读数而不能被写数。以下是我本次使用的传感器MPM3801 型 I2 C 数字压力传感器。
可以看到,它不存在去哪取数的说法。而是先由主设备广播地址与读写位给传感器,在直接从SDA线上读取数据。
一开始,我所借鉴的代码都是有寄存器的,也就是到指定寄存器位置读取数据的。所以他们的读过程大致分为两步。第一步写寄存器的位置,第二步才是到指定位置的寄存器里读数。而这款MPM3801传感器没有寄存器。所以对于读数部分其实只有一步。以下是参考代码。其中,传感器的默认地址是0x28H。
#include <stdio.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>
#define I2C_FILE_NAME "/dev/i2c-1" //I2C-1
#define I2C_ADDR 0x28
int fd;
int i2c_read(int fd, unsigned char addr, unsigned char *val)
{
int ret;
struct i2c_rdwr_ioctl_data data;
struct i2c_msg messages[1];
messages[0].addr = addr; //device address
messages[0].flags = I2C_M_RD; //read
messages[0].len = sizeof(val);
messages[0].buf = val;
data.msgs = messages;
data.nmsgs = 1;
if(ioctl(fd, I2C_RDWR, &data) < 0){
printf("read ioctl err\n");
return 1;
}
return 0;
}
int main()
{
int i;
unsigned char buf[4];
unsigned char a[4] ;
fd = open(I2C_FILE_NAME, O_RDWR);
if(fd < 0)
{
perror("Unable to open i2c controlfile");
return 1;
}
memset(buf, 0x00, sizeof(buf));//清0;
memset(a, 0x00, sizeof(a));
if(i2c_read(fd, I2C_ADDR,&buf))
{
printf("%d,Unable to get register!\n",i);
}
if(i2c_read(fd, I2C_ADDR,&a))
{
printf("%d,Unable to get register!\n",i);
}
for(i=0; i< 4;i++)
{
printf("buf[%d]=%d\n",i,buf[i]);
}
printf("a[0]=%d\n",a[0]);
}
最终得到
buf[0]=7;
a[0]=135;
为什么会不一样呢,后来查得知,压力的数据要略去前两位,135=128+7。刚刚好相等。
最后给想我一样的刚入门ubuntu的小伙伴提个醒,上面的代码先保存为xx.c文件,再到对应的目录下用终端运行gcc xx.c。然后这个目录会生成a.out文件,再运行a.out文件就可以看到结果啦。
gcc xx.c
./a.out