ZYNQ:PS-CAN总线功能应用

0前言

上篇文章解决了ZYNQ搭建PS和PL系统的问题,相当于完成最小系统板搭建。因此,本篇文章主要用于记录搭建CAN外设系统会出现的问题。由于ZYNQ系统包含PS和PL两个部分,PS部分往往问题较少,所以考虑先搭建PS系统的CAN外设系统。熟悉了基本流程和软件库函数使用后,再搭建PL的CAN外设应用。初期目标是能够用逻辑分析仪收发CAN帧。

总结:回顾整个过程,影响CAN帧发送功能的主要两个方面因素:1 EMIO引脚映射,将小梅哥扩展PL引脚看成是普通PL引脚,同时忽略了PL引脚之间的特殊功能差异;2程序无法进入预期模式,目前来看是CAN外设GetMode函数反应问题,需要增加延迟函数。一个硬件系统盲区,一个软件系统外设驱动细节,加上各种小的问题。这些问题共同导致长时间无法实现CAN外设CAN帧发送功能。

1 PS-CAN外设系统

为了高效定位vivado软件系统的问题,需要在前面正常运行的工作上做出修改,添加CAN外设。虽然小梅哥例程中没有CAN总线功能,但是可以参考I2C接口等近似内容。

添加PS-CAN外设后,成功Update硬件。在编译应用canps-polled-example 例程后,运行正常。为了判断CAN通道是否成功发送CAN帧,可以从以下几个方面思考。

第一:通过LED来指示程序运行情况,需要补充GPIO初始化及控制内容。但是,LED调试效率太低,尤其后期的程序规模比较大时
第二:添加串口,打印运行程序节点状态,方便定位程序。需要在ZYNQ系统中添加uart外设。明确如何打印,增加系统不确定性。
第三:使用逻辑分析仪监测TTL电平信号,这种方式帮助判断程序是否成功收发协议数据,但是需要我了解逻辑分析仪的CAN使用。由于手边没有CAN分析仪,因此使用野火开发板发送CAN帧。
第四:仿真模式下,通过变量和Memory区更加高效定位大型程序。

在分析中,思路才慢慢清晰。纠结感显著减少

1.1串口打印uart功能

考虑重新搭建一个串口和LED的系统,这样能够在不影响原系统的情况下,实现特定内容。后来,又考虑到只是在PS端修改参数,不用像PL端一样有大的调整。在Update硬件系统后,马上就出现让人懵逼的问题。

example导入错误

众所周知,vitis的example功能是一个很好的示例工具,帮助学习不同外设的驱动方法。问题在于,这次添加uart之后,让人意外得出现导入Failed
在这里插入图片描述
米联客这篇文章提出了一个重要问题,即uart参数配置中的MIO口和电压等级。文中指出uart电压为1.8V,并且上端的BANK 1 IO Voltage需要设定为1.8V。此外,我发现,当选择MIO为14或者15时,无法选择1.8V;选择MIO为46、47则可行。因此说明不同MIO的电压水平是有差异的。这个发现会加强后期参数配置的重视程度。

虽然进行了上述调整,但是Vitis仍然无法打开例程。与此同时,BSP设置中modify BSP Setting同样出现类似问题。这似乎说明一切仍然是Vivado系统搭建的问题。奇怪的是,次日早上我重新打开Vitis,已经能够顺利运行Uart的example。这种现象说明,Vivado或者Vitis的软件稳定性不好,系统做出的修改无法马上同步。目前还无法确定,是否是前面提到的1.8V修改设置同步影响。由于目前主要目的是使用uart发送信息,就暂时搁置这个问题。【值得注意的是,以后碰到类似问题,可以尝试重启
在这里插入图片描述
不过,运行程序后串口终端并没有出现任何字符,这让人非常疑惑。

在这里插入图片描述

串口终端错误

随后,我查阅了FPGA达芬奇开发板的microblaze uart串口例程,发现工程主要配置了终端参数。这篇文章则提醒,需要调整STDOUT的值,这个值就是串口的基地址值。不过修改之后,任何没有效果。

#define STDIN_BASEADDRESS  0xE8800000
#define STDOUT_BASEADDRESS 0xE0000000

