S32K148自动驾驶赛车通信模块搭建

第一次写文章,也是帮助自己梳理一下项目的框架吧,如果有什么不准确的地方也欢迎指出。

背景

实现自动驾驶赛车MCU之间的稳定通信,其中NXP S32K148将作为主要的MCU来检测赛车状态以及发布命令,通信协议将使用CAN,上位机Jetson Xavier与S32K148的通信目前将基于UART,测试无误后尝试接入CAN网络。

通信协议

主要的通信协议,未来还会加入RES(remote emergency signal)、心跳检测等。

FreeRtos 下的串口收发

串口配置:

波特率为115200

配置完毕后

首先老套路,开发板初始化

CLOCK_DRV_Init(&clockMan1_InitConfig0);
PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr);

 初始化完后设置freeRtos的串口收发任务,并开启scheduler

UART_task_setup();
vTaskStartScheduler();

void UART_init(){
	LPUART_DRV_Init(INST_LPUART1, &lpuart1_State, &lpuart1_InitConfig0);
	LPUART_DRV_InstallRxCallback(INST_LPUART1,uart_callback,NULL);
}

static void UART_recieve_task(void *pvParameters){
    //防止warning
	(void) pvParameters;

    /*模仿的例子*/
	uint32_t bytesRemaining;
	status_t status;

	const TickType_t UART_task_delay = pdMS_TO_TICKS(50UL);

	LPUART_DRV_SendData(INST_LPUART1,"UART init",10);

	while(1){
		LPUART_DRV_ReceiveData(INST_LPUART1,uart_rec_buf,1U);

		while(LPUART_DRV_GetReceiveStatus(INST_LPUART1,&bytesRemaining) == STATUS_BUSY);

		status = LPUART_DRV_GetReceiveStatus(INST_LPUART1, &bytesRemaining);

		if(status != STATUS_SUCCESS){
			LPUART_DRV_SendDataBlocking(INST_LPUART1, (uint8_t *)errorMsg, strlen(errorMsg), TIMEOUT);
			break;
		}

		bufferIdx++;
		uart_rec_buf[bufferIdx] = 0U;

	    LPUART_DRV_SendData(INST_LPUART1, uart_rec_buf, bufferIdx);

	    bufferIdx = 0U;

		LPUART_DRV_SendData(INST_LPUART1,"this is test\n",14);

		vTaskDelay(UART_task_delay);
	}

}

void UART_task_setup(){
	UART_init();

	xTaskCreate(UART_recieve_task,
	        		"UART",
	    			configMINIMAL_STACK_SIZE,
	    			NULL,
					UART_RECEIVE_TASK_PRIORITY,
	    			NULL);
}

此处没有用Blocking函数,因为发现Block函数会导致freeRtos调度卡死,原因尚不明确,不过看到有人用polling函数,或许值得一试。

中断回调函数

static void uart_callback(void *driverState, uart_event_t event, void *userData){
	(void) userData;
	(void) driverState;
	if(event == UART_EVENT_RX_FULL){
		/* The reception stops when newline is received or the buffer is full */
		if ((uart_rec_buf[bufferIdx] != '\n') && (bufferIdx != (BUFFER_SIZE - 2U))){
			/* Update the buffer index and the rx buffer */
			bufferIdx++;
			LPUART_DRV_SetRxBuffer(INST_LPUART1, &uart_rec_buf[bufferIdx], 1U);
		}
	}
}

结果成功在有换行符或者buffer快满时时发送存储的数据

FreeRTOS下 FlexCAN FIFO DMA接收

发现这些方面网上资料对这方面的解释都很模糊,大部分都只包括发送,所以只好自己学的不断测试,毕竟第一次做这方面

首先引脚配置,我只用到了CAN0口,使能FIFO,接收模式DMA,总体很简单。CAN2.0最多1MB/s,通常设置一半500kB/s防止负载过大造成传输错误

 初始化,记得初始化下DMA,目前只用监听RES系统发送的起始信号以及控制器的循环播报的信号,所以id table只有两个

static void flexcan_init(){
	FLEXCAN_DRV_Init(INST_CANCOM0, &canCom0_State, &canCom0_InitConfig0);

	for(int i=0; i<2; i++){
		id_filter_table[i].isRemoteFrame = false;      /*!< Remote frame*/
		id_filter_table[i].isExtendedFrame = false;    /*!< Extended frame*/
	}

	id_filter_table[0].id = 0x18C;
	id_filter_table[1].id = 0x70C;

	FLEXCAN_DRV_ConfigRxFifo(INST_CANCOM0,FLEXCAN_RX_FIFO_ID_FORMAT_A,id_filter_table);
	FLEXCAN_DRV_InstallEventCallback(INST_CANCOM0,can_callback,NULL);
	EDMA_DRV_Init(&dmaController1_State, &dmaController1_InitConfig0, edmaChnStateArray, edmaChnConfigArray, EDMA_CONFIGURED_CHANNELS_COUNT);

}

 然后在相应的监听任务内循环监听就行,FIFO内有数据后DMA会自动存入对应的buffer再触发中断的,目前没感受到这样的好处,可能由于项目不算大,对于can来说还是游刃有余的。目前想不出还可以干什么,等和别的组员进一步交流后再决定。

while(1){
		status = FLEXCAN_DRV_RxFifo(INST_CANCOM0,&recvMsg0);

		if(status == STATUS_SUCCESS){

		}

		vTaskDelay(flexcan_task_delay);
	}

 中断回调函数,收到对应的串口打印出来

void can_callback(uint8_t instance, flexcan_event_type_t eventType,
		uint32_t buffIdx, flexcan_state_t *flexcanState) {
	(void) buffIdx;
	(void) flexcanState;

	if(eventType == FLEXCAN_EVENT_DMA_COMPLETE){
		if(recvMsg0.msgId == 0x18C){
			if(recvMsg0.data[1] == 0x00){
				/*emergency*/
				LPUART_DRV_SendData(INST_LPUART1,"emergency\n",12);
			}else if(recvMsg0.data[1] == 0x03){
				/*start up*/
				LPUART_DRV_SendData(INST_LPUART1,"start up\n",10);
			}else if(recvMsg0.data[1] == 0x01){
				/*ready*/
				LPUART_DRV_SendData(INST_LPUART1,"ready\n",7);
			}
		}else if(recvMsg0.msgId == 0x70C){
			LPUART_DRV_SendData(INST_LPUART1,"init\n",6);
			FLEXCAN_DRV_Send(INST_CANCOM0, 9U, &data_info, start_up_message.msg_id, start_up_message.mb_data);
		}
		FLEXCAN_DRV_RxFifo(INST_CANCOM0,&recvMsg0);
	}
}

最终测试收发都很及时感觉还不错,高频率发送串口和CAN也没有报错,最终和视觉小组合并后再观测数据总线的承载能力吧,下一步就是等开会了。吐槽下,不得不说老外办事真的是慢啊

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值