学习内容

通过一周学习到了一些新的知识并对嵌入式的应用层开发进行了技术栈的补充,新知识例如自动驾驶的cv2x,以及正在做的V2V部分。
主要是编译了固件来支持应用层的开发,学习了使用工具adb来进行调试内核,烧录文件,并且通过设备对于V2V来进行相互通信。

1.固件编译

固件编译部分跟之前没有太大的不同,差异点主要在需要在Linux搭载代理服务来进行编译,因为芯片是高通的,可能由于一些带宽和信号延时问题,导致会有编译报错,之后可以在自己电脑虚拟机上进行代理设置玩玩,但是clash现在删库了,可能需要寻找新的方法来代替。

烧录固件使用的软件为QFil,它烧录需要点运气的成分,会出现找不到指定文件的问题还有process fail的问题,解决方法就是下载最新的QPST,并且使用Tools选项来进行烧录固件,可以在烧录固件之前使用QPST Configuration来查询串口的状态是否enable。经过查询发现,这个软件经常使用在给手机进行刷机(刷系统)。

2023-12-21-091223.png

2.硬件验证

将固件烧录成功后,使用adb进入调试,并输入命令开启进行验证服务。

adb 是 Android 调试桥(Android Debug Bridge)的缩写,它是一个用于与连接到计算机的 Android 设备进行通信的命令行工具。adb 提供了一组用于设备管理、应用安装、调试和其他开发任务的命令。

adb工具的安装以及配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sudo apt-get install anroid-tools-adb
mkdir ~/.android
echo 0x2c7c > ~/.android/adb_usb.ini
cd /etc/udev/rules.d
sudo vim 51-android.rules
##内容
SUBSYSTEM=="usb", SYSFS{idVendor}=="2c7c", MODE="0666",GROUP="plugdev"
##其中的2c7c使用lsusb命令通过热插拔来确定
sudo usermod -a -G plugdev $(id -u -n)
sudo udevadm control --reload-rules
sudo service udev restart
sudo udevadm trigger

sudo -s#进入调试模式
adb kill-server#取消服务
adb start-server#开启adb服务
exit 0 #回到正常模式

至此adb已经安装配置完成了。

adb工具的使用

这个工具安装完毕就可以在终端使用(无论linux和windows)

以下是一些常用的 adb 命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#设备连接与断开:
#连接设备:
adb devices
#断开设备连接:
adb disconnect [device]
#应用管理:

#安装应用:
adb install path/to/app.apk
#卸载应用:
adb uninstall package_name
#启动应用:
adb shell am start -n package_name/activity_name
#文件传输:

#将文件复制到设备:
adb push local_file_path /device/path
#从设备中复制文件:
adb pull /device/path local_file_path
#调试和日志:

#查看设备日志:
adb logcat
#清除设备日志:
adb logcat -c
#Shell 命令:

#进入设备 shell:
adb shell
#执行设备上的命令:
adb shell [command]
#端口转发:

#将设备端口转发到主机:
adb forward tcp:8080 tcp:8080
#系统操作指令
#获取设备型号
adb shell getprop ro.product.model
#获取andorid系统版本
adb shell getprop ro.build.version.release
#获取设备的序列号
adb get-serialno
#获取设备屏幕分辨率
adb shell wm size

在验证过程中发现问题可以多做正常设备之间的比较,来查找是否有问题,排除法最为好用。

在使用adb的过程中发现一个问题,adb在虚拟机的重启后,调试设备会显示没有权限,目前的解决方案为将adb的服务重新开启。

1
2
3
4
sudo -s#进入调试模式
adb kill-server#取消服务
adb start-server#开启adb服务
exit 0 #回到正常模式
将命令发送给特定的设备

如果有多个设备在运行,您在发出 adb 命令时必须指定目标设备。如需指定目标设备,请按以下步骤操作:

  1. 使用 devices 命令获取目标设备的序列号。
  2. 获得序列号后,结合使用-s选项与adb命令,可以将 $ANDROID_SERIAL 环境变量设为包含序列号。
    • 如果您要发出很多 adb 命令,可以将 $ANDROID_SERIAL 环境变量设为包含序列号。
    • 如果您同时使用 -s$ANDROID_SERIAL-s 会替换 $ANDROID_SERIAL

以下示例中,先获得了已连接设备的列表,然后使用其中一个设备的序列号在该设备上安装了 helloWorld.apk

