海思HI35XX串口调试

    我测试使用的是海思HI3520DV400设备,它总共有三个串口,官方提供的SDK只使能了UART0,也就是调试串口。如果要使用UART1或是UART2,用户需要自己手动设置。

(一)使能串口

    最直接的方式就是将设备树中对应uart的status修改为 status = "okay"。海思实际加载的串口驱动是PL011,menuconfig查看配置Device Drivers > Character devices > Serial drivers中的ARM AMBA PL011 serial port support 和 Support for console on AMBA serial port是否有选择上。重新编译内核烧入,在/dev 下可以查看是否有串口设备ttyAMA0~2。

(二)查看串口配置

可以使用linux的stty命令查看串口的配置参数。比如:stty -F /dev/ttyAMA0 -a


 
 
  1. /dev # stty -F /dev/ttyAMA0 -a
  2. speed 115200 baud;stty: /dev/ttyAMA0
  3.  line = 0;
  4. intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ^J;
  5. eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
  6. werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
  7. -parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
  8. -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon ixoff
  9. -iuclc -ixany -imaxbel -iutf8
  10. opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
  11. isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
  12. -echoctl echoke
  13. /dev # 

    同样可以使用stty命令设置串口参数,比如:stty -F /dev/ttyAMA0 ispeed 115200 ospeed 115200 cs8 

(三)查看串口数据收发

    一般调试串口,我们可以将TX与RT接在一起,自己发数据给自己接收,看数据是否正常。也可以使用cat 查看串口数据或是echo发送数据。
发送数据:

    echo "test 1234567890" > /dev/ttyAMA0
接收数据: 

    cat /dev/ttyAMA0

(四)查看串口硬件分配:

    串口的硬件分配状态,比如IO和中断使用情况可以在/proc/tty/driver下的ttyAMA 种查看:


 
 
  1. /proc/tty/driver # ls
  2. ttyAMA     usbserial
  3. /proc/tty/driver # cat ttyAMA 
  4. serinfo: 1.0 driver revision:
  5. 0: uart:PL011 rev2 mmio: 0x12080000 irq: 38 tx: 119786 rx: 254 RTS|DTR|DSR|CD|RI
  6. 1: uart:PL011 rev2 mmio: 0x12090000 irq: 39 tx: 48102 rx: 0 CTS|DSR|CD|RI
  7. 2: uart:PL011 rev2 mmio: 0x120A0000 irq: 40 tx: 8620 rx: 55014 CTS|DSR|CD|RI

(五)注意

    如果串口的配置和数据的收发命令都能够正常,但是串口的引脚没有电平变化,这个可能是串口的复用功能没有设置,需要设置一下GPIO复用为串口功能。复用功能可以在设备树dts中设置,也可以使用海思的himm命令直接设置:


 
 
  1.     himm 0x120f0100 0x01   #UART2_RXD 
  2.     himm 0x120f0104 0x01   #UART2_TXD

 

 



问题更新:

    (1)海思uart1只能发送数据,不能正常接收数据问题

    【问题背景】:设备树中正常启动uart1,配置uart1的TX, RX两个GPIO口复用为串口功能,能正常看到串口设备/dev/ttyAMA1;使用命令初始化串口1:stty -F /dev/ttyAMA1 ispeed 115200 ospeed 115200 cs8 

    【问题现象】:uart1只能发送数据,不能读取数据。执行 echo "test 1234567890" > /dev/ttyAMA1  可以查看到串口1有成功发送数据出去。周期向uart1发送数据,在海思端使用:cat /dev/ttyAMA1 查看串口数据接收情况,发发现接收不到数据。于此同时,数据直接RT接收到数据之后,又通过RT把全部数据发送出去了。在应用层接收不到串口的数据。

    我在海思3520DV300 和HI3520DV400上测试,都是只有uart1出现该问题,uart0和uart2正常。 

    但是如果海思端使用microcom(busybox自带命令工具) 工具来查看数据,又能正常的收到数据。查看命令为:microcom -s 115200 /dev/ttyCOM2

    【问题原因】:串口没有正确的初始化。海思的uart1 如果只设置串口波特率和位数奇偶数等信息是不能正常运行。还需要设置串口的其它属性,也就是结构体struct termios里的参数 。这里需要使用程序来初始化。

    【解决方案】:使用应用程序初始化uart1。

    

