海思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
/dev # stty -F /dev/ttyAMA0 -a
speed 115200 baud;stty: /dev/ttyAMA0
line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ^J;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon -iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
-echoctl echoke
/dev #
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
同样可以使用stty命令设置串口参数,比如:stty -F /dev/ttyAMA0 ispeed 115200 ospeed 115200 cs8
(三)查看串口数据收发
一般调试串口,我们可以将TX与RT接在一起,自己发数据给自己接收,看数据是否正常。也可以使用cat 查看串口数据或是echo发送数据。
发送数据:
echo "test 1234567890" > /dev/ttyAMA0
- 1
接收数据:
cat /dev/ttyAMA0
- 1
(四)查看串口硬件分配:
串口的硬件分配状态,比如IO和中断使用情况可以在/proc/tty/driver下的ttyAMA 种查看:
/proc/tty/driver # ls
ttyAMA usbserial
/proc/tty/driver # cat ttyAMA
serinfo:1.0 driver revision:
0: uart:PL011 rev2 mmio:0x12080000 irq:38 tx:119786 rx:254 RTS|DTR|DSR|CD|RI
1: uart:PL011 rev2 mmio:0x12090000 irq:39 tx:48102 rx:0 CTS|DSR|CD|RI
2: uart:PL011 rev2 mmio:0x120A0000 irq:40 tx:8620 rx:55014 CTS|DSR|CD|RI
- 1
- 2
- 3
- 4
- 5
- 6
- 7
(五)注意
如果串口的配置和数据的收发命令都能够正常,但是串口的引脚没有电平变化,这个可能是串口的复用功能没有设置,需要设置一下GPIO复用为串口功能。复用功能可以在设备树dts中设置,也可以使用海思的himm命令直接设置:
himm 0x120f0100 0x01 #UART2_RXD
himm 0x120f0104 0x01 #UART2_TXD
- 1
- 2
问题更新:
(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。
串口程序:
/************************************************************************************************
*****Describe: This program is writen to operate HI35xx serial devices. *****
*****Email: lishuangliang@outlook.com *****
*****Author: shuang liang li *****
*****Date: 2018-09-30 *****
*************************************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<termios.h>
#include<errno.h>
#include<string.h>
#include <signal.h>
//宏定义
#define HI_FALSE -1
#define HI_TRUE 0
#ifdef debugprintf
#define debugpri(mesg, args...) fprintf(stderr, "[HI Serial print:%s:%d:] " mesg "\n", __FILE__, __LINE__, ##args)
#else
#define debugpri(mesg, args...)
#endif
int HiSerfd;
void HI_Serial_Close(int fd);
void Hi_sigsegv(int dummy)
{
if(HiSerfd > 0)
HI_Serial_Close(HiSerfd);
fprintf(stderr, "Hi Serial Caught SIGSEGV, Abort!\n");
fclose(stderr);
abort();
}
void Hi_sigterm(int dummy)
{
if(HiSerfd > 0)
HI_Serial_Close(HiSerfd);
fprintf(stderr, "Hi Serial Caught SIGTERM, Abort!\n");
fclose(stderr);
exit(0);
}
void Hi_init_signals(void)
{
struct sigaction sa;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGSEGV);
sigaddset(&sa.sa_mask, SIGTERM);
sigaddset(&sa.sa_mask, SIGPIPE);
sa.sa_handler = Hi_sigsegv;
sigaction(SIGSEGV, &sa, NULL);
sa.sa_handler = Hi_sigterm;
sigaction(SIGTERM, &sa, NULL);
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
}
int HI_Serial_Usage(void)
{
printf("Usage:\n");
printf("\tmyhicom [-d] <HiSerialDevice> [-s] get netdeviece info [-rw] read or wite select\n");
printf("\tmyhicom [-h] for more usage\n");
printf("\tmyhicom [-v] the verson of the sofware\n");
printf("\tExample:\n\tmyhicom -d /dev/ttyAMA1 -s 115200 -w HiSerial:HelloWorld\n");
}
/*
*Function: HI_Serial_Open(int fd,char* ComDevice)
*Param: fd:file descirbe handle Serial Device: /dev/ttyAMA1 /dev/ttyAMA2
*Output: Ok or Fail
*/
int HI_Serial_Open(char* HiSerDevice)
{
int fd;
fd = open(HiSerDevice, O_RDWR|O_NOCTTY|O_NDELAY);
if (HI_FALSE == fd)
{
perror("HiSerial Can't Open Serial HiSerDevice");
return(HI_FALSE);
}
//恢复串口为阻塞状态
if(fcntl(fd, F_SETFL, 0) < 0)
{
debugpri("fcntl failed!\n");
return(HI_FALSE);
}
else
{
debugpri("fcntl=%d\n",fcntl(fd, F_SETFL,0));
}
//测试是否为终端设备
if(0 == isatty(STDIN_FILENO))
{
debugpri("standard input is not a terminal device\n");
return(HI_FALSE);
}
else
{
debugpri("isatty success!\n");
}
printf("fd->open=%d\n",fd);
return fd;
}
/*
*Function: HI_Serial_Close(int fd)
*Param: fd:file descirbe handle
*Output: Null
*/
void HI_Serial_Close(int fd)
{
if(fd > 0)
close(fd);
return;
}
/*
*Function: HI_Serial_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity)
*Param1: fd: file descirbe handle
*Param2: speed: select the Serial speed.115200,19200,9600...
*Param3: flow_ctrl: if use flow control
*Param4: databits: data bit select
*Param5: stopbits: stopbits select
*Param5: parity: partiy select
*Output: Ok or Fail
*/
int HI_Serial_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity)
{
int i;
int status;
int speed_arr[] = { B115200, B19200, B9600, B4800, B2400, B1200, B300};
int name_arr[] = {115200, 19200, 9600, 4800, 2400, 1200, 300};
struct termios options;
if( tcgetattr( fd,&options) != 0)
{
perror("SetupSerial 1");
return(HI_FALSE);
}
//set buater rate
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
{
if (speed == name_arr[i])
{
cfsetispeed(&options, speed_arr[i]);
cfsetospeed(&options, speed_arr[i]);
}
}
//set control model
options.c_cflag |= CLOCAL;
options.c_cflag |= CREAD;
//set flow control
switch(flow_ctrl)
{
case 0 ://none
options.c_cflag &= ~CRTSCTS;
break;
case 1 ://use hard ware
options.c_cflag |= CRTSCTS;
break;
case 2 ://use sofware
options.c_cflag |= IXON | IXOFF | IXANY;
break;
}
//select data bit
options.c_cflag &= ~CSIZE;
switch (databits)
{
case 5 :
options.c_cflag |= CS5;
break;
case 6 :
options.c_cflag |= CS6;
break;
case 7 :
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (HI_FALSE);
}
//select parity bit
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB;
options.c_iflag &= ~INPCK;
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB);
options.c_iflag |= INPCK;
break;
case 'e':
case 'E':
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_iflag |= INPCK;
break;
case 's':
case 'S':
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (HI_FALSE);
}
// set stopbit
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB; break;
case 2:
options.c_cflag |= CSTOPB; break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (HI_FALSE);
}
//set raw data output
options.c_oflag &= ~OPOST;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
//options.c_lflag &= ~(ISIG | ICANON);
//set wait time
options.c_cc[VTIME] = 1;
options.c_cc[VMIN] = 1;
tcflush(fd,TCIFLUSH);
//set the attribute to HiSerial device
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("com set error!\n");
return (HI_FALSE);
}
return (HI_TRUE);
}
/*
*Function: HI_Serial_Init(int fd, int speed,int flow_ctrl,int databits,int stopbits,int parity)
*Param: ...
*Output: HI_TRUE or HI_FALSE
*/
int HI_Serial_Init(int fd, int speed,int flow_ctrl,int databits,int stopbits,int parity)
{
int err;
//设置串口[数据帧](https://www.ebaina.com/resources/240000028176 "数据帧")格式
if (HI_Serial_Set(fd,speed,flow_ctrl,databits,stopbits,parity) == HI_FALSE)
{
return HI_FALSE;
}
else
{
return HI_TRUE;
}
}
/*
*Function: HI_Serial_Send(int fd, char *send_buf,int data_len)
*Param1: fd:file descirbe handle
*Param2: send_buf:Data to be send
*Param2: data_len:Data len
*Output: Data send len or HI_FALSE
*/
int HI_Serial_Send(int fd, char *send_buf,int data_len)
{
int len = 0;
len = write(fd,send_buf,data_len);
if (len == data_len )
{
debugpri("send data is %s\n",send_buf);
return len;
}
else
{
tcflush(fd,TCOFLUSH);
return HI_FALSE;
}
}
/*
*Function: HI_Serial_Recv(int fd, char *rcv_buf,int data_len)
*Param1: fd:file descirbe handle
*Param2: rcv_buf:receive Data
*Param2: data_len:receive Data len
*Output: Receive Data len or HI_FALSE
*/
int HI_Serial_Recv(int fd, char *rcv_buf,int data_len)
{
int len,fs_sel;
fd_set fs_read;
struct timeval time;
FD_ZERO(&fs_read);
FD_SET(fd,&fs_read);
time.tv_sec = 30;
time.tv_usec = 0;
//select fdset
fs_sel = select(fd+1,&fs_read,NULL,NULL,&time);
if(fs_sel)
{
len = read(fd,rcv_buf,data_len);
debugpri("HiSeral Receive Data = %s len = %d fs_sel = %d\n",rcv_buf,len,fs_sel);
return len;
}
else
{
debugpri("Hiserial haven't data receive!");
return HI_FALSE;
}
}
int main ( int argc, char *argv[] )
{
int cmd;
int len;
//extern char *optarg;
//extern int optind, opterr, optopt;
char HiSerialDev[32]="/dev/ttyAMA1";
char sendbuf[1024]={0};
char recvbuf[1024]={0};
int SerialSpeed = 115200;
Hi_init_signals();
if(argc == 1)
{
HI_Serial_Usage();
exit(0);
}
else
{
while ((cmd = getopt(argc, argv, ":d:s:rw:hv")) != -1)
{
switch (cmd)
{
case 'h':
HI_Serial_Usage();
break;
case 'v':
printf("myHicom --Verson V1.0.0\n");
break;
case 'd':
//printf("catch -d %s \n",optarg);
memset(HiSerialDev,0,sizeof(HiSerialDev));
sprintf(HiSerialDev,"%s",optarg);
printf("myHicom HiSerialDev %s\n",optarg);
break;
case 's':
SerialSpeed = atoi(optarg);
printf("myHicom speed %d\n",SerialSpeed);
break;
case 'r':
debugpri("myHicom read\n");
HiSerfd = HI_Serial_Open(HiSerialDev);
HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');
while(1)
{
len = HI_Serial_Recv(HiSerfd, recvbuf,sizeof(recvbuf));
if(len > 0)
{
recvbuf[len] = '\0';
printf("Hiserial receive data: %s\n",recvbuf);
memset(recvbuf,0,sizeof(recvbuf));
//break;
}
else
{
debugpri("Hiserial haven't data receive \n");
}
sleep(2);
};
break;
case 'w':
debugpri("myHicom write %s\n",optarg);
HiSerfd = HI_Serial_Open(HiSerialDev);
printf("fd = %d device = %s speed = %d\n",HiSerfd,HiSerialDev,SerialSpeed);
HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');
sprintf(sendbuf,"%s\n",optarg);
HI_Serial_Send(HiSerfd, sendbuf, strlen(sendbuf)+1);
if(HiSerfd > 0)
HI_Serial_Close(HiSerfd);
break;
case ':':
printf ("option: -%c missing argument. -h for help.\n",(char)optopt);
break;
case '?':
printf("Unknown option: -%c\n",(char)optopt);
break;
default:
exit(0);
}
}
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
原文链接:https://blog.csdn.net/li_wen01/article/details/86529523
- 分享
- 举报

-
浏览量:1158次2024-01-05 10:33:11
-
浏览量:2665次2020-08-26 17:32:45
-
浏览量:1454次2023-11-06 15:17:14
-
浏览量:2195次2020-08-04 20:24:33
-
浏览量:1131次2023-10-25 15:43:39
-
浏览量:1139次2023-10-26 15:06:55
-
浏览量:1127次2023-10-26 15:18:07
-
浏览量:937次2023-11-06 16:38:09
-
浏览量:2905次2020-08-04 20:12:26
-
浏览量:1048次2023-11-24 16:31:45
-
浏览量:2436次2020-08-04 20:26:22
-
浏览量:1207次2023-11-24 16:27:11
-
浏览量:2928次2020-07-28 17:54:29
-
浏览量:4710次2020-07-30 10:26:53
-
浏览量:3339次2020-07-28 10:38:42
-
浏览量:3765次2020-07-27 15:12:15
-
浏览量:3123次2020-07-29 15:38:57
-
浏览量:3244次2020-07-30 10:40:24
-
浏览量:3841次2020-07-28 10:49:06
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖

简星






举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明