• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /*
17  * 该文件实现了在Hi3516DV300端通过Uart串口实现自发自收的功能,在内核配置成功的前提下,
18  * 通过打开/dev/ttyAMA1串口,并基于该串口实现自定义字符串的发送,并可在PC端通过串口工具进行查
19  * 看发送的字符串,也可以通过PC端串口工具往板Hi3516DV300端进行发送,板端可通打印查看是否收到的报文。
20  * 该示例可测试Hi3516DV300端串口收发是否正常。
21  *
22  * This file realizes the function of self-sending and self-receiving through the Uart serial port
23  * on the Hi3516DV300 side. On the premise that the kernel configuration is successful,
24  * by opening the /dev/ttyAMA1 serial port, and based on this serial port, the user-defined string is sent,
25  * and on the PC side through the serial port tool to view the sent string.
26  * It can also be sent to the Hi3516DV300 side of the board through the serial port tool on the PC side,
27  * and the board side can print to see if the received message is received.
28  * This example can test whether the serial port on the Hi3516DV300 is sending and receiving normally.
29  */
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <pthread.h>
35 #include <unistd.h>
36 #include <sys/types.h>
37 #include <sys/time.h>
38 #include <unistd.h>
39 #include <fcntl.h>
40 #include <termios.h>
41 
42 int uartFd = 0;
43 
44 /*
45  * 串口设置
46  * Serial port settings
47  */
Uart1Config(int fd)48 int Uart1Config(int fd)
49 {
50     struct termios newtio = {0}, oldtio = {0};
51     /*
52      * 获取原有串口配置
53      * Get the original serial port configuration
54      */
55     if (tcgetattr(fd, &oldtio) != 0) {
56         perror("SetupSerial 1");
57         return -1;
58     }
59     (void)memset_s(&newtio, sizeof(newtio), 0, sizeof(newtio));
60     /*
61      * CREAD开启串行数据接收,CLOCAL打开本地连接模式
62      * CREAD opens serial data reception, CLOCAL opens local connection mode
63      */
64     newtio.c_cflag  |=  CLOCAL | CREAD;
65 
66     /*
67      * 设置数据位
68      * Set data bit
69      */
70     newtio.c_cflag &= ~CSIZE;
71     newtio.c_cflag |= CS8;
72     /*
73      * 设置奇偶校验位
74      * Set parity bit
75      */
76     newtio.c_cflag &= ~PARENB; // 无奇偶校验
77     /*
78      * 设置波特率115200
79      * Set baud rate 115200
80      */
81     cfsetispeed(&newtio, B115200);
82     cfsetospeed(&newtio, B115200);
83 
84     /*
85      * 设置停止位
86      * Set stop bit
87      */
88     newtio.c_cflag &=  ~CSTOPB; /* 默认为一位停止位 */
89     /*
90      * 设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时
91      *
92      * Set the minimum characters and waiting time,
93      * when there are no special requirements for receiving characters and waiting time
94      */
95     newtio.c_cc[VTIME]  = 0; /* 非规范模式读取时的超时时间 */
96     newtio.c_cc[VMIN] = 0; /* 非规范模式读取时的最小字符数 */
97     /*
98      * tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来
99      *
100      * tcflush clears the unfinished input/output requests and data of the terminal;
101      * TCIFLUSH means clearing the data being received and not reading it out
102      */
103     tcflush(fd, TCIFLUSH);
104     if ((tcsetattr(fd, TCSANOW, &newtio)) != 0) {
105         perror("com set error");
106         return -1;
107     }
108     return 0;
109 }
110 
111 /*
112  * @berf uart 发送数据
113  * @param int fd: 串口文件描述符
114  * @param void *buf:发送数据buffer
115  * @param int len:数据缓冲长度
116  *
117  * @berf uart send
118  * @param int fd: uart file descriptor
119  * @param void *buf:send data buf
120  * @param int len:data buf len
121  */
UartSend(int fd,char * buf,int len)122 int UartSend(int fd, char *buf, int len)
123 {
124     int ret = 0;
125     int count = 0;
126     char *sendBuf = buf;
127     int sendLen = len;
128 
129     tcflush(fd, TCIFLUSH);
130 
131     while (sendLen > 0) {
132         ret = write(fd, (char*)sendBuf + count, sendLen);
133         if (ret < 1) {
134             printf("write data below 1 byte % d\r\n", ret);
135             break;
136         }
137         count += ret;
138         sendLen = sendLen - ret;
139     }
140 
141     return count;
142 }
143 
144 /*
145  * @berf uart 读取数据
146  * @param int uart_fd: 串口文件描述符
147  * @param void *buf: 读取数据buffer
148  * @param int len: 数据缓冲区长度
149  * @param int timeoutMs: 读取数据时间
150  *
151  * @berf uart read
152  * @param int uart_fd: uart file descriptor
153  * @param void *buf: read data buf
154  * @param int len: data buf len
155  * @param int timeoutMs: read data time
156  */
UartRead(int fd,char * buf,int len,int timeoutMs)157 int UartRead(int fd, char *buf, int len, int timeoutMs)
158 {
159     int ret = 0;
160     size_t  rsum = 0;
161     ret = 0;
162     fd_set rset;
163     struct timeval time;
164     int timeout = timeoutMs;
165     char *readBuf = buf;
166     int readLen = len;
167 
168     while (rsum < readLen) {
169         time.tv_sec = timeout / 1000; /* 1000:转换成秒 */
170         time.tv_usec = (timeout - time.tv_sec * 1000) * 1000; /* 1000, 1000:转换为微秒 */
171         FD_ZERO(&rset);
172         FD_SET(fd, &rset);
173         ret = select(fd + 1, &rset, NULL, NULL, &time); // 非阻塞式读取数据
174         if (ret <= 0) {
175             if (ret == 0) {
176                 printf("time over!\r\n");
177                 return -1;
178             }
179             if (ret == -1) {
180                 printf("select error!\r\n");
181                 continue; // 信号中断
182             }
183             return -1;
184         } else {
185             ret = read(fd, (char *)readBuf + rsum, readLen - rsum);
186             if (ret < 0) {
187                 printf("read data failed\r\n");
188                 return ret;
189             } else {
190                 rsum += ret;
191             }
192         }
193     }
194     return rsum;
195 }
196 
UartOpenInit(void)197 unsigned int UartOpenInit(void)
198 {
199     int fd;
200     char *uart1 = "/dev/ttyAMA1";
201 
202     if ((fd = open(uart1, O_RDWR | O_NOCTTY | O_NDELAY)) < 0) {
203         printf("open %s is failed", uart1);
204         return -1;
205     } else {
206         Uart1Config(fd);
207     }
208     return fd;
209 }
210 
UartClose(int fd)211 void UartClose(int fd)
212 {
213     close(fd);
214 }
215 
main(void)216 int main(void)
217 {
218     char *gestureName = NULL;
219     gestureName = "gesture first !!!!!!!!"; /* 对应手势里面字符串 */
220     unsigned char uartReadBuff[2048] = {0}; /* 读取buff大小为2048 */
221     unsigned int RecvLen = strlen(gestureName);
222     unsigned int ret = 0;
223     int readLen = 0;
224 
225     /*
226      * 串口初始化定义
227      * Serial port initialization definition
228      */
229     uartFd = UartOpenInit();
230     if (uartFd < 0) {
231         printf("uart1 open failed\r\n");
232     } else {
233         printf("uart1 open successed\r\n");
234     }
235     while (1) {
236         ret = UartSend(uartFd, (unsigned char*)gestureName, strlen(gestureName));
237         readLen = UartRead(uartFd, uartReadBuff, RecvLen, 1000); /* 1000 :time out */
238         if (readLen > 0) {
239             printf("Uart read data:%s\r\n", uartReadBuff);
240         }
241         if (getchar() == 'q') { /* 退出AI时, 调用clsoe函数 */
242             close(uartFd);
243             break;
244         }
245     }
246     uartFd = 0;
247     return 0;
248 }