后来我发现可以修改BSP配置,入口在图中位置。图中可以看到stdout可以修改Value,修改为ps7_uart_0。遗憾的是,仍然无法实现串口字符输出。值得说明的是,BSP的设置在后期以太网使用频率也较高。
在这里插入图片描述
回顾过去的流程,我意识到是没有理解COM3的工作机制。换言之,COM3的字符输出本质是开发板通过USB输出给笔记本,笔记本将USB驱动接收的数据发送给Vitis的terminal而已。这意味着,在按照米联客观点做出调整时,我忽略了小梅哥开发板本身串口的位置,即MIO口不是随意设置的,需要对应到相应的USB转串口器件上。

按照小梅哥板子修改了BD系统参数后,Vitis再次出现无法导入example问题。顺着上章思路,我关掉Vivado和Vitis,发现example问题解决。这再次证实了Vivado本身的问题,以后出现类似问题,重启电脑策略还是可行的。
在这里插入图片描述
重启软件后,我查阅程序发现STDOUT的地址自动调整为Uart1的地址值。在Buidl例程之后,COM3也如期出现相应的字符,真是令人开心的结果。
在这里插入图片描述
不过,我测试这个Uart的目的主要是直接应用在例程中,但是直接在程序中使用print函数是无法直接打印字符,需要进行串口的初始化配置。奇怪的地方在于,我已经将例程基本复制过来,例程也能使用,但是COM3就是没有显示。程度下载后,可以看到LED是正常闪烁,说明前面的Uart的LookUpConfig以及XUartPs_CfgInitialize是正常工作的,否则进入if条件语句。奇怪的是,Uart面板却没有任何反应。重启软件也没有什么效果!

