【JokerのZYNQ7020】AXI_UARTLITE_LINUX。

软件环境:vivado 2017.4        硬件平台:XC7Z020


工程还是之前那篇的那个工程,今天说下怎么把axi_uartlite加到linux下,并使用起来。

 工程编译完成,生成设备树以后,看眼设备树pl.dtsi,确定是如下的样子。

/ {
	amba_pl: amba_pl {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "simple-bus";
		ranges ;
		axi_uartlite_0: serial@42c00000 {
			clock-names = "s_axi_aclk";
			clocks = <&clkc 15>;
			compatible = "xlnx,xps-uartlite-1.00.a";
			current-speed = <115200>;
			device_type = "serial";
			interrupt-names = "interrupt";
			interrupt-parent = <&intc>;
			interrupts = <0 29 1>;
			port-number = <0>;
			reg = <0x42c00000 0x10000>;
			xlnx,baudrate = <0x1c200>;
			xlnx,data-bits = <0x8>;
			xlnx,odd-parity = <0x0>;
			xlnx,s-axi-aclk-freq-hz-d = "50.0";
			xlnx,use-parity = <0x0>;
		};
	};
};

这里面的xInx,baudrate、xInx,data-bits、xInx,odd-parity和vivado中axi_uartlite设置的参数是保持一致的,和上篇说过的一样,如果要调整波特率、数据位数、奇偶校验等参数,在vivado中就必须重新设置并生成bitstream。

linux下axi_uartlite使用的驱动是 xlnx,xps-uartlite-1.00.a,在编译内核的时候,需要按路径依次打开如下选项。Device Drivers---Character devices---Serial drivers。

 添加对xilinx uartlite的支持,然后就可以保存,编译了。

哦对了,在做设备树的时候,一定注意一下调试串口,默认的好像是uartlite,把这里要改回去,不然kernel就从uartlite打印了。

 系统跑起来以后,在/dev下就能看到axi_uartlite设备了,名字叫ttyUL1。

应用层代码如下。

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>

int uart_configure(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
	struct termios newtio,oldtio;
	if  ( tcgetattr( fd,&oldtio)  !=  0) { 
		perror("SetupSerial 1");
		return -1;
	}
	bzero( &newtio, sizeof( newtio ) );
	newtio.c_cflag  |=  CLOCAL | CREAD;
	newtio.c_cflag &= ~CSIZE;

	switch( nBits )
	{
		case 7:
			newtio.c_cflag |= CS7;
			break;
		case 8:
			newtio.c_cflag |= CS8;
			break;
	}

	switch( nEvent )
	{
		case 'O':
			newtio.c_cflag |= PARENB;
			newtio.c_cflag |= PARODD;
			newtio.c_iflag |= (INPCK | ISTRIP);
			break;
		case 'E': 
			newtio.c_iflag |= (INPCK | ISTRIP);
			newtio.c_cflag |= PARENB;
			newtio.c_cflag &= ~PARODD;
			break;
		case 'N':  
			newtio.c_cflag &= ~PARENB;
			break;
	}

	switch( nSpeed )
	{
		case 2400:
			cfsetispeed(&newtio, B2400);
			cfsetospeed(&newtio, B2400);
			break;
		case 4800:
			cfsetispeed(&newtio, B4800);
			cfsetospeed(&newtio, B4800);
			break;
		case 9600:
			cfsetispeed(&newtio, B9600);
			cfsetospeed(&newtio, B9600);
			break;
		case 115200:
			cfsetispeed(&newtio, B115200);
			cfsetospeed(&newtio, B115200);
			break;
		case 460800:
			cfsetispeed(&newtio, B460800);
			cfsetospeed(&newtio, B460800);
			break;
		default:
			cfsetispeed(&newtio, B9600);
			cfsetospeed(&newtio, B9600);
			break;
	}

	if( nStop == 1 )
		newtio.c_cflag &=  ~CSTOPB;
	else if ( nStop == 2 )
		newtio.c_cflag |=  CSTOPB;

	newtio.c_cc[VTIME]  = 0;
	newtio.c_cc[VMIN] = 0;
	tcflush(fd,TCIFLUSH);

	if((tcsetattr(fd,TCSANOW,&newtio))!=0)
	{
		perror("com set error");
		return -1;
	}
	
	return 0;
}

void main()
{
	int fd,recv_cnt;
	char *uart_pl = "/dev/ttyUL1";
	char buffer[1500];
	char *uart_out = "start pl uart application\r\n";

	memset(buffer, 0, sizeof(buffer));
	fd = open(uart_pl, O_RDWR|O_NOCTTY);

	if(fd < 0)
		printf("open %s is failed",uart_pl);

	uart_configure(fd, 115200, 8, 'N', 1);
	write(fd,uart_out, strlen(uart_out));

	while(1){

		recv_cnt = read(fd, buffer, 1500);
		
		if(recv_cnt > 0)
		{
			buffer[recv_cnt+1] = '\0';			
			write(fd,buffer,strlen(buffer));
			memset(buffer, 0, strlen(buffer));
			recv_cnt = 0;
		}
	}
}

 串口助手测试,一切OK。

最后呢,备注两点:

1.按照道理呢, 代码中open(uart_pl, O_RDWR|O_NOCTTY)没加O_NONBLOCK,应该是阻塞模式,也就是说在串口没接收到东西的时候,会一直停在read(fd, buffer, 1500)这里,但是我在read下面加调试打印后,可以不断打印出来,说明就没有阻塞住,这个我得再琢磨琢磨是啥子问题。

2.由于使用的是pl端的axi_uart模块,所以如果要改串口的波特率等参数,不能只从操作系统应用代码中改波特率,那样是改不成功的,vivado中axi_uart模块参数必须与应用代码中设置的波特率一直才可以正常收发,这也是比较不方便的一点。

  • 6
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 24
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值