===== 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|}}