Debug | COM1 | COM2 | USB1 | J5_LVDS-BLK | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | NC | 1 | RS485_B1 | 6 | NC | 1 | RS485_B2 | 6 | NC | 1 | USB_VCC5 | 1/2 | GND/GND | ||||
2 | TX | 2 | A_RX1_CON | 7 | UART_RTS1_232 | 2 | A_RX2_CON | 7 | UART_RTS2_232 | 2 | HUB_USB_D3N | 3 | BL_PWM_OUT | ||||
3 | RX | 3 | UART_TX1_232 | 8 | UART_CTS1_232 | 3 | UART_TX2_232 | 8 | UART_CTS2_232 | 3 | HUB_USB_D3P | 4 | BL_EN_OUT | ||||
4 | GND | 4 | NC | 9 | NC | 4 | NC | 9 | NC | 4 | GND | 5 | LVDS_BK_IN | ||||
5 | GND | 5 | GND | 6 | LVDS_BK_IN |
GPIO1 | GPIO2 | LVDS输出接口 | eDP输出接口 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | GPIO0 | 5 | GPIO2 | 1 | GPIO4 | 5 | GPIO6 | 1 | VDD | 16 | CLK_A+ | 1 | VDD | 11 | NC | |||
2 | VCC5_IO | 6 | GPIO9 | 2 | VCC5_IO | 6 | GPIO11 | 2 | VDD | 17 | Data_A3- | 2 | VDD | 12 | NC | |||
3 | GPIO1 | 7 | GPIO3 | 3 | GPIO5 | 7 | GPIO7 | 3 | VDD | 18 | Data_A3+ | 3 | GND | 13 | GND | |||
4 | GPIO8 | 8 | GND | 4 | GPIO10 | 8 | GND | 4 | GND | 19 | Data_B0- | 4 | GND | 14 | GND | |||
5 | GND | 20 | Data_B0+ | 5 | TX0N | 15 | AXUN | |||||||||||
6 | GND | 21 | Data_B1- | 6 | TX0P | 16 | AXUP | |||||||||||
7 | Data_A0- | 22 | Data_B1+ | 7 | TX1N | 17 | GND | |||||||||||
8 | Data_A0+ | 23 | Data_B2- | 8 | TX1P | 18 | GND | |||||||||||
9 | Data_A1- | 24 | Data_B2+ | 9 | NC | 19 | 3.3V | |||||||||||
10 | Data_A1+ | 25 | GND | 10 | NC | 20 | HPD | |||||||||||
11 | Data_A2- | 26 | GND | |||||||||||||||
12 | Data_A2+ | 27 | CLK_B- | |||||||||||||||
13 | GND | 28 | CLK_B+ | |||||||||||||||
14 | GND | 29 | Data_B3- | |||||||||||||||
15 | CLK_A- | 30 | Data_B3+ |
COM1_SEL | COM2_SEL | LVDS_SEL | BLK_SEL | XXXX | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 3 | RS232 | 1 | 3 | RS232 | 1 | 3 | EDP | 1 | 2 | 3.3V | ||||||||
2 | 4 | 2 | 4 | 2 | 4 | 3 | 4 | 5V | |||||||||||
3 | 5 | RS485 | 3 | 5 | RS485 | 3 | 5 | LVDS | 5 | 6 | 12V | ||||||||
4 | 6 | 4 | 6 | 4 | 6 |
硬件资源规格 | |
---|---|
SOC | Rockchip RK3399 (28纳米HKMG制程) |
CPU | ARM®六核64位处理器,主频高达1.8GHz 基于big.LITTLE大小核架构, 双核Cortex-A72(大核) + 四核Cortex-A53(小核) |
GPU | ARM® Mali-T860 MP4 四核GPU 支持OpenGL ES1.1/2.0/3.0/3.1, OpenVG1.1, OpenCL, DX11 支持AFBC(帧缓冲压缩) |
NPU | |
ISP | |
编解码 | |
内存 | 4GB LPDDR4(2GB/4GB可选配) |
存储 | 16G/32G/64G可选 |
以太网 | 2*1000Mpbs ( 可选 ) |
WIFI | 2.4GHz 单频WiFi / 2.4G/5G 双频 |
视频输出 | 支持eDP. LVDS1080P. HDMI2.0 |
视频输入 | |
音频 | 2*SPK ( 6W 8Ω ) |
SATA | |
USB | 3*USB2.0 1*USB3.0 |
电源 | DC IN 12~24V |
其他 | |
硬件电气特性 | |
高低温环境 | -20℃~60℃ |
静电 | 满足ESD 等级3 ,接触放电6KV,空气放电8KV |
其他 | 满足EFT GB/T 17626.4-2008等级3 |
1、下载烧录工具:
2、开始烧录:
3、完成烧录:
1、首先,在您的系统上安装以下这些依赖项:
sudo apt-get install gettext autotools-dev intltool python-crypto python-paramiko python-gtk2 python-glade2 python-notify cron
2、创建文件夹Fwbackups
3、接下来进入Fwbackups,下载fwbackups并使用以下命令从源代码进行安装。
wget http://downloads.diffingo.com/fwbackups/fwbackups-1.43.7.tar.bz2
4、ls查看当前路径文件,执行以下命令:
tar xfj fwbackups-1.43.7.tar.bz2
cd fwbackups-1.43.7/
./configure --prefix=/usr
5、执行make
6、执行sudo make install
7、下载安装完成在本机运行fwbackups指令,进入备份界面
1、进入fwbackups
2、点击 New set 新添设置
3、点击Add File或Add Folder备份文件或文件夹
4、选择要备份的文件或文件夹
5、进行设置备份文件的压缩路径、压缩格式以及远程或本地压缩
6、点击Backup Set Now 进行备份压缩
7、备份成功生成压缩文件
8、输入“/”或选择文件系统将文件恢复到原始位置
9、查看调试信息
10、插入U盘或SD卡,进入linux挂载路径新建一个文件夹,把压缩包放入文件夹中,解压压缩包
sudo tar -zvxf Backup-one-2023-04-11_09-48.tar.gz
11、调用mk-rootfs脚本生成rootfs镜像(mk-rootfs提取|提取码acay)
a) 把脚本mk-rootfs.sh拷到与新建的文件同路径下
b) 执行vi mk-rootfs.sh
c) 编译
sudo ./mk-rootfs.sh
d) 生成rootfs.ext4镜像文件
12、烧入生成的rootfs.ext4镜像文件
1、通过串口进入系统后台,需要利用板子的Debug接口,接口位置和定义如图:
* 接口只需要用到3个引脚,TX、RX、GND
2、需要用到串口小板工具
3、硬件部分连接效果图
4、在电脑的设备管理器→端口 中看有没有串口信息
5、打开Xshell新建一个会话,在连接下选择协议为SERIAL,操作如图:
6、点击串口,端口号为设备管理器看到的串口号,波特率为:1500000
7、最后点击连接,串口进入后台
1. 串口定义参考:
2. 安卓系统串口设备节点对应表:
主板丝印 | 设备节点 |
---|---|
UART0_TTL | /dev/ttyS0 |
RS232_Rx5/Tx5 | /dev/ttyS1 |
RS232_Rx3/Tx3 | /dev/ttyS2 |
RS232_Rx4/Tx4 | /dev/ttyS3 |
RS485_A1/B1 | /dev/ttyS4 |
RS485_A2/B2 | /dev/ttyS5 |
3. ComAssistant 测试串口通讯,以232_Rx5\Tx5回环测试为例
波特率:9600 数据位:8bit 起始位:1bit 校验位:none
4. RS485测试通讯,不支持回环测试,测试方式:
1. 将网线连接到主板LAN1接口上
2. 查看网卡IP地址
a)点击设置 ⇒ 点击更多
b)点击Ethernet
c)查看IP地址,一般系统默认动态获取IP地址
3. 连接上网络后,打开浏览器浏览网页查看是否连接上网络
4.设置以太网静态IP地址
* 点击 Ethernet IP mode 选择 static
* 进行设置
1.导出节点(编号为56、57、58、59)
先获取权限:su 再输入导出命令:echo 56 >/sys/class/gpio/export 也可以使用for循环一次性导出所有IO节点: $:cd /sys/class/gpio $:for i in {56,57,58,59}; do echo $i >export; done
2. IO 控制节点在目录:/sys/class/gpio/
3. IO 对应表如下:
功能 | 主板丝印 | 节点编号 |
---|---|---|
输入\输出 | J_GPIO1 | gpio56 |
J_GPIO2 | gpio57 | |
J_GPIO3 | gpio58 | |
J_GPIO4 | gpio59 |
echo out >/sys/class/gpio/gpio56/direction
echo 0 >/sys/class/gpio/gpio56/value
echo 1 >/sys/class/gpio/gpio56/value
cat /sys/class/gpio/gpio56/value
0 对应高电平 1.8V 1 对应低电平 0V
连接扬声器后,可播放音视频,测试左右声道
接好麦克风和一对喇叭后,使用系统内置的录音机APP,录音和播放测试
5.1 插入TF卡至设备TF卡卡槽
5.2 上滑至应用页面 » 文件 » 查看外接TF卡信息
5.3 在系统下拷贝文件至TF卡,进行读写测试
5.4 上滑至应用页面 » 文件 » TF卡挂载名称 » 点击旁边的弹出图标,弹出TF卡
支持在线升级,系统内置升级APP,打开可查看是否有最新系统版本
date MMddHHmmyyyy.ss set(月日时分年.秒) 例如:date 052514192023.00 set
hwclock -w --从系统时间同步到硬件时钟 hwclock -s --从硬件时钟同步到系统时间
cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cur_freq //查看cpu频率 cat /sys/class/thermal/thermal_zone0/temp //查看CPU当前温度
free -h
df -h
lsusb
NodkaAPI入口类
NodkaAPI使用方法:
1、在Application的onCreate中创建NodkaAPI实例
mNodkaAPI = NodkaAPI.nodkaAPICreate(this);
2、在Activity或Fragment中使用API步驟:
private NodkaAPI mNodkaAPI = APIApplication.getApplication().getNodkaAPI();
NodkaAPI接口说明:
1、以devinfo开头的是硬件及系统信息查询类api
2、以display开头的是显示控制类api
3、以gpio开头的是GPIO控制类api
4、以uart开头的是串口控制类api
5、以sysctrl开头的是系统控制类api,包括定时开关机
接口类别 | 方法名 | 方法说明 |
---|---|---|
硬件及系统信息查询类 | devinfo_getAndroidVersion() | 获取Android系统版本信息 |
devinfo_getAvailMem() | 获取可用内存容量 | |
devinfo_getBuildNumber() | 获取系统版本号信息 | |
devinfo_getCpuCores() | 获取cpu核心数 | |
devinfo_getCPUCurFreqKHz() | 获取cpu当前运行主频 | |
devinfo_getCPUMaxFreqKHz() | 获取cpu最大主频 | |
devinfo_getCPUMinFreqKHz() | 获取cpu最小主频 | |
devinfo_getCPUTemp() | 获取cpu温度 | |
devinfo_getDeviceModel() | 获取设备型号信息 | |
devinfo_getKernelVersion() | 获取内核版本信息 | |
devinfo_getSerialNum() | 获取设备SN号 | |
devinfo_getStorageAvailableSize() | 获取本机可用存储容量 | |
devinfo_getStorageTotalSize() | 获取本机存储容量(不包括系统分区) | |
devinfo_getTotalMem() | 获取内存总容量 | |
显示控制类 | display_getNavBar() | 获取是否显示导航栏跟状态栏 |
display_getScreenBrightness() | 获取屏幕亮度 | |
display_getScreenRotation() | 获取屏幕旋转方向 | |
display_getWindowHeight() | 获取屏幕分辨率高度 | |
display_getWindowWidth() | 获取屏幕分辨率宽度 | |
display_setNavBar(Boolean enable) | 设置是否显示导航栏跟状态栏 | |
display_setNavBarSlideShow(Boolean enable) | 设置滑动是否会显示导航栏跟状态栏 | |
display_setScreenBrightness(int screenBrightness) | 设置屏幕亮度 | |
display_setScreenRotation(int rotation) | 设置屏幕旋转方向 | |
GPIO控制类 | gpio_direction(int gpioNumber, String direction) | 设置GPIO的方向(输入输出),对指定的gpio号进行设置 |
gpio_export(int gpioNumber) | 导出控制的GPIO引脚,对指定的gpio号进行导出 | |
gpio_read(int gpioNumber) | 读取GPIO的输出电平值,对指定的gpio号进行读取 | |
gpio_unExport(int gpioNumber) | 取消导出控制的GPIO引脚,对指定的gpio号进行取消导出 | |
gpio_write(int gpioNumber, int value) | 设置GPIO的输出电平,对指定的gpio号进行设置 | |
串口控制类 | uart_close(String uartNode) | 关闭uart设备,如/dev/ttyXRUSB2 |
List<String> uart_getAvailableDevices() | 获取uart可用的设备节点 | |
uart_IsOpen(String uartNode) | uart设备是否已经打开,如/dev/ttyXRUSB2 | |
uart_open(String uartNode, int baudrate) | 打开uart设备,如/dev/ttyXRUSB2 | |
uart_receive(String uartNode, UartReceiveDataCallback callback) | 接收串口数据,如从/dev/ttyXRUSB2接收数据 | |
uart_send(String uartNode, byte[] buffer) | 发送串口数据,如向/dev/ttyXRUSB2发送数据 | |
uart_stopReceive(String uartNode) | 停止接收数据,调用后,不再有数据回调 | |
系统控制类 | sysctrl_cancelReboot() | 取消重启设备 |
sysctrl_cancelShutdown() | 取消自动关机 | |
sysctrl_powerOn(String time, boolean repeat) | 设置设备开机时间 | |
sysctrl_reboot(String time, boolean repeat) | 设置重启设备时间 | |
sysctrl_rebootNow() | 立即重启设备 | |
sysctrl_shutdown(String time, boolean repeat) | 设置设备关机时间 | |
sysctrl_shutdownNow() | 立即关机 | |
sysctrl_installApk(String apkPath) | 静默安装应用 |
1.IO控制节点都在/sys/class/io_control
2. IO 对应表如下:
功能 | 主板丝印 | 节点名 |
---|---|---|
输入 | IO1 | gpio_ip0 |
IO2 | gpio_ip1 | |
IO3 | gpio_ip2 | |
IO4 | gpio_ip3 | |
IO5 | gpio_ip4 | |
IO6 | gpio_ip5 | |
输出 | IO7 | gpio_op0 |
IO8 | gpio_op1 | |
IO9 | gpio_op2 | |
IO10 | gpio_op3 | |
IO11 | gpio_op4 | |
IO12 | gpio_op5 |
3. IO控制方法:
echo 0 >/sys/class/io_control/gpio_op0
*输出高电平:
echo 1 >/sys/class/io_control/gpio_op0
*查看输入电平:
cat /sys/class/io_control/gpio_ip0
1. 串口定义参考:
2. 串口设备节点系统对应表:
主板丝印 | 设备节点 |
---|---|
COM1 | /dev/ttyXRUSB0 |
COM2 | /dev/ttyXRUSB1 |
COM3 | /dev/ttyXRUSB2 |
COM4 | /dev/ttyXRUSB3 |
3. CuTecom 测试串口,以COM2回环测试为例
4. 命令行方式测试串口,同样以COM2回环测试为例
打开终端输入如下指令接收数据:
com_recv /dev/ttyXRUSB1 115200
打开另一个终端发送数据:
com_send /dev/ttyXRUSB1 115200
测试结果如下:
1. 查看网卡IP地址,系统默认都为动态获取IP地址
#ifconfig -a
2. 设置网卡静态IP地址
双击桌面图标Advanced Network Configuration
vim /etc/network/interfaces
1. 点击右下角网络图标,浏览可用WIFI路由:
2. 方法2 – 命令行连接wifi
nmcli d wifi connect "SSID" password "PASSWROD"
1. 系统已带自动拨号,打开终端,输入命令4g 即可自动拨号:
root@rk3399:~# 4g
2. 拨号完成后,查看IP地址:
3. 打开浏览器,浏览任意网站。
4. 5G测试方法与4G类似,输入命令5g即可自动拨号:
root@rk3399:~# 5g
1.IO控制节点都在/sys/class/io_control
2. IO 对应表如下:
功能 | 主板丝印 | 节点名 |
---|---|---|
输入 | IO1 | gpio_ip0 |
IO2 | gpio_ip1 | |
IO3 | gpio_ip2 | |
IO4 | gpio_ip3 | |
IO5 | gpio_ip4 | |
IO6 | gpio_ip5 | |
输出 | IO7 | gpio_op0 |
IO8 | gpio_op1 | |
IO9 | gpio_op2 | |
IO10 | gpio_op3 | |
IO11 | gpio_op4 | |
IO12 | gpio_op5 |
3. IO控制方法:
echo 0 >/sys/class/io_control/gpio_op0
*输出高电平:
echo 1 >/sys/class/io_control/gpio_op0
*查看输入电平:
cat /sys/class/io_control/gpio_ip0
1. 方法① – 使用系统自带SMPayer播放器,以及音频测试文件,可以做简单音频功能测试
2. 方法② – 使用命令方式播放:
aplay /nodka_test/LR_audio.wav -D hw:0,0
arecord -d 5 -f cd -r 44100 -c 2 -t wav test.wav aplay test.wav
1. U盘自动挂载/media/disk
root@rk3399:~# df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/root 15G 3.6G 10G 27% / devtmpfs 980M 0 980M 0% /dev tmpfs 981M 0 981M 0% /dev/shm tmpfs 981M 8.8M 972M 1% /run tmpfs 5.0M 4.0K 5.0M 1% /run/lock tmpfs 981M 0 981M 0% /sys/fs/cgroup tmpfs 197M 16K 197M 1% /run/user/0 /dev/sda1 57G 2.7G 54G 5% /media/disk
* SDcard 自动挂载:
root@rk3399:~# df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/root 15G 3.6G 10G 27% / devtmpfs 980M 0 980M 0% /dev tmpfs 981M 0 981M 0% /dev/shm tmpfs 981M 8.8M 972M 1% /run tmpfs 5.0M 4.0K 5.0M 1% /run/lock tmpfs 981M 0 981M 0% /sys/fs/cgroup tmpfs 197M 16K 197M 1% /run/user/0 /dev/mmcblk0p8 30G 3.8G 25G 14% /media/3699f79c-f05d-4948-89c9-04dc4b132a1f
解除挂载:
umount /dev/mmcblk0p8
挂载:
mount /dev/mmcblk0p8 /sdcard
1. 输入命令evtest 查看系统下所有按键、输入设备:
root@rk3399:~# evtest No device specified, trying to scan all of /dev/input/event* Available devices: /dev/input/event0: ff420030.pwm /dev/input/event1: USB Optical Wheel Mouse /dev/input/event2: SIGMACH1P USB Keyboard /dev/input/event3: rk29-keypad /dev/input/event4: SIGMACH1P USB Keyboard Select the device event number [0-4]:
2. 按照上面提示选择测试按键,如RK3399 boot按键为 /dev/input/event3: rk29-keypad
则event number 为3:按下按键会打印value 1,松开按键则会打印value 0,如下图:
3. 自定义按键功能,配置文件为
/etc/triggerhappy/triggers.d/example.conf
如下为定义按键为reboot功能,亦为系统默认配置,用户可以根据需要自定义。
KEY_VOLUMEUP 1 reboot
1. 系统支持使用APP切换不同的LCD屏,输入dis命令打开APP如下图:
2. 背光亮度调节:
echo 100 > /sys/class/backlight/backlight1/brightness
(注:写入数值越大亮度越大,max_brightness 为250)
1.查看当前系统时间:
[root@rk3399:~]# date Wed Jun 8 15:54:09 CST 2022
2. 设置同步硬件时钟:
[root@rk3399:/]# date -s "2022-06-08 17:01:01" Wed Jun 8 17:01:01 CST 2022 [root@rk3399:/]# hwclock -w [root@rk3399:/]# hwclock -r Wed Jun 8 17:01:09 2022 0.000000 seconds
3. 关机断电5秒以上,再开机查看系统时间是否保存:
[root@rk3399:/]# date Wed Jun 8 17:02:30 CST 2022
注:系统默认为网络时间同步,以上RTC测试需要在断外网情况下测试。
4. 时区设置
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime reboot
设置其他时区只需将上面命令中的Asia/Shanghai改为对应的时区城市即可。
选择完成后关闭窗口,使用date命令查看时区变化:
查看CPU信息:
cat /proc/cpuinfo
查看内存容量大小:
free -h
查看EMMC可用容量大小
df -h
C参考代码如下:
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> static char gpio_path[100]; //设置GPIO方向、高低电平 static int gpio_config(const char *file, const char *value) { char config_path[100]; int len; int fd; sprintf(config_path, "%s/%s", gpio_path, file); if (0 > (fd = open(config_path, O_WRONLY))) { perror("open error"); return fd; } len = strlen(value); if (len != write(fd, value, len)) { perror("write error"); close(fd); return -1; } close(fd); return 0; } //获取GPIO的方向、电平 static int gpio_get(const char *file) { char get_path[100]; char buf[10]={"\0"}; int len; int fd; sprintf(get_path, "%s/%s", gpio_path, file); if (0 > (fd = open(get_path, O_RDWR))) { perror("open error"); return fd; } if ( 0 > read(fd,buf,10)) { perror("read error"); return fd; } printf(" %s : %s",file,buf); close(fd); return 0; } int main(int argc, char *argv[]) { if (4 != argc) { if (3 != argc) { fprintf(stderr, "set gpio out : %s <gpio> <out> <value>\n", argv[0]); fprintf(stderr, "set gpio in : %s <gpio> <in>\n", argv[0]); exit(-1); } } sprintf(gpio_path, "/sys/class/gpio/gpio%s", argv[1]); if (access(gpio_path, F_OK)) { printf("%s inexistence,export %s... \n",gpio_path,argv[1]); int fd; int len; if (0 > (fd = open("/sys/class/gpio/export", O_WRONLY))) { perror("open error"); exit(-1); } len = strlen(argv[1]); if (len != write(fd, argv[1], len)) { perror("write error"); close(fd); exit(-1); } close(fd); } if (gpio_config("direction", argv[2])) exit(-1); if ( 0 == strcmp("out",argv[2] ) && argc == 4 ) { if(gpio_config("value", argv[3])) exit(-1); } printf("gpio_op%s:\n",argv[1]); if (gpio_get("direction")) exit(-1); if (gpio_get("value")) exit(-1); exit(0); }
交叉编译源码:
aarch64-linux-gnu-gcc -o a.out gpio.c
将编译好的gpio程序使用scp拷贝到 rk3399 主板上,执行测试:
使用方法:
0:./gpio 0 out 0
1:./gpio 0 out 1
系统下操作 UART 的测试串口,以 COM2 测试为例:
COM2 设备节点为:
/dev/ttyXRUSB1
C参考UART高低电平输入代码如下:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <termios.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #define UART_DEVICE "/dev/ttyXRUSB1" //uart设备文件名称 int main(int argc, char *argv[]) { int fd, res; struct termios oldtio, newtio; char ch; char buf[256] = {0}; //-----------打开uart设备文件------------------ fd = open(UART_DEVICE, O_RDWR|O_NOCTTY);//没有设置O_NONBLOCK。所以这里read和write是堵塞操作 if (fd < 0) { perror(UART_DEVICE); exit(1); } else printf("Open %s successfully\n", UART_DEVICE); //-----------设置操作參数----------------------- tcgetattr(fd, &oldtio);//获取当前操作模式參数 memset(&newtio, 0, sizeof(newtio)); //波特率=115200 数据位=8 使能数据接收 newtio.c_cflag = B115200|CS8|CLOCAL|CREAD; newtio.c_iflag = IGNPAR; tcflush(fd, TCIFLUSH);//清空输入缓冲区和输出缓冲区 tcsetattr(fd, TCSANOW, &newtio);//设置新的操作參数 //------------向urat发送数据------------------- res=write(fd, "Begin Uart tx", 16); while(1) { //从控制台终端获取数据,然后通过uart发送出去,直到接收到!字符 while((ch=getchar()) != '!') { buf[0]=ch; res=write(fd, buf, 1); } buf[0]=ch; buf[1]=' '; res = write(fd, buf, 2); break; } //-------------从uart接收数据------------------- while(1) { res = read(fd, buf, 255);//程序将在这里挂起,直到从uart接收到数据(堵塞操作) if (res == 0) continue; buf[res] = ' '; printf("res = %d, buf = %s\n", res, buf);//将uart接收到的字符打印出来 if (buf[0] == '!')//uart接收到!字符后退出while break; } //------------关闭uart设备文件,恢复原先參数-------- close(fd); printf("Close %s\n", UART_DEVICE); tcsetattr(fd, TCSANOW, &oldtio); //恢复原先的设置 return 0; } }
交叉编译源码:
aarch64-linux-gnu-gcc -o uart uart.c
将编译好的程序使用 scp 拷贝到 3399 主板上,执行测试:
参考系统下操作Key的方法,获取到key的设备节点为
/dev/input/event2
C参考代码如下:
#include <unistd.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <linux/input.h> #include <sys/select.h> #define INPUT_DEVICE "/dev/input/event2" int main(int argc, char **argv){ int fd; struct input_event event; ssize_t bytesRead; int ret; fd_set readfds; if ( 0 > (fd = open(INPUT_DEVICE,O_RDONLY))) { perror("open error"); return fd; } while(1){ FD_ZERO(&readfds); FD_SET(fd,&readfds); ret = select(fd + 1, &readfds, NULL, NULL, NULL); if (ret == -1){ fprintf(stderr,"select call on%s : an error ocurred",argv[1]); break; } if(FD_ISSET(fd,&readfds)){ bytesRead = read(fd, &event,sizeof(struct input_event)); if(bytesRead == -1 ) fprintf(stderr,"bytesRead :%ld : an error ocurred",bytesRead); } if(event.type == EV_KEY && (event.value == 0 || event.value == 1)) { printf("key %s\n",(event.value) ? "pressed" : "released"); } } close(fd); return EXIT_SUCCESS; }
交叉编译源码:
aarch64-linux-gnu-gcc -o key key.c
将编译好的程序使用 scp 拷贝到 r39s2 主板上,执行测试,按动 key 打印如下:
* 主机环境推荐:Debian 10 x64 bit, 可以直接导入配置好的虚拟机镜像: QT编译环境virtualbox
或者使用QT编译环境 Docker image: QT编译环境Docker
### load docker image sudo docker load <nodka_docker_qt_build_20230223.tar ### 运行docker image,注意 : /home/APP_PATH为QT应用程序所在目录 sudo docker run --rm --mount type=bind,source=/home/APP_PATH,target=/mnt/ -i -t 09a37c1b2fc3 /bin/bash ### 编译QT 应用程序 cd /mnt qmake make
* 主机交叉编译环境配置参考步骤:
1. 安装交叉编译工具链:
apt install -y crossbuild-essential-arm64
2. 拷贝平板系统内的/usr & /lib 到主机 /home/nodka/qt5/qt_sysroot 目录下
3. 配置以下环境变量
QTSYSROOT="/home/nodka/qt5/qt_sysroot" QTPATH=$QTSYSROOT/usr/local/qt5.12-arm LD_LIBRARY_PATH=$QTPATH/lib:$LIBRARY_PATH LIBRARY_PATH=$QTPATH/lib:$LIBRARY_PATH C_INCLUDE_PATH=$QTPATH/include:$C_INCLUDE_PATH PATH=$QTPATH/bin:$PATH PKG_CONFIG_PATH=$QTPATH/lib/pkgconfig:$PKG_CONFIG_PATH export LD_LIBRARY_PATH export LIBRARY_PATH export C_INCLUDE_PATH export CPLUS_INCLUDE_PATH export PKG_CONFIG_PATH export PATH
4. 编译APP
qmake make
1. 安装
进入Qt官方下载页面,选择一个版本下载 qt-creator-opensource-linux-x86_64-x.x.x.run,下载完成之后,在终端执行 ./xxxx.run 运行安装,注意文件需要有执行权限。
2.配置
安装完成后,启动 Qt Creator,打开菜单 Tools → Option ,找到Kits。
点击右侧 add 按钮添加,选择 Qt 环境安装位置中的 qmake 即可
qmake:
/usr/local/qt5.12-arm/bin/qmake
点击右侧 add 按钮添加 gcc 和 g++ 交叉编译器的位置
如果主机安装了 crossbuild-essential-arm64,则编译器就在 /usr/bin/ 下
如果使用了第三方的交叉编译器,找到安装位置并添加即可
如果目标平台是 Buildroot ,则需要使用 Buildroot Qt 环境包中的编译器
g++:/usr/bin/aarch64-linux-gnu-g++
gcc:/usr/bin/aarch64-linux-gnu-gcc
为方便调试,配置 Debeggers 和 Devices 用于在线调试:
点击右侧 add 按钮添加 gbd-multiarch: apt install -y gdb-multiarch
检查目标机上是否存在 /usr/bin/gdbserver, 没有的话需要安装:apt install -y gdbserver,没有的话需要安装:apt install -y gdbserver (Buildroot 自带,无需安装)
回到主机的 Qt Creator,点击右侧 add 按钮添加 gdb
选择主机中的 gdb-multiarch : /usr/bin/gdb-multierch
设置好设备的 IP 、用户名(root)。为了方便调试,可以在设备上设置静态 IP。
将前面设置的配置项添加到 Kits。
如果目标平台是 Ubuntu 系统,这一步也需要添加 sysroot 的路径
Docker English-Community 支持以下的 Ubuntu 版本:
安装命令如下:
curl -fsSL https://get.docker.com | bash -s docker --miror Aliyun
也可以使用国内 daocloud 一键安装命令:
curl -sSL https://get.daocloud.io/docker | sh
测试 Docker 是否安装成功,输入以下指令,打印出以下信息则安装成功:
sudo docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 1b930d010525: Pull complete Digest: sha256:c3b4ada4687bbaa170745b3e4dd8ac3f194ca95b2d0518b417fb47e5879d9b5f Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/