XiLinx SDK FreeRTOS学习记录(二)——UART与蓝牙收发中的BytesNum清零问题

问题简介

上一篇中我们说到我们将接收到的字节数一并传回,然后只把这个字节数打印出来,这就涉及到一个接收字节数清零的问题,因为要将所有数据都放在一个数组中,因此必须要有一个变量来记录上次接收到第几个字节了,所以只能在字节接收完毕后才可以将其清零而且必须清零。在原来的方案中,字节数清零是放在XUARTPS_EVENT_RECV_DATA分支中来做的,并且是在发送数据到队列之前,但是若是要将字节数传回就需要在打印之后才清零,也就是说必须要在发送数据到队列之后才可以清零,这里就衍生了两种方法。

方法一

第一种方法是将字节数设置为一个全局变量,打印时就可以读取字节数来决定打印多少字节,然后在打印完成后将字节数清零。

方法二

第二种方法是将发送数组改为发送一个结构体,这个结构体中包含了数组和字节数,当接收函数从队列中接收到结构体之后就可以读取到字节数了,然后在中断服务函数中,发送数据到队列之后就可以将字节数清零了。注:这种方法还没有实测效果。

明日测试需要修改的地方:

  • RTOS_bsp\ps7_cortexa9_0\include\xuartps.h
typedef void (*XUartPs_Handler) (void *CallBackRef, u32 Event,
				  u32 EventData, u32 Remain);
  • RTOS_bsp\ps7_cortexa9_0\libsrc\uartps_v3_7\src\xuartps.h
    修改代码同上。

  • RTOS_bsp\ps7_cortexa9_0\libsrc\uartps_v3_7\src\xuartps_intr.c

static void ReceiveDataHandler(XUartPs *InstancePtr)
{
	/*
	 * If there are bytes still to be received in the specified buffer
	 * go ahead and receive them. Removing bytes from the RX FIFO will
	 * clear the interrupt.
	 */
	 if (InstancePtr->ReceiveBuffer.RemainingBytes != (u32)0) {
		(void)XUartPs_ReceiveBuffer(InstancePtr);
	}

	 /* If the last byte of a message was received then call the application
	 * handler, this code should not use an else from the previous check of
	 * the number of bytes to receive because the call to receive the buffer
	 * updates the bytes ramained
	 */
	if (InstancePtr->ReceiveBuffer.RemainingBytes == (u32)0) {
		InstancePtr->Handler(InstancePtr->CallBackRef,
				XUARTPS_EVENT_RECV_DATA,
				(InstancePtr->ReceiveBuffer.RequestedBytes -
				InstancePtr->ReceiveBuffer.RemainingBytes),
				InstancePtr->ReceiveBuffer.RemainingBytes);
	}

}
  • RTOS_bsp\ps7_cortexa9_0\libsrc\uartps_v3_7\src\xuartps_intr.c
static void ReceiveTimeoutHandler(XUartPs *InstancePtr)
{
	u32 Event;

	/*
	 * If there are bytes still to be received in the specified buffer
	 * go ahead and receive them. Removing bytes from the RX FIFO will
	 * clear the interrupt.
	 */
	if (InstancePtr->ReceiveBuffer.RemainingBytes != (u32)0) {
		(void)XUartPs_ReceiveBuffer(InstancePtr);
	}

	/*
	 * If there are no more bytes to receive then indicate that this is
	 * not a receive timeout but the end of the buffer reached, a timeout
	 * normally occurs if # of bytes is not divisible by FIFO threshold,
	 * don't rely on previous test of remaining bytes since receive
	 * function updates it
	 */
	if (InstancePtr->ReceiveBuffer.RemainingBytes != (u32)0) {
		Event = XUARTPS_EVENT_RECV_TOUT;
	} else {
		Event = XUARTPS_EVENT_RECV_DATA;
	}

	/*
	 * Call the application handler to indicate that there is a receive
	 * timeout or data event
	 */
	InstancePtr->Handler(InstancePtr->CallBackRef, Event,
				 InstancePtr->ReceiveBuffer.RequestedBytes -
				 InstancePtr->ReceiveBuffer.RemainingBytes, 
				 InstancePtr->ReceiveBuffer.RemainingBytes);

}
  • 还有一些修改忘记了,但是会报错,可以根据报错直接修改。