1
2
3
4
5
adb devices
List of devices attached
emulator-5554 device
emulator-5555 device
adb -s emulator-5555 install helloWorld.apk

注意:如果您在多个设备可用时发出命令但未指定目标设备,adb 会显示错误。

3.嵌入式应用层的编写

应用层的编写主要是使用C和C++的语言,主要发送和接收都是基于SDK开发,

因为收发程序为发送字符缓冲区的字符串,为保证数据发送的稳定,时间戳放入前要注意将数据类型设置为无符号整型变量,而且要注意变量的实际大小,不要溢出。

1
2
3
4
static array<char, G_BUF_LEN> gBuf;       //用于存储发送的数据
uint64_t time1 = getCurrentTimestamp(); //获取时间戳
std::string stringValue = std::to_string(time1); //整型转成字符串
std::strncpy(gBuf.data(), stringValue.c_str(), G_BUF_LEN);//将整型变量放入字符缓冲区

要注意环境,可能C++程序编译没bug,但是实际硬件运行的环境不能完全支持。还是C更好一点。

应用层编写出现的问题:

  1. 在全双工通信时候做收发线程时候发现堵塞,暂时没发现解决方案,换做半双工通信,两个线程作为互斥并加入应答机制,但是在其中发现主机容易堵塞,从机没事,找到其中的区别,是收发线程开启的顺序问题,所以将全双工通信的双线程分时打开,发现问题得到了解决。
  2. 因为必须在程序执行结束后进行退出服务,如果不进行注销退出服务的话不能再次开启程序只能重新启动,为方便调试加入了信号处理机制便于退出,但是因为接收线程使用的接收机制是阻塞接收,在信号处理机制后会阻塞在接收函数中,放入了跳转机制想跳出这个阻塞,会出现线程没有结束的报错总线错误。最后是去掉了跳转,对阻塞接收函数进行超时处理,这样退出时就不会因为没有信号发生进程阻塞。
  3. 发送消息为判断是否丢包,加入发送时候所在的发送次数。在接收时候进行打印,并比较总接收次数完成丢包率的查找。
  4. V2V使用的是卫星同步源,两端的设备使用的是网络时间同步,会有不同的延迟误差。

4.时间戳的同步

时间戳是指使用数字签名技术对包含原始文件信息、签名参数、签名时间等信息构成的对象进行数字签名而产生的数据,用以证明原始文件在签名时间之前已经存在

多个传感器可能同时工作,或者在同一系统中的多个组件需要协同工作。通过在传感器数据中包含时间戳,可以实现时间同步,确保数据采集的时序是一致的。这对于在后续数据处理或分析中确保时间一致性是很重要的。
在v2v中使用接收时间戳减去发送时间戳来得到传输设备之间的传输延迟,所使用的精度越高那么得到的时间戳的精度越高。

目前了解可使用的时间戳同步为ntp时间同步以及订阅时间同步,可使用命令进行查询时间同步后的系统偏差。

1
2
chronyc tracking
chronyc sources -v

chrony的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 打开终端。
# 安装chrony
sudo apt-get install chrony
# 启动chrony服务
sudo systemctl start chronyd
# 确保chrony在系统启动时自动运行
sudo systemctl enable chronyd
# 检查chrony的状态,如果显示为“active(running)”,则表示已成功启动
sudo systemctl status chronyd
# 编辑chrony配置文件
sudo nano /etc/chrony/chrony.conf
# 找到服务器行注释以下信息
# pool ntp.ubuntu.com iburst maxsources 4
# pool 0.ubuntu.pool.ntp.org iburst maxsources 1
# pool 1.ubuntu.pool.ntp.org iburst maxsources 1
# pool 2.ubuntu.pool.ntp.org iburst maxsources 2
# 常用ntp时间服务器:国家授时中心ntp服务器、阿里云ntp服务器
# 找到服务器行并添加您想要同步的NTP服务器地址(可以根据需要添加多个服务器),例如:
server ntp1.aliyun.com iburst
server ntp1.aliyun.com minpoll 4 maxpoll 10 iburst
# 同步更新时间间隔在2的4次幂到2的10次幂秒之间
# 保存并关闭文件。
# 重启chrony服务以应用更改
sudo systemctl restart chronyd。
# 最后,检查时间同步状态。如果显示为“*”或“+”,则表示时间同步正在进行中
chronyc tracking