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 }