下面串口程序来源于:https://blog.csdn.net/dosthing/article/details/82951207 ;在我的开发板上测试正常。


 
 
  1. /************************************************************************************************
  2. *****Describe: This program is writen to operate HI35xx serial devices. *****
  3. *****Email: lishuangliang@outlook.com *****
  4. *****Author: shuang liang li *****
  5. *****Date: 2018-09-30 *****
  6. *************************************************************************************************/
  7. #include<stdio.h>
  8. #include<stdlib.h>
  9. #include<unistd.h>
  10. #include<sys/types.h>
  11. #include<sys/stat.h>
  12. #include<fcntl.h>
  13. #include<termios.h>
  14. #include<errno.h>
  15. #include<string.h>
  16. #include <signal.h>
  17. //宏定义
  18. #define HI_FALSE -1
  19. #define HI_TRUE 0
  20. #ifdef debugprintf
  21. #define debugpri(mesg, args...) fprintf(stderr, "[HI Serial print:%s:%d:] " mesg "\n", __FILE__, __LINE__, ##args)
  22. #else
  23. #define debugpri(mesg, args...)
  24. #endif
  25. int HiSerfd;
  26. void HI_Serial_Close(int fd);
  27. void Hi_sigsegv(int dummy)
  28. {
  29. if(HiSerfd > 0)
  30. HI_Serial_Close(HiSerfd);
  31. fprintf( stderr, "Hi Serial Caught SIGSEGV, Abort!\n");
  32. fclose( stderr);
  33. abort();
  34. }
  35. void Hi_sigterm(int dummy)
  36. {
  37. if(HiSerfd > 0)
  38. HI_Serial_Close(HiSerfd);
  39. fprintf( stderr, "Hi Serial Caught SIGTERM, Abort!\n");
  40. fclose( stderr);
  41. exit( 0);
  42. }
  43. void Hi_init_signals(void)
  44. {
  45. struct sigaction sa;
  46. sa.sa_flags = 0;
  47. sigemptyset(&sa.sa_mask);
  48. sigaddset(&sa.sa_mask, SIGSEGV);
  49. sigaddset(&sa.sa_mask, SIGTERM);
  50. sigaddset(&sa.sa_mask, SIGPIPE);
  51. sa.sa_handler = Hi_sigsegv;
  52. sigaction(SIGSEGV, &sa, NULL);
  53. sa.sa_handler = Hi_sigterm;
  54. sigaction(SIGTERM, &sa, NULL);
  55. sa.sa_handler = SIG_IGN;
  56. sigaction(SIGPIPE, &sa, NULL);
  57. }
  58. int HI_Serial_Usage(void)
  59. {
  60. printf( "Usage:\n");
  61. printf( "\tmyhicom [-d] <HiSerialDevice> [-s] get netdeviece info [-rw] read or wite select\n");
  62. printf( "\tmyhicom [-h] for more usage\n");
  63. printf( "\tmyhicom [-v] the verson of the sofware\n");
  64. printf( "\tExample:\n\tmyhicom -d /dev/ttyAMA1 -s 115200 -w HiSerial:HelloWorld\n");
  65. }
  66. /*
  67. *Function: HI_Serial_Open(int fd,char* ComDevice)
  68. *Param: fd:file descirbe handle Serial Device: /dev/ttyAMA1 /dev/ttyAMA2
  69. *Output: Ok or Fail
  70. */
  71. int HI_Serial_Open(char* HiSerDevice)
  72. {
  73. int fd;
  74. fd = open(HiSerDevice, O_RDWR|O_NOCTTY|O_NDELAY);
  75. if (HI_FALSE == fd)
  76. {
  77. perror( "HiSerial Can't Open Serial HiSerDevice");
  78. return(HI_FALSE);
  79. }
  80. //恢复串口为阻塞状态
  81. if(fcntl(fd, F_SETFL, 0) < 0)
  82. {
  83. debugpri( "fcntl failed!\n");
  84. return(HI_FALSE);
  85. }
  86. else
  87. {
  88. debugpri( "fcntl=%d\n",fcntl(fd, F_SETFL, 0));
  89. }
  90. //测试是否为终端设备
  91. if( 0 == isatty(STDIN_FILENO))
  92. {
  93. debugpri( "standard input is not a terminal device\n");
  94. return(HI_FALSE);
  95. }
  96. else
  97. {
  98. debugpri( "isatty success!\n");
  99. }
  100. printf( "fd->open=%d\n",fd);
  101. return fd;
  102. }
  103. /*
  104. *Function: HI_Serial_Close(int fd)
  105. *Param: fd:file descirbe handle
  106. *Output: Null
  107. */
  108. void HI_Serial_Close(int fd)
  109. {
  110. if(fd > 0)
  111. close(fd);
  112. return;
  113. }
  114. /*
  115. *Function: HI_Serial_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity)
  116. *Param1: fd: file descirbe handle
  117. *Param2: speed: select the Serial speed.115200,19200,9600...
  118. *Param3: flow_ctrl: if use flow control
  119. *Param4: databits: data bit select
  120. *Param5: stopbits: stopbits select
  121. *Param5: parity: partiy select
  122. *Output: Ok or Fail
  123. */
  124. int HI_Serial_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity)
  125. {
  126. int i;
  127. int status;
  128. int speed_arr[] = { B115200, B19200, B9600, B4800, B2400, B1200, B300};
  129. int name_arr[] = { 115200, 19200, 9600, 4800, 2400, 1200, 300};
  130. struct termios options;
  131. if( tcgetattr( fd,&options) != 0)
  132. {
  133. perror( "SetupSerial 1");
  134. return(HI_FALSE);
  135. }
  136. //set buater rate
  137. for ( i= 0; i < sizeof(speed_arr) / sizeof( int); i++)
  138. {
  139. if (speed == name_arr[i])
  140. {
  141. cfsetispeed(&options, speed_arr[i]);
  142. cfsetospeed(&options, speed_arr[i]);
  143. }
  144. }
  145. //set control model
  146. options.c_cflag |= CLOCAL;
  147. options.c_cflag |= CREAD;
  148. //set flow control
  149. switch(flow_ctrl)
  150. {
  151. case 0 : //none
  152. options.c_cflag &= ~CRTSCTS;
  153. break;
  154. case 1 : //use hard ware
  155. options.c_cflag |= CRTSCTS;
  156. break;
  157. case 2 : //use sofware
  158. options.c_cflag |= IXON | IXOFF | IXANY;
  159. break;
  160. }
  161. //select data bit
  162. options.c_cflag &= ~CSIZE;
  163. switch (databits)
  164. {
  165. case 5 :
  166. options.c_cflag |= CS5;
  167. break;
  168. case 6 :
  169. options.c_cflag |= CS6;
  170. break;
  171. case 7 :
  172. options.c_cflag |= CS7;
  173. break;
  174. case 8:
  175. options.c_cflag |= CS8;
  176. break;
  177. default:
  178. fprintf( stderr, "Unsupported data size\n");
  179. return (HI_FALSE);
  180. }
  181. //select parity bit
  182. switch (parity)
  183. {
  184. case 'n':
  185. case 'N':
  186. options.c_cflag &= ~PARENB;
  187. options.c_iflag &= ~INPCK;
  188. break;
  189. case 'o':
  190. case 'O':
  191. options.c_cflag |= (PARODD | PARENB);
  192. options.c_iflag |= INPCK;
  193. break;
  194. case 'e':
  195. case 'E':
  196. options.c_cflag |= PARENB;
  197. options.c_cflag &= ~PARODD;
  198. options.c_iflag |= INPCK;
  199. break;
  200. case 's':
  201. case 'S':
  202. options.c_cflag &= ~PARENB;
  203. options.c_cflag &= ~CSTOPB;
  204. break;
  205. default:
  206. fprintf( stderr, "Unsupported parity\n");
  207. return (HI_FALSE);
  208. }
  209. // set stopbit
  210. switch (stopbits)
  211. {
  212. case 1:
  213. options.c_cflag &= ~CSTOPB; break;
  214. case 2:
  215. options.c_cflag |= CSTOPB; break;
  216. default:
  217. fprintf( stderr, "Unsupported stop bits\n");
  218. return (HI_FALSE);
  219. }
  220. //set raw data output
  221. options.c_oflag &= ~OPOST;
  222. options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
  223. //options.c_lflag &= ~(ISIG | ICANON);
  224. //set wait time
  225. options.c_cc[VTIME] = 1;
  226. options.c_cc[VMIN] = 1;
  227. tcflush(fd,TCIFLUSH);
  228. //set the attribute to HiSerial device
  229. if (tcsetattr(fd,TCSANOW,&options) != 0)
  230. {
  231. perror( "com set error!\n");
  232. return (HI_FALSE);
  233. }
  234. return (HI_TRUE);
  235. }
  236. /*
  237. *Function: HI_Serial_Init(int fd, int speed,int flow_ctrl,int databits,int stopbits,int parity)
  238. *Param: ...
  239. *Output: HI_TRUE or HI_FALSE
  240. */
  241. int HI_Serial_Init(int fd, int speed,int flow_ctrl,int databits,int stopbits,int parity)
  242. {
  243. int err;
  244. //设置串口数据帧格式
  245. if (HI_Serial_Set(fd,speed,flow_ctrl,databits,stopbits,parity) == HI_FALSE)
  246. {
  247. return HI_FALSE;
  248. }
  249. else
  250. {
  251. return HI_TRUE;
  252. }
  253. }
  254. /*
  255. *Function: HI_Serial_Send(int fd, char *send_buf,int data_len)
  256. *Param1: fd:file descirbe handle
  257. *Param2: send_buf:Data to be send
  258. *Param2: data_len:Data len
  259. *Output: Data send len or HI_FALSE
  260. */
  261. int HI_Serial_Send(int fd, char *send_buf,int data_len)
  262. {
  263. int len = 0;
  264. len = write(fd,send_buf,data_len);
  265. if (len == data_len )
  266. {
  267. debugpri( "send data is %s\n",send_buf);
  268. return len;
  269. }
  270. else
  271. {
  272. tcflush(fd,TCOFLUSH);
  273. return HI_FALSE;
  274. }
  275. }
  276. /*
  277. *Function: HI_Serial_Recv(int fd, char *rcv_buf,int data_len)
  278. *Param1: fd:file descirbe handle
  279. *Param2: rcv_buf:receive Data
  280. *Param2: data_len:receive Data len
  281. *Output: Receive Data len or HI_FALSE
  282. */
  283. int HI_Serial_Recv(int fd, char *rcv_buf,int data_len)
  284. {
  285. int len,fs_sel;
  286. fd_set fs_read;
  287. struct timeval time;
  288. FD_ZERO(&fs_read);
  289. FD_SET(fd,&fs_read);
  290. time.tv_sec = 30;
  291. time.tv_usec = 0;
  292. //select fdset
  293. fs_sel = select(fd+ 1,&fs_read, NULL, NULL,&time);
  294. if(fs_sel)
  295. {
  296. len = read(fd,rcv_buf,data_len);
  297. debugpri( "HiSeral Receive Data = %s len = %d fs_sel = %d\n",rcv_buf,len,fs_sel);
  298. return len;
  299. }
  300. else
  301. {
  302. debugpri( "Hiserial haven't data receive!");
  303. return HI_FALSE;
  304. }
  305. }
  306. int main ( int argc, char *argv[] )
  307. {
  308. int cmd;
  309. int len;
  310. //extern char *optarg;
  311. //extern int optind, opterr, optopt;
  312. char HiSerialDev[ 32]= "/dev/ttyAMA1";
  313. char sendbuf[ 1024]={ 0};
  314. char recvbuf[ 1024]={ 0};
  315. int SerialSpeed = 115200;
  316. Hi_init_signals();
  317. if(argc == 1)
  318. {
  319. HI_Serial_Usage();
  320. exit( 0);
  321. }
  322. else
  323. {
  324. while ((cmd = getopt(argc, argv, ":d:s:rw:hv")) != -1)
  325. {
  326. switch (cmd)
  327. {
  328. case 'h':
  329. HI_Serial_Usage();
  330. break;
  331. case 'v':
  332. printf( "myHicom --Verson V1.0.0\n");
  333. break;
  334. case 'd':
  335. //printf("catch -d %s \n",optarg);
  336. memset(HiSerialDev, 0, sizeof(HiSerialDev));
  337. sprintf(HiSerialDev, "%s",optarg);
  338. printf( "myHicom HiSerialDev %s\n",optarg);
  339. break;
  340. case 's':
  341. SerialSpeed = atoi(optarg);
  342. printf( "myHicom speed %d\n",SerialSpeed);
  343. break;
  344. case 'r':
  345. debugpri( "myHicom read\n");
  346. HiSerfd = HI_Serial_Open(HiSerialDev);
  347. HI_Serial_Init(HiSerfd,SerialSpeed, 0, 8, 1, 'N');
  348. while( 1)
  349. {
  350. len = HI_Serial_Recv(HiSerfd, recvbuf, sizeof(recvbuf));
  351. if(len > 0)
  352. {
  353. recvbuf[len] = '\0';
  354. printf( "Hiserial receive data: %s\n",recvbuf);
  355. memset(recvbuf, 0, sizeof(recvbuf));
  356. //break;
  357. }
  358. else
  359. {
  360. debugpri( "Hiserial haven't data receive \n");
  361. }
  362. sleep( 2);
  363. };
  364. break;
  365. case 'w':
  366. debugpri( "myHicom write %s\n",optarg);
  367. HiSerfd = HI_Serial_Open(HiSerialDev);
  368. printf( "fd = %d device = %s speed = %d\n",HiSerfd,HiSerialDev,SerialSpeed);
  369. HI_Serial_Init(HiSerfd,SerialSpeed, 0, 8, 1, 'N');
  370. sprintf(sendbuf, "%s\n",optarg);
  371. HI_Serial_Send(HiSerfd, sendbuf, strlen(sendbuf)+ 1);
  372. if(HiSerfd > 0)
  373. HI_Serial_Close(HiSerfd);
  374. break;
  375. case ':':
  376. printf ( "option: -%c missing argument. -h for help.\n",( char)optopt);
  377. break;
  378. case '?':
  379. printf( "Unknown option: -%c\n",( char)optopt);
  380. break;
  381. default:
  382. exit( 0);
  383. }
  384. }
  385. }
  386. return 0;
  387. }

 

  

    

  •                     <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#csdnc-thumbsup"></use>
                        </svg><span class="name">点赞</span>
                        <span class="count"></span>
                        </a></li>
                        <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-Collection-G"></use>
                        </svg><span class="name">收藏</span></a></li>
                        <li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xlink:href="#icon-csdnc-fenxiang"></use>
                        </svg>分享</a></li>
                        <!--打赏开始-->
                                                <!--打赏结束-->
                                                <li class="tool-item tool-more">
                            <a>
                            <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                            </a>
                            <ul class="more-box">
                                <li class="item"><a class="article-report">文章举报</a></li>
                            </ul>
                        </li>
                                            </ul>
                </div>
                            </div>
            <div class="person-messagebox">
                <div class="left-message"><a href="https://blog.csdn.net/li_wen01">
                    <img src="https://profile.csdnimg.cn/3/0/D/3_li_wen01" class="avatar_pic" username="li_wen01">
                                            <img src="https://g.csdnimg.cn/static/user-reg-year/2x/4.png" class="user-years">
                                    </a></div>
                <div class="middle-message">
                                        <div class="title"><span class="tit"><a href="https://blog.csdn.net/li_wen01" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">li_wen01</a></span>
                                                    <span class="flag expert">
                                <a href="https://blog.csdn.net/home/help.html#classicfication" target="_blank">
                                    <svg class="icon" aria-hidden="true">
                                        <use xlink:href="#csdnc-blogexpert"></use>
                                    </svg>
                                    博客专家
                                </a>
                            </span>
                                            </div>
                    <div class="text"><span>发布了164 篇原创文章</span> · <span>获赞 243</span> · <span>访问量 65万+</span></div>
                </div>
                                <div class="right-message">
                                            <a href="https://bbs.csdn.net/topics/395527769" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-messageboard">他的留言板
                        </a>
                                                            <a class="btn btn-sm  bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">关注</a>
                                    </div>
                            </div>
                    </div>
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值