//初始化GPIO驱动结构体
	CfgPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
	XGpioPs_CfgInitialize(&GPIO, CfgPtr ,CfgPtr->BaseAddr);
	XGpioPs_SetDirectionPin(&GPIO,7,1);
	XGpioPs_SetOutputEnablePin(&GPIO,7,1);

	//初始化PL GPIO
	XGpio_Initialize(&xGpio,XPAR_AXI_GPIO_0_DEVICE_ID);
	XGpio_SetDataDirection(&xGpio,1,0);

	//XGpioPs_SetDirection(XPAR_PS7_GPIO_0_BASEADDR,1);

	/*
	 * Initialize the UART driver so that it's ready to use
	 * Look up the configuration in the config table and then initialize it.
	 */
	UartCfg= XUartPs_LookupConfig(XPAR_PS7_UART_1_DEVICE_ID);
	if (NULL == UartCfg) {
		return XST_FAILURE;
	}

	Status = XUartPs_CfgInitialize(&Uart_Ps, UartCfg, UartCfg->BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	XUartPs_SetBaudRate(&Uart_Ps, 115200);

	while (SentCount < (sizeof(HelloWorld) - 1)) {
			/* Transmit the data */
			SentCount += XUartPs_Send(&Uart_Ps,
						   &HelloWorld[SentCount], 1);
		}
	xil_printf("Uartps hello world Example Failed\r\n");

串口初始化错误

奇怪之处有三点。首先Uart的初始化只有查找基地址、初始化以及设置braud三个步骤。如此简单的流程,检查之后也没有发现问题。其次,LED灯能够正常闪烁,说明整个程序能够正常运行,没有进入if语句的Failure逻辑。最后Example例程能够正常发送串口数据,COM3能够显示,说明硬件系统和BSP能够正常工作。即使调整语句顺序,将初始化逻辑放在前面,仍然没有效果。这种情况让人怀疑Vitis软件系统的编译出现Bug,这种观点的意义只是提醒我需要更换为SDK软件。值得指出的是,这种例程套用问题非常普遍,广泛存在于大型程序中,比如以太网Lwip example。前期解决这种小问题,能够更好避免相关的问题。

思路进入死胡同,必须另辟蹊径。调试是定位软件问题的有效办法,但是我还没有充分研究过。因此,我重新学习了Vitis软件debug基本操作,准备运用单步执行定位串口问题

在调试过程中,观察到一些奇怪现象:

现象1:单步执行存在无法进入XUartPs_SetBaudRate函数的情况。这种情况不普遍,前期出现过几次,在进行了几次操作之后,这种现象就不见了!

现象2:uart1程序调试进入XUartPs_SetBaudRate函数时,XSCT console显示异常。在进入if判断程序后,程度似乎就跑飞了。程序没有运行至XUartPs_ReadReg函数,Resume变灰无法点击,等一下才正常是怎么回事(即程序直接停留在return处)?这说明两个红框之间程序发生异常。
在这里插入图片描述
现象3Memory窗口中,所有寄存器显示内容为**????。虽然单步运行操作下能够正常进入函数,变量也已经赋值,但是内存单元就是没有数据。为了更好评估这个问题,我考虑将前面正常运行的uart example运行下,看看此外的memory是否也为??????。这个实验能够帮助判断是否问号**现象与uart功能是直接关联的。
在这里插入图片描述
实践结果表明,uart example例程同样出现这种现象。这说明,以上三个现象与uart串口的正常状态没有直接关系。这种奇怪情况让人怀疑是Vitis的软件本身所致,因此有必要使用SDK软件重新测试整个流程,从而明确这些问题发生的原因。考虑2-7号早上直接下载运行百度网盘下载好的Vivado2018安装包,测试一下这个版本里的uart程序是否正常运行。

电源供电

在应用vivado2018测试例程时,出现了如下错误。这篇文章提出,小梅哥板子供电可能影响板子的程度行动,按照要求我将电源切入到DC而非USB时,程度果然能够正常运行了。这意味着前面许多问题的产生,电源是一大原因。
在这里插入图片描述

Vivado2018版本兼容

实践表明,Vivado2018马上就实现了相关的功能。代码简单,基本采用Vivado202同样的逻辑。这意味着,以后还是以2018Vivado软件版本为主,方便定位问题。

//初始化gpio ps
	gpioCfg=XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
	XGpioPs_CfgInitialize(&gpiops,gpioCfg,gpioCfg->BaseAddr);
	XGpioPs_SetDirectionPin(&gpiops,7,1);
	XGpioPs_SetOutputEnablePin(&gpiops,7,1);

	//初始化uart
	uartCfg=XUartPs_LookupConfig(XPAR_PS7_UART_1_DEVICE_ID);
	XUartPs_CfgInitialize(&uartps,uartCfg,gpioCfg->BaseAddr);
	XUartPs_SetBaudRate(&uartps,115200);
	while(1)
	{
		//led间隔1秒闪烁
		XGpioPs_WritePin(&gpiops,7,1);
		sleep(1);
		XGpioPs_WritePin(&gpiops,7,0);
		sleep(1);
		print("uart test \r\n");

	}

程序运行的一刻,内心比较激动!没有想到前期大量问题是软件本身造成的。既然Vivado2018软件稳定性好,决定后期选择这个软件搭建CAN外设系统。
在这里插入图片描述

CAN帧多次触发

在用vivado2018成功搭建好系统后,CAN例程串口正常输出内容。但是通过逻辑分析仪获取数据时,却一直出现多次触发的情况。下图显示,在下降沿激励下,逻辑分析仪开始记录数据。虽然调整为单次触发,同时软件也是一次执行,可是为什么引脚会收到多个数据?帧解码数据全部为1,说明这个数据存在问题。难道是波特率设置问题?由于没有CANBUS工具,所以无法高效调试相关功能。
在这里插入图片描述
在这里插入图片描述
这篇文章提出CAN-CLK范围是8-24 Mhz。但是在BD参数配置页面,CAN-CLK默认为100MHZ。如果以这个为出发点,确实可以存在问题,因此我首先考虑将这个值设定为24Mhz。

基于目前的条件限制,可以聚焦CAN-PL功能调试。

Vivado编译效率较慢

相比2022版Vivado,2018版Vivado的效率似乎非常慢。修改CAN-CLK参数后,耗费几个小时才编译成功,好像软件死机一样。右上角的圆圈一直转,让人着急(后发现是设置问题)。
在这里插入图片描述

逻辑分析仪重复解码

为什么下载CAN程序后,逻辑分析仪也会发生变化 ?CAN示例程序的主要功能就是发送一个CAN帧,tx IO口是MIO11。但是当逻辑分析仪引脚连接插针,程序运行后,却出现重复多次触发的现象。换言之,原本例程发送一个CAN帧后就会停止运行,但是图中却说明CAN外设持续一直在发送CAN帧。前面提到波特率,但是修改为24Mhz后并没有什么问题。同时,野火开发板是可以成功发送CAN帧信号的。这意味着是ZYNQ的什么环节出现的一个问题。

为了增强这个问题的现实感,我考虑在这个程序中添加GPIO相关的功能,并且CAN帧只有在接收到按键点击后,才发送CAN帧。通过这种主动设计,看看例程和zynq现象之间的关系是什么。

突然意识到,CAN协议有没有成功发送而回传的功能,这个功能就会造成CAN一直发送的情况。前期学习stm32就遇到这个问题,也就是关闭自动发送功能。CAN协议的特点在于,协议中的ACK位需要获得其它节点的信号,否则默认是发送错误CAN帧。这里可以得出两点:1逻辑分析仪是可以分析CAN帧,但是由于没有内部的CAN结构,所以不会回发ACK信号。2分析仪的重复现象就是底层CAN协议功能造成的,但是第一个CAN帧的解析就出现错误,说明本身zynq的CAN帧发送是出现问题。

为了验证这个观点,可以考虑重新测试一个野火板子。通过TTL引脚观察信号,看看是否会出现重复接收的情况。此外,看看是否首个发送的CAN帧没有问题。
在这里插入图片描述

1.2 逻辑分析仪-CAN协议分析

在梦源官方这篇文章中,详细说明了如何使用逻辑分析仪分析CAN信号。野火霸天虎开发板发送CAN信号帧,逻辑分析仪成功捕捉。虽然逻辑分析仪没有CAN分析仪操作方便,功能丰富,但是当前阶段基本能够满足需要。
在这里插入图片描述

电路连通

前面在使用逻辑分析仪时,很快就判断出逻辑分析仪可用。但是因为存在CAN帧重复发送的问题,我又测试了下野火开发板是否能够正常发送CAN帧时,又再次出现无法解析的问题。

后来发现,似乎是没有按下电源开关所致。因为看到板子上点亮了两个红灯,所以觉得板子没有问题,没有想到这只是仿真器JTAG接口电源。当我在野火程度之上添加LED,发现程序没有点亮之后,我就开始定位问题。在看到按下按键后,LED才开始亮灭,我才意识到真正的问题。

禁止报文自动重传

接收CAN帧的ID和数据都没有问题,只是同样存在CAN帧的重复发送问题。
在这里插入图片描述
stm32初始化程序中,可以设定禁止报文自动重传功能。在打开这个功能后,确实发现不再发生重复接收CAN帧的情况。这说明可以考虑关闭zynq的CAN的这个功能

在这里插入图片描述
在将逻辑分析仪的信号线接入STM32开发板的PB13 TTL CAN TX接口时,逻辑分析仪成功接收CAN帧信号,说明ZYNQ确实没有成功发送CAN帧。此外,在关闭禁止报文自动重传功能后,逻辑分析仪再次出现CAN帧重复接收问题,再次印证ZYNQ前面出现问题确实是这个功能造成的。不过让人奇怪的是,vitis库文件中没有看到特定头文件说明。如何没有这个功能,就需要CAN分析仪来完成测试功能。
在这里插入图片描述

电压阈值

电压阈值是否存在影响?这篇文章提出要CAN收发器连接,但是我在stm32上测试,发现不用这种操作(使用CAN收发器和后,CAN帧发生问题仍然存在)。

猜想是波特率问题,但是按照100MHz和40Mhz配置,都没有达到理想的CAN帧解析目的。

zynq NART无法设置

DS798提到CAN IP包含自动重发功能。但是数据手册以及库文件中都没有提到关闭此功能的选项。这会影响CAN帧调试的效果。
在这里插入图片描述

逻辑分析仪解码失效

从逻辑分析仪图像可知,图形有三个特点。第一层,时间轴最大时,可以看到周期出现的逻辑信号段,这是自动重发功能所致。第二层,这段表面上看是CAN帧逻辑段;第三层,这层才是实际CAN帧解析的内容。矛盾地方在于,重复逻辑段中不是按照CAN帧来解决,就像波特率比较小,一段CAN帧信息硬是被分为好几段。虽然前期我怀疑是波特率影响,但是调整之后,逻辑分析仪没有太大变化。
在这里插入图片描述
前面设置波特率为100KHz,当调整波特率为4KHz后,单个CAN帧解析的长度基本与周期逻辑信号段的长度相同。这说明TTL的tx口发出的逻辑信号确实是发出的信号,但是特定波特率出现了问题。我选择作用Lookback模式判断一下是否内部的协议接收是正常的,从而能够将问题定位在物理层还是数据链路层。
在这里插入图片描述
此外,CAN回环测试是成功的,这说明内部的发送机制是没有问题的。关键可能是哪里的链路出现问题,或者波特率设置确实出现了问题。

zynq时钟系统

这篇文章介绍了zynq的时钟系统,让我对vivado的clock configuration的基本概念有基本了解。下图配置页面中的方框内数字和比例关系基本清楚,主要是调整CAN时钟为40Mhz。
米联客在例程中也只是设定了CAN的clock,没有修改其它参数。遗憾的是,实际调试仍然没有效果。
在这里插入图片描述

1.3 CAN BUS分析仪+CAN收发器

在CAN BUS分析仪和CAN收发器的帮助下,数据链路连接好。但是,下载程序后,ECanTool上位机没有任何反应。波特率识别没有效果:
在这里插入图片描述
为了严谨,首先用野火开发板测试CAN-BUS+CAN收发器没有问题。在运行程序时,selftest函数没有输出错误。但是串口信息显示enter mode error,说明CAN外设无法进入正常模式发送CAN帧这篇文章提到,官方提供的CAN驱动主要是应用于EMIO模式下,不过帖子下面没有提供解决办法,注册账号留言也没有成功。这篇文章提到波特率的问题,但是也强调自己使用了EMIO功能。基于此,有必要考虑调整CAN外设的输出模式。

结果我发现,前期无法进入normal mode是单次。因为while逻辑的存在,现在CAN无法进入normal mode,就会一直输出错误信息。说明无法进入Normal mode是长期状态,一起处于配置模式。

驱动兼容

上面文章指出CAN驱动与EMIO的关系,可以联想到vivado最新版本的驱动也许能够解决相关问题。因此zynq7020的CAN外设与vivado2018的CAN驱动可能存在不兼容问题

在这里插入图片描述

//测试can 功能自测
	status = XCanPs_SelfTest(&Can);
	print("self test point\r\n");

	if(status != XST_SUCCESS)
	{
		print("self test error:can controller no wrong\n\r");
	}

	//配置波特率
	XCanPs_EnterMode(&Can, XCANPS_MODE_CONFIG);
	XCanPs_SetBaudRatePrescaler(&Can,3);
	XCanPs_SetBitTiming(&Can,3,2,15);

	//发送CAN数据
	XCanPs_EnterMode(&Can,XCANPS_MODE_NORMAL);
	while(XCanPs_GetMode(&Can) != XCANPS_MODE_NORMAL)
	{
		print("normal mode error\r\n");
		sleep(1);
	};

debug调试-memory显示????

考虑到驱动层面的问题,所以有必要通过进入仿真模式,看看CAN外设控制器的寄存器是否按照预期进入特定标志位。
在这里插入图片描述
进入debug模式,SDKmemory又是显示为问号。这个现象导致无法分析外设寄存器的情况。这篇文章提到自己使用的system debugger功能,而非目前使用的GDB debugger功能。在切换debugger为前者后,memory顺利显示特定值。这说明SDK和vitis软件兼容性不足,需要切换不同模式使用。
在这里插入图片描述
在这里插入图片描述
实际寄存器值也表明,CAN外设在enter mode函数作用下,并没有顺利进入normal mode模式。

CAN无法进入normal mode

此贴是唯一与我遇到的问题直接关联的,但是帖子没有回复。CAN能够通过CAN selftest测试,可以进入lookback模式和config模式,却无法进入normal模式,让人疑惑。

此帖也指出了这个问题,发现是收发器进入SB模式影响。考虑到这个影响,于是考虑用野火开发板实际测试一下刚接入的can收发器和CAN-BUS
其次,这个帖子中提到CAN0 MIO-CLK以及可能存在的CAN0和CAN1区分。·

使用野火CAN收发器,ECanTool可以顺利接收野火板子发送的CAN帧。但是,当接入TJA1050收发器时,ECanTool没有反应(也没有LED提示)。换个CAN收发器,结果仍然无法接收CAN帧。奇怪的是,换回野火CAN收发器,还是不能接收CAN帧。ECanTool显示红色的错误报警。整个过程,只是换了收发器,但是板子却无法使用。可能是还没有断开刚刚接入的CAN收发器引脚,导致PB12-PB13有两条路径进入CAN收发,这是拆除之后没有反应。
在这里插入图片描述
在这里插入图片描述
重启ECanTool后,上位机又正常工作,这说明软件稳定性不好。重启软件后,TJA1050的收发器正常工作,SN65HV收发器出现重复发送的情况。选择TJA1050收发器进行后续的实验。

vivado配置与库文件更新错误

此贴直接提出特定时钟和位时序对CAN正常工作的影响。在vivado调整时钟为80Mhz后,需要确保硬件更新成功。在查看SDK驱动文件时,发现xparameters.h文件中时钟频率仍然是10MHZ。这个频率即不是vivado提供的初始值100Mhz,也不是vivado时钟配置页面的40Mhz。
在这里插入图片描述
更让人疑惑的是,在更新硬件信息时,每次都会出现一个新的hw_platform_1。我以前习惯性关掉,但是这次更新后,我查看了相关的文件。发现xparameters.hps_init.html和vivado配置页面数据存在冲突:设置的时钟不同,打开的CAN外设也没有显示在文件中。后来发现,有可能是在generate output product操作时,把force to update的内容当成bitstream生成。因此 后期经常没有直接点击generate bitstream。结果发现,文件目录中的hdf文件日期确实更新为此刻。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
以上现象说明vivado硬件层SDK软件层存在更新同步问题。找到工作文件目录,可以看到**.hdf**硬件工程描述文件的最近修改日期为昨天。这说明今天刚刚导出的文件,被修改为旧版。

在这里插入图片描述
首先按照xparameters.h文件输出的10Mhz来配置波特率。令人困惑的是,程序完全无法运行。注释掉while条件语句,LED也无法闪烁,说明程序出现了一些根本问题。猜测可能跟删除hw_platform_0文件有关,只留下一个文件。换言之,转了一圈,发现最简单的GPIO功能都失效了
在这里插入图片描述
考虑到以上文件的存在,准备重新采用vivado2020软件,寻找转机。结果表明,vivado2020和vitis比较准确同步了软件硬件层的内容。
在这里插入图片描述

assignment to int*语法错误

在编写CAN外设驱动程序时,出现assignment to int* from int makes pointer from integer without a cast错误。后来发现,一方面,**include **文件没有添加;另一方面,vitis的文件更新速度慢,刚修改的文件无法马上同步。重启vitis软件没有效果,剪切代码再复制才解决问题。可以用同样的操作解决后面的代码错误,说明vitis软件本身存在更新同步问题。

	//初始化canps
	CanPs0Cfg = XCanPs_LookupConfig(XPAR_XCANPS_0_DEVICE_ID);
	XCanPs_CfgInitialize(&CanPs0, CanPs0Cfg, CanPs0Cfg->BaseAddr);
	status = XCanPs_SelfTest(&CanPs0);
	if(Status != XST_SUCCESS )
	{
		print("can self test\r\n");
	}

CAN无法进入loopback模式

类似前面遇到的CAN无法进入normal模式,这个问题直接导致selftest函数都无法正常工作。此时CAN外设一起处于Config模式下。前期似乎也是这种问题,于是选择换vivado2018版本。但是现在又似乎碰到同样的问题,此时也不知道需要如何做出选择。有一种可能性就是,并非所有的IO都是可用的。但是封装文件中并没有表明两者的差异,这就很让人疑惑。
在这里插入图片描述
但是在查看文件时,突然发现T5和W6原来是小梅哥板对板的PL管脚,而非通用PL端GPIO接口
在这里插入图片描述
在选择EMIO引脚时,会注意BANK、特殊功能引脚(D18)、memeory byte group和HR等,因此选择G17和G18引脚做为CAN总线引脚。虽然不知道它们是否会影响板子的实际工作。这个发现也说明,EMIO与引脚映射的重要性,前期在stm32的CAN外设remap中也遇到相似问题。

H15  IO_L19P_T3_35            3                  35    NA            NA                  HR        NA
D20  IO_L4N_T0_35             0                  35    NA            NA                  HR        NA
E19  IO_L5N_T0_AD9N_35        0                  35    NA            NA                  HR        NA
D18  IO_L3N_T0_DQS_AD1N_35    0                  35    NA            NA                  HR        NA
G17  IO_L16P_T2_35            2                  35    NA            NA                  HR        NA
G18  IO_L16N_T2_35            2                  35    NA            NA                  HR        NA

可惜的是,仍然无法正常进入CAN0的Lookback模式。于是选择CAN1,进行同样的测试,但是更加奇怪的情况发生了。串口只打印了第一个print,没有打印selftest或者if条件语句里面的print函数。说明程序卡在某个while逻辑中,只有debug模式可以比较快定位。


	//初始化canps1
	print("canps1 test\r\n");
	CanPsCfg0 = XCanPs_LookupConfig(XPAR_XCANPS_0_DEVICE_ID);
	XCanPs_CfgInitialize(&CanPs0, CanPsCfg0, CanPsCfg0->BaseAddr);

	CanPsCfg1 = XCanPs_LookupConfig(XPAR_XCANPS_1_DEVICE_ID);
	XCanPs_CfgInitialize(&CanPs1, CanPsCfg1, CanPsCfg1->BaseAddr);
	status = XCanPs_SelfTest(&CanPs1);

			if(status != XST_SUCCESS )
			{
				print("can111 self test fail\r\n");
			}else
			{
				print("can111 selftese success\r\n");
			}

selftes程序跑飞

在运行上面的程序时,当程序进入到s32 XCanPs_SelfTest(XCanPs *InstancePtr)函数时,就出现程序跑飞情况。主要表现在,当将断点分别放在102行109行时,程序都能自动停住。但是,如果断点放置在113行时,程序无法自动停止。猜想重置CAN外设之后,如果获取外设的模式,CAN外设就会进入异常模式。
在这里插入图片描述
vitis中,有三个控件:resume、suspend和terminate等。当程序跑飞时,前面两个控件都为灰色,只有terminate才能停止程序。
在这里插入图片描述
在调试过程中,无法定位程序跑飞断点。观察到vitis有CAN和CAN_SYSTEM两个层级,每个层次都可以操作debug as模式。每种debug又都有GDB和TCF两种single application debug模式。联想到上次在sdk中,system debugger才能查看memory内容,说明这种选择是有必要的。
在这里插入图片描述在这里插入图片描述
但是,在选择调试工具时,发现system debugger相关功能会导致程序无法顺利进入main函数。程度会卡在_boot处,也就是没有启动。最后,几轮试用下来,最开始的调试工具也失效。于是不得不重启软件,看看是怎么回事。当重启软件前,看到串口发送信息,我猜想程序跑飞情况消失。于是又下载程度,看看效果。这次,程序正常运行。
在这里插入图片描述
虽然第一次获取状态时,模式获取失败。但是在while逻辑中添加延时后,CAN外设正常进入回环模式。这似乎说明while模式逻辑过快,可能CAN外设来不及修改状态值。也可能是内部缓存机制影响,或者是zynq初始配置速度为-1影响,总之程序正常运行成功。总之,通过在while逻辑中添加延时函数来等待GetMode函数,CAN外设顺利进入预期模式。

	XCanPs_EnterMode(InstancePtr, XCANPS_MODE_LOOPBACK);
	GetModeResult = XCanPs_GetMode(InstancePtr);
	while (GetModeResult != ((u8)XCANPS_MODE_LOOPBACK)) {
		GetModeResult = XCanPs_GetMode(InstancePtr);
		xil_printf("in selftest 2:%d\r\n",GetModeResult);
		sleep(2);
	}

随后,我又添加了如下逻辑,串口打印正常。这说明CAN0已经能够正常发送CAN帧。但是ECanTool仍然没有发现接收到任何CAN帧,重启软件也没有反应。尝试自动识别波特率,仍然没有接收到CAN帧。联想到某个帖子,可能需要强制设定波特率,于是重启软件。

	//初始化canps0
	print("canps1 test\r\n");
	CanPsCfg0 = XCanPs_LookupConfig(XPAR_XCANPS_0_DEVICE_ID);
	XCanPs_CfgInitialize(&CanPs0, CanPsCfg0, CanPsCfg0->BaseAddr);

	status = XCanPs_SelfTest(&CanPs0);

	if(status != XST_SUCCESS )
	{
		print("can000 self test fail\r\n");
	}else
	{
		print("can000 selftese success\r\n");
	}

	//初始化canps0
	CanPsCfg1 = XCanPs_LookupConfig(XPAR_XCANPS_1_DEVICE_ID);
	XCanPs_CfgInitialize(&CanPs1, CanPsCfg1, CanPsCfg1->BaseAddr);
	status = XCanPs_SelfTest(&CanPs1);

			if(status != XST_SUCCESS )
			{
				print("can111 self test fail\r\n");
			}else
			{
				print("can111 selftese success\r\n");
			}

	//配置CAN0波特率
	XCanPs_EnterMode(&CanPs0, XCANPS_MODE_CONFIG);
	while(XCanPs_GetMode(&CanPs0) != XCANPS_MODE_CONFIG)
	{
		sleep(1);
		print("getmode test1111 error\r\n");
	}

	XCanPs_SetBaudRatePrescaler(&CanPs0, 9);
	XCanPs_SetBitTiming(&CanPs0, 2, 1, 12);

	//配置CAN0正常模式,发送CAN帧
	XCanPs_EnterMode(&CanPs0, XCANPS_MODE_NORMAL);
	while(XCanPs_GetMode(&CanPs0) != XCANPS_MODE_NORMAL)
		{
			print("getmode test2222 error\r\n");
			sleep(1);
		}

	TxFrame[0] = (u32)XCanPs_CreateIdValue((u32)2000U, (u32)0U, (u32)0U, (u32)0U, (u32)0U);
	TxFrame[1] = (u32)XCanPs_CreateDlcValue((u32)8);

	FramePtr = (u8 *)((void*)(&TxFrame[2]));

	for(i = 0; i<8;i++)
	{
		if(*FramePtr != 0U){
		*FramePtr = (u8)8;
		FramePtr++;
		}
	}

	status = XCanPs_Send(&CanPs0, TxFrame);
	if(status != XST_SUCCESS)
	{
		print("send error \r\n");
	}else
	{
		print("send success \r\n");
	}

	while(1)
	{
		XGpioPs_WritePin(&GPIO,7,1);

		XGpio_DiscreteWrite(&xGpio,1,1);
		sleep(2);

		print("test\n\r");
		XGpioPs_WritePin(&GPIO,7,0);
		XGpio_DiscreteWrite(&xGpio,1,0);

		sleep(2);
		status = XCanPs_Send(&CanPs0, TxFrame);
		if(status != XST_SUCCESS)
			{
				print("send error \r\n");
			}
	}

ECanTool登录页面配置

后来在登录页面,我才发现问题。**添加设置页面包含CAN1和CAN2的设置,每次我都是默认设置CAN1,但是电路是连接CAN2。当我将配置对象调整为CAN2,上位机正常接收到CAN帧!!!

在这里插入图片描述
上位机页面中,CAN ID是正确的,但是数据存在问题。因为配置的8个数据全为8,但是上位机中第三个数据后就变成其它数据了。
在这里插入图片描述

1.4 其他问题

hdf文件更新

sdk的软件开发是基于vivado生成的硬件hdf文件。今早在导入hdf文件时,发现一个奇怪的现象。HDF文件的修改日期是2-7,而非2-15。在export hardware选择页面,有个include bitsteam选项。当点击这个选择后,hdf文件的修改时间才发生变化。这让人不禁怀疑,前期许多问题可能是hdf文件没有更新造成的。
在这里插入图片描述
在这里插入图片描述

vivado编译太长时间

在点击generate output product选项时,vivado2018编译时间似乎过长。昨天晚上开始编译,今早还没完成。但是今早当然点击右上角的编译指示字符时,发现可以点击某个内容,比较快实现编译。说明前期低效编译是没有操作好造成的。即点击detail后,再点击force out of date
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

xilinx平台无法发帖

许多zynq的问题都可以在xilinx官方平台找到,但是在注册账号时发现,这些平台只有官方人员或者会员才能发帖求助。以下是sign in页面提示,说明需要官方账号才能登录(salesforce是一家软件公司)。
在这里插入图片描述

编译同步

由于vivado和vitis可能存在的编译同步问题,在点击相应操作时,需要查看界面信息。比如vivado的report页面说明output product生成时间,或者vitis的特定文件说明硬件系统信息。
在这里插入图片描述

代码文件修改同步

任何修改未保存的文件,其左上角会一个星号。每当修改文件会,习惯性CTRL+S能够及时更新修改,避免出现将没有修改的结论当成实际情况。
在这里插入图片描述

上拉类型配置

在定位CAN无法进入normal模式问题时,发现IO Ports页面中包含Pull type选项。这个选项中有上拉、下拉、保持和NONE四个选项,默认是NONE选项。考虑如下几个方面:1资料说明,CAN总线不用上下拉;2以前正常发送CAN帧时也没有设置上拉类型。所以认为这个设置目前没有意义。
在这里插入图片描述

2写作表达

1一个句子尽量只有两句以内,最多三句。
2减少定语
3注意逻辑词关联。
4问题意识和观点意识基本与技术兴趣结合起来:写代码时,碰到问题会觉得发生新的踏脚石;写程序时觉得是在表达一种小的观点,需要循序渐进提升这种观点意识。

  • 44
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值