差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
r39s2 [2023/02/07 18:10]
wjj [Linux OTA 在线升级]
r39s2 [2023/02/21 18:46] (当前版本)
wjj
行 81: 行 81:
 {{page>:template:temp_linux_can}} {{page>:template:temp_linux_can}}
 == GPIO/DIO == == 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}} {{page>:template:temp_linux_gpio}}
 == Audio == == Audio ==
行 108: 行 141:
 == EMMC == == EMMC ==
 {{page>:template:temp_linux_emmc}} {{page>:template:temp_linux_emmc}}
-==== Linux编程指南 ==== +==== Linux 编程指南 ==== 
-{{page>:template:temp_Linux_sw}}+ 
 +=== GPIO 应用编程 === 
 + 
 +C参考代码如下: 
 +<code 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]; 
 +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 <gpio>\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); 
 +
 +</code> 
 +交叉编译源码: 
 + 
 +  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高低电平输入代码如下: 
 + 
 +<code C> 
 +#include <stdio.h> 
 +#include <stdlib.h> 
 +#include <string.h> 
 +#include <unistd.h> 
 +#include <sys/types.h> 
 +#include <sys/stat.h> 
 +#include <fcntl.h> 
 +#include <termios.h> 
 +#include <errno.h> 
 +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; 
 +
 + 
 +</code> 
 + 
 +交叉编译源码: 
 + 
 +  aarch64-linux-gnu-gcc -o uart uart.c 
 + 
 +将编译好的程序使用 scp 拷贝到 3399 主板上,执行测试: 
 + 
 +{{:arm:rk3399:linux:r39s2_uart.c.png?600|}} 
 + 
 + 
 +=== KEY 应用编程 === 
 + 
 +参考系统下操作Key的方法,获取到key的设备节点为 
 +<code> 
 +/dev/input/event2 
 +</code> 
 +C参考代码如下: 
 + 
 +<code 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; 
 +
 +</code> 
 + 
 +交叉编译源码: 
 + 
 +<code>  
 +aarch64-linux-gnu-gcc -o key key.c 
 +</code> 
 +将编译好的程序使用 scp 拷贝到 r39s2 主板上,执行测试,按动 key 打印如下: 
 + 
 +{{:arm:rk3399:linux:key编程.png?600|}} 
 + 
 +  *按下按键时显示:key pressed 
 +  *松开按键时显示:key released 
  
  
打印/导出