===== NP-8132-V0B ===== } ====资源特性==== * CPU:Rockchip RK3399 6 核处理器,2*A73 ( up to 1.8GHz ) + 4*A53 ( up to 1.4GHz ) * GPU:Mail-T860 GPU MP4 四核心 GPU ,支持 OpenGL ES1.1/2.0/3.0/3.1,OpenVG1.1,OpenCL,DX11 * 内存:板载 DDR4 2GB (可选 4G) * 存储 :板载 eMMC 16G * TF :1*TF 卡接口,最大支持 32GB * 网络: 2 * 10/100/1000Mbps 速率自侦测以太网口,1 *10/100Mbps 速率自侦测以太网口 * 4G/5G:1*M.2接口 支持 * 串口: 4xCOM 其中2*RS232,2*RS485 * HDMI:1 * HDMI 接口 ,最大支持 1920x1080 输出 * USB:2*USB 接口 * KEY:1*Return,U-boot 复用 * OTG:1*OTG * Debug:1* debug 接口 * LED:3*系统指示灯可控) 1*电源指示灯 * IO:1*左右拨码开关、1* 10段位编码开关 * CANBUS: 2* spican * 扩展IO:支持 NXP PCA9555 16*GPO,16*GPI } ====接口布局和尺寸==== {{:8132_vob.png?600|}}===接口概览=== ====快速上手==== ===系统下载=== ==Linux系统== [[ftp://drv.nodka.com/arm_download/NP8132/NP-8132_Ubuntu22_lite-V5.002.02R-20230807.zip|ubuntu下载链接]] ===工具链下载=== ===OTG 驱动下载=== [[ftp://drv.nodka.com/arm_download/DriverAssitant_v5.11.zip|OTG 驱动下载]] ===烧录工具下载=== [[ftp://drv.nodka.com/arm_download/RKDevTool_Release_v2.84.zip|烧录工具下载]] 1、下载烧录工具: * 请务必先安装驱动,烧录工具链接含有驱动DriverAssitant压缩包,解压后点击DriverInstall.exe安装驱动 {{:arm:rk3399:3399-shaolu.png?600×365|}} 2、开始烧录: * 将数据线一端与主板OTG连接,另一端连接电脑。注意烧录前,需要按住boot_key按键再接通电源 {{:arm:rk3399:shaolugujian.png?600×356|}} * 打开压缩包中开发工具 >> 升级固件 >> 点击固件并选择好固件 >> 点升级开始烧录 {{:arm:rk3399:faxian.png?600×356|}} * 烧录过程中的状态,会有进度显示 {{:arm:rk3399:shaoluzhong.png?600×356|}} * 更换系统平台(例如安卓切换到Linux)时,可能出现无法烧录的情况,此时打开开发工具 >> 高级功能 >> 点击进入Maskrom切换烧录模式后烧录系统 {{:arm:rk3399:moshi.png?600×456|}} 3、完成烧录: * 烧录过程不需要任何操作,烧录成功后右框会显示设备自动重启,烧录完成。 {{:arm:rk3399:shaoluwancheng.png?600|}} ===串口调试=== * Windows 上一般用 putty 或 SecureCRT。以 putty 为例介绍如何使用串口调试功能 * putty下载链接:[[https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html|下载链接]],选择putty.exe * 串口通讯参数配置: 波特率:1500000 数据位:8 停止位:1 奇偶校验:无 流控:无 * putty设置界面如下: {{:arm:rk3399:putty-setting.png?600×492|}} 1.Connection type设置为Serial 2.Serial line设置为pc端连接的串口(此项填写pc端实际的串口号) 3.Speed设置为150000 4.点击Open按钮打开终端 * 查看PC端的串口号: {{:arm:rk3399:putty-com.png?600×492|}} *右键点击我的电脑->管理->设备管理器->端口(COM和LPT)找到本机对应的串口 *如无设备请先确定pc端是否自带串口及驱动是否安装 * 进入串口调试终端: {{:arm:rk3399:putty-com1.png?600×363|}} *如图进入交互界面,敲击回车或者输入命令会有反馈 ===ssh连接=== 网络接口IP地址默认设置如下: {{:pasted:20220608-013830.png}} 打开xshell,新建连接,输入IP地址: {{:pasted:20220608-014005.png}} 用户身份验证 用户名为:root 密码为为: 123456 {{:pasted:20220608-014120.png}} 点击连接,提示ssh密钥认证: {{:pasted:20220608-014234.png}} ====Linux系统的使用==== ===以太网使用方法=== ==查看所有网络设备== #ifconfig -a {{:pasted:20220607-190402.png?600|}} ==设置静态IP与动态IP== # vi /etc/network/interfaces {{:pasted:20220607-191133.png}} ==设置DNS== # vi /etc/resolv.conf ==Ping测试== # ping 192.168.2.238 -s 65000 //指定数据包大小 # ping 192.168.2.238 -c 10 //指定ping次数 ==Iperf Throughput 测试== 需要与server端配合使用, server端需要安装iperf测试工具 在server端开启iperf: $ iperf -s 在测试端开启iperf测试: # iperf -c 192.168.2.238 -i 1 //192.168.2.238 为server端IP地址 {{:pasted:20220607-194324.png}} ==网口指示灯状态== {{:pasted:20220607-223702.png}} ===串口使用方法=== ==串口定义== {{:pasted:20220607-205252.png}} ==RS485== 对应设备节点: 485A1/B1 -- /dev/ttyXRUSB0 485A2/B2 -- /dev/ttyXRUSB1 测试方法 硬件连接:将485A1/B1 对接 485A2/B2: 设置串口: stty -F /dev/ttyXRUSB0 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke stty -F /dev/ttyXRUSB1 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke 使用485A1/B1接收: cat /dev/ttyXRUSB0 使用485A2/B2发送 echo abcdefghijklmn >/dev/ttyXRUSB1 在接收端可以收到字符: {{:pasted:20220607-224649.png}} ==RS232== 对应设备节点: RS232RX3/TX3 -- /dev/ttyXRUSB2 RS232RX4/TX4 -- /dev/ttyXRUSB3 测试方法 硬件连接:将RS232RX3/TX3 交叉对接 RS232RX4/TX4: 设置串口: stty -F /dev/ttyXRUSB2 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke stty -F /dev/ttyXRUSB3 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke 使用RS232RX3/TX3接收: cat /dev/ttyXRUSB2 使用RS232RX4/TX4发送: echo abcdefghijklmn >/dev/ttyXRUSB3 在接收端可以收到字符: {{:pasted:20220607-225417.png}} ===CANBUS使用方法=== CAN接口定义 {{:pasted:20220607-232222.png}} CAN测试方法,连接CAN1L -- CAN2L ,CAN1H -- CAN2H 设置can: ip link set can0 down ip link set can0 type can bitrate 125000 ip link set can0 up ip link set can1 down ip link set can1 type can bitrate 125000 ip link set can1 up 使用can0 接收: candump can0 使用can1发送数据帧: cansend can1 123#1122334455667788 查看接收端: {{:pasted:20220607-233323.png}} C编程指导参考:[[np-8132-v0a#CAN应用编程|CAN应用编程]] ===左右拨码开关使用方法=== [root@rk3399:~]# evtest --------------> 输入命令evtest No device specified, trying to scan all of /dev/input/event* Available devices: /dev/input/event0: ff420030.pwm /dev/input/event1: gpio-decoder /dev/input/event2: gpio-keys /dev/input/event3: rk29-keypad Select the device event number [0-3]: 2 -------------> 选择2 gpio-keys Input driver version is 1.0.1 Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100 Input device name: "gpio-keys" Supported events: Event type 0 (EV_SYN) Event type 1 (EV_KEY) Event code 105 (KEY_LEFT) Event code 106 (KEY_RIGHT) Properties: Testing ... (interrupt to exit) Event: time 1654670127.676876, type 1 (EV_KEY), code 105 (KEY_LEFT), value 0 Event: time 1654670127.676876, -------------- SYN_REPORT ------------ Event: time 1654670127.693874, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 1 -------------> 拨到右边时打印1 Event: time 1654670127.693874, -------------- SYN_REPORT ------------ Event: time 1654670128.597949, type 1 (EV_KEY), code 106 (KEY_RIGHT), value 0 Event: time 1654670128.597949, -------------- SYN_REPORT ------------ Event: time 1654670128.610192, type 1 (EV_KEY), code 105 (KEY_LEFT), value 1 -------------> 拨到左边时打印1 Event: time 1654670128.610192, -------------- SYN_REPORT ------------ C编程指导参考:[[np-8132-v0a#Switch应用编程|Switch应用编程]] ===WATCHDOG使用方法=== 设置看门狗timeout超时时间 i2ctransfer -y -f 4 w3@0x15 0x00 0x02 0x01 (1分钟) 以此类比 0x01=1分钟 0x02=2分钟 0x03=3分钟 打开watchdog i2ctransfer -y -f 4 w3@0x15 0x00 0x03 0x01 喂狗: i2ctransfer -y -f 4 w3@0x15 0x00 0x04 0x01 ===LED使用方法=== {{:pasted:20220608-001138.png}} 系统共有8个LED,pwr_led不可以控制其中7个LED均可控,系统下对应的设备接口为: [root@rk3399:~]# cd /sys/class/leds/ [root@rk3399:/sys/class/leds]# ls mmc1:: sys_led work_led1 work_led2 work_led3 work_led4 work_led5 work_led6 控制work_led1熄灭 echo 0 >/sys/class/leds/work_led1/brightness 控制work_led1点亮 echo 1 >/sys/class/leds/work_led1/brightness 其他LED类似 ===RTC使用方法=== 查看当前系统时间: [root@rk3399:~]# date Wed Jun 8 15:54:09 CST 2022 设置同步硬件时钟: [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 关机断电5秒以上,再开机查看系统时间是否保存: [root@rk3399:/]# date Wed Jun 8 17:02:30 CST 2022 ===TFCARD使用方法=== 接入TFCARD,如果TFCARD有分区,系统会自动挂载到/mnt/sdcard [root@rk3399:/]# df Filesystem 1K-blocks Used Available Use% Mounted on /dev/root 14781436 480548 13675260 4% / devtmpfs 1962984 0 1962984 0% /dev tmpfs 1963920 28 1963892 1% /dev/shm tmpfs 1963920 176 1963744 1% /tmp tmpfs 1963920 304 1963616 1% /run /dev/mmcblk0p6 3462176 2768616 497976 85% /mnt/sdcard ===十段位编码开关使用方法=== [root@rk3399:~]# evtest --------------> 输入命令evtest No device specified, trying to scan all of /dev/input/event* Available devices: /dev/input/event0: ff420030.pwm /dev/input/event1: gpio-decoder /dev/input/event2: gpio-keys /dev/input/event3: rk29-keypad Select the device event number [0-3]: 1 -------------> 选择1 gpio-decoder Input driver version is 1.0.1 Input device ID: bus 0x19 vendor 0x0 product 0x0 version 0x0 Input device name: "gpio-decoder" Supported events: Event type 0 (EV_SYN) Event type 3 (EV_ABS) Event code 0 (ABS_X) Value 6 Min 0 Max 15 Properties: Testing ... (interrupt to exit) Event: time 1654670726.561933, type 3 (EV_ABS), code 0 (ABS_X), value 7 -------------> 旋转编码开关,打印上报对应的值。 Event: time 1654670726.561933, -------------- SYN_REPORT ------------ Event: time 1654670728.565864, type 3 (EV_ABS), code 0 (ABS_X), value 8 Event: time 1654670728.565864, -------------- SYN_REPORT ------------ Event: time 1654670729.567865, type 3 (EV_ABS), code 0 (ABS_X), value 9 Event: time 1654670729.567865, -------------- SYN_REPORT ------------ Event: time 1654670731.571873, type 3 (EV_ABS), code 0 (ABS_X), value 0 Event: time 1654670731.571873, -------------- SYN_REPORT ------------ C编程指导参考:[[np-8132-v0a#Rotary应用编程|Rotary应用编程]] ===扩展IO卡使用方法=== GPO1~GPO16 对应的GPIO编号依次为480~495 GPI1~GPI16 对应的GPIO编号依次为496~511 系统支持Linux标准的sysfs gpio操作,以GPO1(480)为例: [root@rk3399:/sys/class/gpio]# echo 480 >export -------------> 导出GPO1 [root@rk3399:/sys/class/gpio]# echo out >gpio480/direction -------------> 设置为输出 [root@rk3399:/sys/class/gpio]# echo 0 >gpio480/value -------------> 设置为低电平输出 [root@rk3399:/sys/class/gpio]# echo 1 >gpio480/value -------------> 设置为高电平输出 C编程指导参考:[[np-8132-v0a#GPIO应用编程|GPIO应用编程]] ===USB接口使用=== 系统支持U盘自动挂载:/media/usb0 [root@rk3399:/]# df Filesystem 1K-blocks Used Available Use% Mounted on /dev/root 14781436 480556 13675252 4% / devtmpfs 1962984 0 1962984 0% /dev tmpfs 1963920 28 1963892 1% /dev/shm tmpfs 1963920 184 1963736 1% /tmp tmpfs 1963920 288 1963632 1% /run /dev/sda1 1046512 2728 1043784 1% /media/usb0 ===CODESYS 实时性支持=== 系统已支持Fully Preemptible Kernel(RT),实时性内核版本为: [root@rk3399:/]# uname -r 4.4.167-rt176 如下图为实时系统连接8台伺服间隔1ms运行效果: {{:pasted:20220610-004130.png}} CPU core分布: cpu0:linux system cpu1:none cpu2:none cpu3:task cpu4: eth0 cpu5: codecsys run time task {{:pasted:20220608-191107.png}} ---- ====Linux C编程指导==== === 交叉编译环境 === 1. 建议主机环境: Ubuntu 18.04 x86_64 2. 下载安装交叉编译工具链: apt install -y crossbuild-essential-arm64 3. 查看是否安装正确: aarch64-linux-gnu-gcc -v 系统有打印Gcc 版本即为正常: {{:pasted:20220719-004327.png}} === GPIO应用编程 === 系统下操作GPIO的方式参考[[np-8132-v0a#扩展IO卡使用方法|IO使用方法]] C参考代码如下: #include #include #include #include #include #include #include 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 \n", argv[0]); fprintf(stderr, "set gpio in : %s \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%s:\n",argv[1]); if (gpio_get("direction")) exit(-1); if (gpio_get("value")) exit(-1); exit(0); } 交叉编译源码: aarch64-linux-gnu-gcc -o gpio gpio.c 将编译好的gpio程序使用scp 拷贝到8132 主板上,执行测试: 使用方法: set gpio out : ./gpio set gpio in : ./gpio {{:pasted:20220719-001444.png}} === Switch应用编程 === 参考系统下操作Switch的方法:[[np-8132-v0a#左右拨码开关使用方法|左右拨码开关使用方法]],获取到switch的设备节点为 /dev/input/event2 C参考代码如下: #include #include #include #include #include #include #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.code == KEY_RIGHT){ if(event.value == 1) printf("Switch on the right\n"); } if (event.type == EV_KEY && event.code == KEY_LEFT){ if(event.value == 1) printf("Switch on the left\n"); } } close(fd); return EXIT_SUCCESS; } 交叉编译源码: aarch64-linux-gnu-gcc -o switch switch.c 将编译好的程序使用scp 拷贝到8132 主板上,执行测试,拨动switch打印如下: {{:pasted:20220719-014056.png}} === Rotary应用编程 === 参考系统下操作Rotary的方法:[[np-8132-v0a#十段位编码开关使用方法|编码开关使用方法]],获取到Rotary的设备节点为 /dev/input/event1 C参考代码如下: #include #include #include #include #include #include #define INPUT_DEVICE "/dev/input/event1" 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_ABS && event.code == ABS_X){ printf("Rotary value is : %d \n",event.value); } } close(fd); return EXIT_SUCCESS; } 交叉编译源码: aarch64-linux-gnu-gcc -o rotary rotary.c 将编译好的程序使用scp 拷贝到8132 主板上,执行测试,拨动rotary打印如下 {{:pasted:20220719-020037.png}} === CAN应用编程 === 参考系统下操作CANBUS的方法:[[np-8132-v0a#CANBUS使用方法|CANBUS使用方法]],设置can: ip link set can0 down ip link set can0 type can bitrate 125000 ip link set can0 up ip link set can1 down ip link set can1 type can bitrate 125000 ip link set can1 up C参考代码如下: #include #include #include #include #include #include #include #include #include int main(int argc, char **argv) { struct ifreq ifr_recv = {0}; struct ifreq ifr_send = {0}; struct sockaddr_can addr_recv = {0}; struct sockaddr_can addr_send = {0}; struct can_frame frame_recv = {0}; struct can_frame frame_send = {0}; int sockfd_r = -1; int sockfd_s = -1; int ret, i; if ( 3 != argc ) { fprintf(stderr, "user : %s \n", argv[0]); exit(EXIT_FAILURE); } if ( 0 > (sockfd_r = socket(PF_CAN, SOCK_RAW, CAN_RAW))) { perror("socket error"); exit(EXIT_FAILURE); } if ( 0 > (sockfd_s = socket(PF_CAN, SOCK_RAW, CAN_RAW))) { perror("socket error"); exit(EXIT_FAILURE); } strcpy(ifr_recv.ifr_name, argv[1]); ioctl(sockfd_r, SIOCGIFINDEX, &ifr_recv); addr_recv.can_family = AF_CAN; addr_recv.can_ifindex = ifr_recv.ifr_ifindex; strcpy(ifr_send.ifr_name, argv[2]); ioctl(sockfd_s, SIOCGIFINDEX, &ifr_send); addr_send.can_family = AF_CAN; addr_send.can_ifindex = ifr_send.ifr_ifindex; ret = bind(sockfd_r, (struct sockaddr *)&addr_recv, sizeof(addr_recv)); if (0 > ret) { perror("bind error"); close(sockfd_r); exit(EXIT_FAILURE); } ret = bind(sockfd_s, (struct sockaddr *)&addr_send, sizeof(addr_send)); if (0 > ret) { perror("bind error"); close(sockfd_s); exit(EXIT_FAILURE); } setsockopt(sockfd_s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); frame_send.data[0] = 0xAA; frame_send.data[1] = 0xBB; frame_send.data[2] = 0xCC; frame_send.data[3] = 0xDD; frame_send.data[4] = 0xEE; frame_send.data[5] = 0xFF; frame_send.data[6] = 0x11; frame_send.data[7] = 0x22; frame_send.can_dlc = 8; frame_send.can_id = 0x123; while(1) { ret = write(sockfd_s, &frame_send, sizeof(frame_send)); if(sizeof(frame_send) != ret) { perror("write error"); goto out; } printf("%s send :[%d]",ifr_send.ifr_name,frame_send.can_dlc); for (i = 0; i < frame_send.can_dlc; i++) printf("%02x ", frame_send.data[i]); sleep(1); if (0 > read(sockfd_r, &frame_recv, sizeof(struct can_frame))) { perror("read error"); break; } if (frame_recv.can_id & CAN_ERR_FLAG) { printf("Error frame_recv!\n"); break; } printf("\n%s recv :[%d]", ifr_recv.ifr_name,frame_recv.can_dlc); for (i = 0; i < frame_recv.can_dlc; i++) printf("%02x ", frame_recv.data[i]); printf("\n"); } out: close(sockfd_r); close(sockfd_s); exit(EXIT_SUCCESS); } 交叉编译源码: aarch64-linux-gnu-gcc -o cantest cantest.c 将编译好的程序使用scp 拷贝到8132 主板上,对接CAN0-CAN1执行测试: {{:pasted:20220720-004229.png}}