一、 前言
Hi3559V200 的 UART0 是调试串口,所以当我们想要用串口跟外设通信的时候就要用到其他的 UART,接下来为大家介绍 Hi3559V200 UART1 的启用步骤。
使用的硬件平台是 Hi3559V200DMEB VER.A,使用的 SDK 版本是 Hi3559V200_MobileCam_SDK_V1.0.1.5。
二、 硬件原理图
2.1 Hi3559V200 平台 UART 介绍
Hi3559V200 平台一共有 5 个 UART,如果要使用 UART1,首先在设备树中使能 UART1,然后需要把具有 UART1 TXD 和 RXD 功能的管脚复用为 UART1 功能,
然后编写一个验证 UART1 收发数据功能的应用程序即可实现 UART1 通信。
2.2 查看原理图确认 UART1 的位置
查看原理图可以发现 CPU 的 UART1_TXD 和 UART1_RXD 管脚连接到 J21 上,所以 J21 就是 UART1 在板端的位置。
图 2.1 UART1 的原理图
图 2.2 UART1 在板端的位置
三、 硬件资源申请及分配
3.1 配置 DTS 文件
海思平台可以通过 DTS 设备树文件对硬件设备资源进行申请及分配,DTS 文件所在目录为 osdrv\opensource\kernel\linux-4.9.y\arch\arm\boot\dts,
文件名是 hi3559v200.dtsi 和 hi3559v200-demb.dts。在 hi3559v200.dtsi 中 UART1 是默认分配给 LiteOS 系统的,这里需要修改为分配到 Linux 系统中,
并且在 aliases 中添加 “serial1 = &uart1;”:
图 3.1 修改 hi3559v200.dtsi 文件
在 hi3559v200-demb.dts 文件中只需要把 uart1 的状态设置为 “okay”即可:
图3.2 修改 hi3559v200-demb.dts 文件
3.2 配置时钟和中断
这一步骤是为了填 SDK 里的一个坑,如果配置好 DTS 文件启用 UART1 后直接调试的话,会出现 UART1 的波特率一直为 0,从而无法通信的情况。
造成这个问题的原因是 UART1 的时钟没有开启!需要手动在 osdrv/opensource/kernel/linux-4.9.y/drivers/clk/hisilicon/clk-hi3559v200.c 文件里开启 UART1 的时钟,
并且 UART1 在 HI3559V200 平台上默认用作 LiteOS 系统的调试串口,所以也需要在 osdrv/platform/liteos/platform/bsp/board/hi3559v200/include/hisoc/uart.h
文件把 LiteOS 的默认调试串口修改为其他串口,在osdrv/platform/liteos/platform/bsp/board/hi3559v200/include/irq_map.h 文件把 UART1 的中断从 CPU1 所属
设置为 CPU0 所属,CPU1 是 LiteOS 系统,CPU0 是 Linux 系统。
图 3.3 去掉注释开启 UART1 时钟
图 3.4 修改 LiteOS 调试串口为 UART2
图 3.5 修改 UART1 中断所属为 CPU0
注:完成此步骤后需要重新编译 kernel 并更新到板端。
四、 管脚复用
4.1 查询管脚复用寄存器
在 《Hi3559V200_PINOUT_CN.xlsx》 中查询 UART1_TXD 和 UART1_RXD 管脚的控制寄存器地址:
图 4.1 UART1 管脚复用寄存器
4.2 配置管脚复用
接下来需要把以上的两个引脚复用成 UART1 功能,海思提供了一个表格工具对引脚复用进行初始化配置,表格工具位于 osdrv\tools\pc\uboot_tools,
对于 Hi3559V200DMEB 板,适用 Hi3559V200-DMEB_6L_T-DDR3_1800M_512MB_16bitx2-A7_900M-SYSBUS_300M.xlsm 表格,只需按照上面的例子
把刚才查到的寄存器名称、地址、要写入的数据填进去即可:
图 4.2 配置管脚复用表格
注:添加复用后要重新编译 u-boot 并更新到板端。
五、 编写 UART1 通信应用程序
配置好 SDK 后,接下来需要一个应用程序来验证 UART1 是否能正常收发数据,以下是我在 Samplecam 中编写的一个用于调试的 uart_app 应用程序,
存放的位置为 reference/samplecam/app/uart1/uart1_main.c,完整代码请看附件,以下代码仅供参考:
|
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);
//printf("HiSeral Receive Data = %s len = %d fs_sel = %d\n",rcv_buf,len,fs_sel);
return len;
}
else
{
printf("Hiserial haven't data receive!");
return HI_FALSE;
}
}
/* 提示运行程序时需要输入的参数 */
void HI_Serial_Usage(void)
{
printf("Usage:\n");
printf("\tmyhicom [-d] [-s] get netdeviece info [-rw] read or write select\n");
printf("\tExample:\n\tmyhicom -d /dev/ttyAMA1 -s 115200 -w HiSerial:HelloWorld\n");
}
int main (int argc, char *argv[])
{
int cmd;
int len;
HI_S32 HiSerfd;
HI_S32 *fd = &HiSerfd;
extern char *optarg;
const HI_CHAR *uartDev = "/dev/ttyAMA1";
char sendbuf[1024]={0};
char recvbuf[1024]={0};
//extern int optind, opterr, optopt;
//Hi_init_signals();
if(argc == 1)
{
HI_Serial_Usage();
exit(0);
}
else
{
while ((cmd = getopt(argc, argv, ":rw:")) != -1)
{
switch (cmd)
{
case 'r':
printf("myHicom read\n");
HAL_UART_Init(uartDev, fd);
//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
{
printf("Hiserial haven't data receive \n");
}
sleep(2);
};
break;
case 'w':
printf("myHicom write %s\n",optarg);
HAL_UART_Init(uartDev, fd);
//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)
HAL_UART_DeInit(HiSerfd);
break;
default:
exit(0);
}
}
}
return 0;
}
六、验证过程
为了方便验证,使用 UART1 串口与 PC 端进行通信,将 UART0 调试串口和 UART1 同时连接到 PC 端,具体验证步骤如下:
① 在板端输入 “stty -F /dev/ttyAMA1 ispeed 115200 ospeed 115200” 命令设置 UART1 的波特率为 115200,其中的 “/dev/ttyAMA1”指的是 UART1 的设备文件。
② 运行 uart_app 使用 UART1 发送一串数据,查看 PC 端是否能成功接收。
③ 运行 uart_app 进入读取 UART1 数据的状态,在此状态会一直读取 UART1 接收的数据,然后在 PC 端发送一串数据到 UART1,查看板端是否能准确读取。
图 6.1 UART0 调试终端
图 6.2 UART1 终端
从上两图可以看出,UART1 发送 “12345” 这个字符串成功在 PC 端接收,PC 端发送 “hello world!” 字符串在板端也成功接收,
至此,UART1 已经成功与外部设备进行通信。
参考资料:
【1】《外围设备驱动操作指南.doc》
【2】《Hi3559V200_PINOUT_CN.xlsx》
【3】《HI3559V200DMEB_VER_A_SCH.pdf》
评论