===== NK-R39S2A1 ===== ==== 主板框架图 ==== {{:pasted:20221214-220552.png}} ==== 接口定义 ==== {{page>:template:R39S2_hw}} === 插针pin定义 === {{page>:template:R39S2p_hw_pin}} === Jump_sel === {{page>:template:R39S2_hw_jump}} ==== 硬件特性 ==== {{page>:template:temp_hwspec}} ==== 快速上手 ==== === 系统烧录 === {{page>:template:temp_burn}} === Debug串口调试 === {{page>:template:temp_debug}} === Android ADB === {{page>:template:temp_adb}} === Linux SSH === {{page>:template:temp_ssh}} ==== Android 使用指南 ==== === 接口功能测试 === == UART == {{page>:template:temp_android_uart}} == LAN == {{page>:template:temp_android_lan}} == WIFI == {{page>:template:temp_android_wifi}} == 4G/5G == {{page>:template:temp_android_4g5g}} == Can == {{page>:template:temp_android_can}} == GPIO/DIO == {{page>:template:temp_android_gpio}} == Audio == {{page>:template:temp_android_audio}} == Mic == {{page>:template:temp_android_mic}} == USB == {{page>:template:temp_android_usb}} == SDCARD == {{page>:template:temp_android_sdcard}} == Bluetooth == {{page>:template:temp_android_bluetooch}} == WatchDog == {{page>:template:temp_android_watchdog}} == Key == {{page>:template:temp_android_key}} == LCD == {{page>:template:temp_android_lcd}} == PowerManager == {{page>:template:temp_android_pm}} == RTC == {{page>:template:temp_android_rtc}} === 系统基本功能设置 === {{page>:template:temp_android_system}} === 系统性能测试 === {{page>:template:temp_android_perf}} ==== Android API 使用说明 ==== {{page>:template:temp_android_api}} ==== Linux 使用指南 ==== === 接口功能测试 === == GPIO == {{page>:template:temp_linux_gpio11}} == UART == {{page>:template:temp_linux_uart}} == LAN == {{page>:template:temp_linux_lan}} == WIFI == {{page>:template:temp_linux_wifi}} == 4G/5G == {{page>:template:temp_linux_4g5g}} == Can == {{page>:template:temp_linux_can}} == GPIO/DIO == 1. IO 控制节点都在/sys/class/io_control/ {{:arm:rk3399:linux:r39s2a1-linux-io.png?600|}} 2. IO 对应表如下: ^ 功能 ^ 主板丝印 ^ 节点名 ^ ^ 输入 | IO1 | gpio_ip0 | | ::: | IO2 | gpio_ip1 | | ::: | IO3 | gpio_ip2 | | ::: | IO4 | gpio_ip3 | ^ 输出 | IO5 | gpio_op0 | | ::: | IO6 | gpio_op1 | | ::: | IO7 | gpio_op2 | | ::: | IO8 | gpio_op3 | 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 {{page>:template:temp_linux_gpio}} == Audio == {{page>:template:temp_linux_audio}} == Mic == {{page>:template:temp_linux_mic}} == USB == {{page>:template:temp_linux_usb}} == SDCARD == {{page>:template:temp_linux_sdcard}} == Bluetooth == {{page>:template:temp_linux_bluetooch}} == WatchDog == {{page>:template:temp_linux_watchdog}} == Key == {{page>:template:temp_linux_key}} == LCD/Backlight == {{page>:template:temp_linux_lcd}} == PowerManager == {{page>:template:temp_linux_pm}} == RTC/Timezone == {{page>:template:temp_linux_rtc}} == CPU == {{page>:template:temp_linux_cpu}} == Memory == {{page>:template:temp_linux_mem}} == EMMC == {{page>:template:temp_linux_emmc}} ==== Linux 编程指南 ==== === GPIO 应用编程 === C参考代码如下: #include #include #include #include #include #include #include static char gpio_path[100]; static int gpio_config(const char *attr, const char *val) { char file_path[100]; int len; int fd; sprintf(file_path, "%s/%s", gpio_path, attr); if (0 > (fd = open(file_path, O_WRONLY))) { perror("open error"); return fd; } len = strlen(val); if (len != write(fd, val, len)) { perror("write error"); close(fd); return -1; } close(fd); //关闭文件 return 0; } int main(int argc, char *argv[]) { char file_path[100]; char val; int fd; /* 校验传参 */ if (2 != argc) { fprintf(stderr, "usage: %s \n", argv[0]); exit(-1); } /* 判断指定编号的 GPIO 是否导出 */ sprintf(gpio_path, "/sys/class/gpio/gpio%s", argv[1]); if (access(gpio_path, F_OK)) {//如果目录不存在 则需要导出 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)) {//导出 gpio perror("write error"); close(fd); exit(-1); } close(fd); //关闭文件 } /* 配置为输入模式 */ if (gpio_config("direction", "in")) exit(-1); /* 极性设置 */ if (gpio_config("active_low", "0")) exit(-1); /* 配置为非中断方式 */ if (gpio_config("edge", "none")) exit(-1); /* 读取 GPIO 电平状态 */ sprintf(file_path, "%s/%s", gpio_path, "value"); if (0 > (fd = open(file_path, O_RDONLY))) { perror("open error"); exit(-1); } if (0 > read(fd, &val, 1)) { perror("read error"); close(fd); exit(-1); } printf("value: %c\n", val); /* 退出程序 */ close(fd); exit(0); } 交叉编译源码: aarch64-linux-gnu-gcc -o gpio gpio.c 将编译好的gpio程序使用scp拷贝到 r39s2 主板上,执行测试: 使用方法: 0:./gpio 3 1:./gpio 1 {{:arm:rk3399:linux:r39s2_gpio.c.png?600|}} === UART 应用编程 === 系统下操作 UART 的测试串口,以 J_RS232 TX3\RX3 测试为例: J_RS232 TX3\RX3 设备节点为: /dev/ttysWK2 C参考UART高低电平输入代码如下: #include #include #include #include #include #include #include #include #include int set_opt(int,int,int,char,int); void main(){ int fd,nByte; char *uart3 = "/dev/ttyS2"; char bufferR[2]; char bufferW[2]; memset(bufferR, '\0', 2); memset(bufferW, '\0', 2); if((fd=open(uart3,O_RDWR,0777))<0) { printf("failed\n"); } else{ printf("success\n"); set_opt(fd, 115200, 8, 'N', 1); } while(1){ nByte = 0; memset(bufferR, '\0', 2); memset(bufferW, '\0', 2); // printf("hello\n"); if((nByte = read(fd, bufferR, 1)) == 1){ //MCU串口发送接收都是单字节(单字符)函数 printf("receive:%c\n",bufferR[0]); bufferW[0] = 'A'; write(fd,bufferW,1); //串口发送单字节(单字符) buffer[0] = data memset(bufferR, '\0', 2); memset(bufferW, '\0', 2); nByte = 0; } } close(fd); } //串口通用初始化函数 int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop) { struct termios newtio,oldtio;//定义结构体newtio和oldtio //将原串口的数据取到oldtio if ( tcgetattr( fd,&oldtio) != 0) { perror("SetupSerial 1"); return -1; } //将newio清零和设置c_cflag bzero( &newtio, sizeof( newtio ) ); newtio.c_cflag |= CLOCAL | CREAD;//使能接收和忽略控制线 newtio.c_cflag &= ~CSIZE; //设置数据位 switch( nBits ) { case 7: newtio.c_cflag |= CS7; break; case 8: newtio.c_cflag |= CS8; break; } //设置校验位 switch( nEvent ) { //偶校验 case 'O': newtio.c_cflag |= PARENB;//使能奇偶校验 newtio.c_cflag |= PARODD;//偶校验 newtio.c_iflag |= (INPCK | ISTRIP);//输入校验并忽略第八位 break; case 'E': newtio.c_iflag |= (INPCK | ISTRIP); newtio.c_cflag |= PARENB; newtio.c_cflag &= ~PARODD;//取消偶校验(置零偶校验位),开启奇校验 break; case 'N': newtio.c_cflag &= ~PARENB;//不进行奇偶校验 break; } //设置波特率 switch( nSpeed ) { case 2400: cfsetispeed(&newtio, B2400); cfsetospeed(&newtio, B2400); break; case 4800: cfsetispeed(&newtio, B4800); cfsetospeed(&newtio, B4800); break; case 9600: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; case 115200: cfsetispeed(&newtio, B115200); cfsetospeed(&newtio, B115200); break; case 460800: cfsetispeed(&newtio, B460800); cfsetospeed(&newtio, B460800); break; default: cfsetispeed(&newtio, B9600); cfsetospeed(&newtio, B9600); break; } //设置停止位 if( nStop == 1 ) newtio.c_cflag &= ~CSTOPB;//一位停止位 else if ( nStop == 2 ) newtio.c_cflag |= CSTOPB;//两位停止位 newtio.c_cc[VTIME] = 0;//不设置读取超时 newtio.c_cc[VMIN] = 0;//读取最小字符数为0 tcflush(fd,TCIFLUSH);//清空缓冲区 //使配置生效 if((tcsetattr(fd,TCSANOW,&newtio))!=0) { perror("com set error"); return -1; } // printf("set done!\n\r"); return 0; } 交叉编译源码: aarch64-linux-gnu-gcc -o uart uart.c 将编译好的程序使用 scp 拷贝到 3399 主板上,执行测试: {{:arm:rk3399:linux:r39s2_uart.c.png?600|}} === KEY 应用编程 === 参考系统下操作Key的方法,获取到key的设备节点为 /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.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 打印如下: {{:arm:rk3399:linux:key编程.png?600|}} *按下按键时显示:key pressed *松开按键时显示:key released ==== Linux 应用支持 ==== === QT交叉编译环境 === {{page>:template:temp_Linux_qt}} === QT Creator === {{page>:template:temp_Linux_qt_creator}} === 高清硬解码 === {{page>:template:temp_Linux_dec}} === Docker === {{page>:template:temp_Linux_docker}} ===OpenCL=== * 系统已经支持OpenCL,输入命令clinfo即可查看支持详情: {{:arm:rk3399:linux:opencl.png?600|}} ==== Linux OTA 在线升级 ==== {{page>:template:temp_Linux_upgrade}} 终端输入 ota 进行固件在线升级 {{:arm:rk3399:linux:r39x2_ota.c.png?600|}}