Makefile文件内容

    1. SOURCE = $(wildcard *.c)
    2. TARGETS = $(patsubst %.c, %, $(SOURCE))
    3. CC = arm-linux-gcc
    4. PREFIX=/usr/lib/alsa-lib
    5. #CFLAGS = -Wall
    6. all:$(TARGETS)
    7. $(TARGETS):%:%.c
    8. $(CC) $< -o $@
    9. .PHONY:clean all
    10. clean:
    11. -rm -rf $(TARGETS)

    源文件uart_test.c

    1. #include<stdio.h>
    2. #include<stdlib.h>
    3. #include<fcntl.h>
    4. #include<unistd.h>
    5. #include<assert.h>
    6. #include<termios.h>
    7. #include<string.h>
    8. #include<sys/time.h>
    9. #include<sys/types.h>
    10. #include<errno.h>
    11. static int ret;
    12. static int fd;
    13. /*
    14. * 安全读写函数
    15. */
    16. ssize_t safe_write(int fd, const void *vptr, size_t n)
    17. {
    18. size_t nleft;
    19. ssize_t nwritten;
    20. const char *ptr;
    21. ptr = vptr;
    22. nleft = n;
    23. printf("%s, %d\n", ptr, nleft);
    24. while(nleft > 0)
    25. {
    26. if((nwritten = write(fd, ptr, nleft)) <= 0)
    27. {
    28. if(nwritten < 0&&errno == EINTR)
    29. nwritten = 0;
    30. else
    31. return -1;
    32. }
    33. nleft -= nwritten;
    34. ptr += nwritten;
    35. }
    36. return(n);
    37. }
    38. ssize_t safe_read(int fd,void *vptr,size_t n)
    39. {
    40. size_t nleft;
    41. ssize_t nread;
    42. char *ptr;
    43. ptr=vptr;
    44. nleft=n;
    45. while(nleft > 0)
    46. {
    47. if((nread = read(fd,ptr,nleft)) < 0)
    48. {
    49. if(errno == EINTR)//被信号中断
    50. nread = 0;
    51. else
    52. return -1;
    53. }
    54. else
    55. if(nread == 0)
    56. break;
    57. printf("%s", ptr);
    58. fflush(stdout);
    59. nleft -= nread;
    60. ptr += nread;
    61. }
    62. return (n-nleft);
    63. }
    64. int uart_open(int fd,const char *pathname)
    65. {
    66. assert(pathname);
    67. /*打开串口*/
    68. fd = open(pathname,O_RDWR|O_NOCTTY);
    69. if(fd == -1)
    70. {
    71. perror("Open UART failed!");
    72. return -1;
    73. }
    74. /*清除串口非阻塞标志*/
    75. /* if(fcntl(fd,F_SETFL,0) < 0)
    76. {
    77. fprintf(stderr,"fcntl failed!\n");
    78. return -1;
    79. }*/
    80. return fd;
    81. }
    82. int uart_set(int fd,int baude,int c_flow,int bits,char parity,int stop)
    83. {
    84. struct termios options;
    85. /*获取终端属性*/
    86. if(tcgetattr(fd,&options) < 0)
    87. {
    88. perror("tcgetattr error");
    89. return -1;
    90. }
    91. /*设置输入输出波特率,两者保持一致*/
    92. switch(baude)
    93. {
    94. case 4800:
    95. cfsetispeed(&options,B4800);
    96. cfsetospeed(&options,B4800);
    97. break;
    98. case 9600:
    99. cfsetispeed(&options,B9600);
    100. cfsetospeed(&options,B9600);
    101. break;
    102. case 19200:
    103. cfsetispeed(&options,B19200);
    104. cfsetospeed(&options,B19200);
    105. break;
    106. case 38400:
    107. cfsetispeed(&options,B38400);
    108. cfsetospeed(&options,B38400);
    109. break;
    110. case 115200:
    111. cfsetispeed(&options,B115200);
    112. cfsetospeed(&options,B115200);
    113. break;
    114. default:
    115. fprintf(stderr,"Unkown baude!\n");
    116. return -1;
    117. }
    118. /*设置控制模式*/
    119. options.c_cflag |= CLOCAL;//保证程序不占用串口
    120. options.c_cflag |= CREAD;//保证程序可以从串口中读取数据,表启用字符接收器,目的是能够从串口中读取输入的数据
    121. /*设置数据流控制*/
    122. switch(c_flow)
    123. {
    124. case 0://不进行流控制
    125. options.c_cflag &= ~CRTSCTS;
    126. break;
    127. case 1://进行硬件流控制
    128. options.c_cflag |= CRTSCTS;
    129. break;
    130. case 2://进行软件流控制
    131. options.c_cflag |= IXON|IXOFF|IXANY;
    132. break;
    133. default:
    134. fprintf(stderr,"Unkown c_flow!\n");
    135. return -1;
    136. }
    137. /*设置数据位*/
    138. switch(bits)
    139. {
    140. case 5:
    141. options.c_cflag &= ~CSIZE;//屏蔽其它标志位
    142. options.c_cflag |= CS5;
    143. break;
    144. case 6:
    145. options.c_cflag &= ~CSIZE;//屏蔽其它标志位
    146. options.c_cflag |= CS6;
    147. break;
    148. case 7:
    149. options.c_cflag &= ~CSIZE;//屏蔽其它标志位
    150. options.c_cflag |= CS7;
    151. break;
    152. case 8:
    153. options.c_cflag &= ~CSIZE;//屏蔽其它标志位
    154. options.c_cflag |= CS8;
    155. break;
    156. default:
    157. fprintf(stderr,"Unkown bits!\n");
    158. return -1;
    159. }
    160. /*设置校验位*/
    161. switch(parity)
    162. {
    163. /*无奇偶校验位*/
    164. case 'n':
    165. case 'N':
    166. options.c_cflag &= ~PARENB;//PARENB:产生奇偶位,执行奇偶校验
    167. printf("N\n");
    168. break;
    169. /*设为空格,即停止位为2位*/
    170. case 's':
    171. case 'S':
    172. options.c_cflag &= ~PARENB;//PARENB:产生奇偶位,执行奇偶校验
    173. options.c_cflag &= ~CSTOPB;//CSTOPB:使用两位停止位
    174. break;
    175. /*设置奇校验*/
    176. case 'o':
    177. case 'O':
    178. options.c_cflag |= PARENB;//PARENB:产生奇偶位,执行奇偶校验
    179. options.c_cflag |= PARODD;//PARODD:若设置则为奇校验,否则为偶校验
    180. options.c_cflag |= INPCK;//INPCK:使奇偶校验起作用
    181. options.c_cflag |= ISTRIP;//ISTRIP:若设置则有效输入数字被剥离7个字节,否则保留全部8位
    182. break;
    183. /*设置偶校验*/
    184. case 'e':
    185. case 'E':
    186. options.c_cflag |= PARENB;//PARENB:产生奇偶位,执行奇偶校验
    187. options.c_cflag &= ~PARODD;//PARODD:若设置则为奇校验,否则为偶校验
    188. options.c_cflag |= INPCK;//INPCK:使奇偶校验起作用
    189. options.c_cflag |= ISTRIP;//ISTRIP:若设置则有效输入数字被剥离7个字节,否则保留全部8位
    190. break;
    191. default:
    192. fprintf(stderr,"Unkown parity!\n");
    193. return -1;
    194. }
    195. /*设置停止位*/
    196. switch(stop)
    197. {
    198. case 1:
    199. options.c_cflag &= ~CSTOPB;//CSTOPB:使用一位停止位
    200. break;
    201. case 2:
    202. options.c_cflag |= CSTOPB;//CSTOPB:使用两位停止位
    203. break;
    204. default:
    205. fprintf(stderr,"Unkown stop!\n");
    206. return -1;
    207. }
    208. /*设置输出模式为原始输出*/
    209. options.c_oflag &= ~(OPOST| ONLCR | OLCUC | OCRNL | ONOCR | ONLRET | OFILL);//OPOST:若设置则按定义的输出处理,否则所有c_oflag失效
    210. /*设置本地模式为原始模式*/
    211. options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    212. /*
    213. *ICANON:允许规范模式进行输入处理
    214. *ECHO:允许输入字符的本地回显
    215. *ECHOE:在接收EPASE时执行Backspace,Space,Backspace组合
    216. *ISIG:允许信号
    217. */
    218. /*设置等待时间和最小接受字符*/
    219. options.c_cc[VTIME] = 0;//可以在select中设置
    220. options.c_cc[VMIN] = 1;//最少读取一个字符
    221. /*如果发生数据溢出,只接受数据,但是不进行读操作*/
    222. tcflush(fd,TCIFLUSH);
    223. /*激活配置*/
    224. if(tcsetattr(fd,TCSANOW,&options) < 0)
    225. {
    226. perror("tcsetattr failed");
    227. return -1;
    228. }
    229. return 0;
    230. }
    231. int uart_read(int fd,char *r_buf,size_t len)
    232. {
    233. ssize_t cnt = 0;
    234. fd_set rfds;
    235. struct timeval time;
    236. /*将文件描述符加入读描述符集合*/
    237. FD_ZERO(&rfds);
    238. FD_SET(fd,&rfds);
    239. /*设置超时为15s*/
    240. time.tv_sec = 15;
    241. time.tv_usec = 0;
    242. /*实现串口的多路I/O*/
    243. ret = select(fd+1,&rfds,NULL,NULL,&time);
    244. switch(ret)
    245. {
    246. case -1:
    247. fprintf(stderr,"select error!\n");
    248. return -1;
    249. case 0:
    250. fprintf(stderr,"time out!\n");
    251. return -1;
    252. default:
    253. cnt = safe_read(fd,r_buf,len);
    254. printf(" in uart_read");
    255. if(cnt == -1)
    256. {
    257. fprintf(stderr,"read error!\n");
    258. return -1;
    259. }
    260. return cnt;
    261. }
    262. }
    263. int uart_write(int fd,const char *w_buf,size_t len)
    264. {
    265. ssize_t cnt = 0;
    266. cnt = safe_write(fd,w_buf,len);
    267. if(cnt == -1)
    268. {
    269. fprintf(stderr,"write error!\n");
    270. return -1;
    271. }
    272. return cnt;
    273. }
    274. int uart_close(int fd)
    275. {
    276. assert(fd);
    277. close(fd);
    278. /*可以在这里做些清理工作*/
    279. return 0;
    280. }
    281. int main(int argc, char *argv[])
    282. {
    283. const char *w_buf = "hello";
    284. size_t w_len = strlen(w_buf);
    285. const char *tty = NULL;
    286. int baude;
    287. int c_flow;
    288. int bits;
    289. char parity;
    290. int stop;
    291. char r_buf[1024];
    292. bzero(r_buf,1024);
    293. tty = argv[1];
    294. printf("%s\n", tty);
    295. fd = uart_open(fd, tty);/*串口号/dev/ttySn,USB口号/dev/ttyUSBn*/
    296. if(fd == -1)
    297. {
    298. fprintf(stderr,"uart_open error\n");
    299. exit(EXIT_FAILURE);
    300. }
    301. printf("open OK\n");
    302. if( argc < 2)
    303. {
    304. printf("format uart_test /dev/ttySx baude stop data_bits parity config_stream\n");
    305. printf("such as:./uart_test /dev/ttySx 115200 1 8 N 0\n");
    306. exit(EXIT_FAILURE);
    307. }
    308. baude = atoi(argv[2]);
    309. stop = atoi(argv[3]);
    310. bits = atoi(argv[4]);
    311. parity = *argv[5];
    312. c_flow = atoi(argv[6]);
    313. printf("%s\n", tty);
    314. printf("%d, %d, %d, %c, %d\n", baude, stop, bits, parity, c_flow);
    315. if(uart_set(fd,baude,c_flow,bits,parity,stop) == -1)
    316. {
    317. fprintf(stderr,"uart set failed!\n");
    318. exit(EXIT_FAILURE);
    319. }
    320. printf("uart_set OK\n");
    321. ret = uart_write(fd,w_buf,w_len);
    322. if(ret == -1)
    323. {
    324. fprintf(stderr,"uart write failed!\n");
    325. exit(EXIT_FAILURE);
    326. }
    327. printf("uart_write OK\n");
    328. while(1)
    329. {
    330. ret = uart_read(fd,r_buf,1024);
    331. printf("loop");
    332. if(ret == -1)
    333. {
    334. fprintf(stderr,"uart read failed!\n");
    335. exit(EXIT_FAILURE);
    336. }
    337. printf("loop");
    338. }
    339. ret = uart_close(fd);
    340. if(ret == -1)
    341. {
    342. fprintf(stderr,"uart_close error\n");
    343. exit(EXIT_FAILURE);
    344. }
    345. exit(EXIT_SUCCESS);
    346. }