【S32K】S32K144入门笔记(5) Lin (Lin组件)

1. 引言

上一篇介绍了S32K 的LinStack组件,其实这个组件正常用起来除了觉得有时候有些约束(可能主要还是因为自己对协议不够理解),稳定性倒没有其他问题。
直到有一次遇到一个超声波雷达,要发0x3c的ID,这个是属于诊断帧的,但在LinStack的配置界面没有找到诊断帧相关的设置,导致使用LinStack这个组件怎么也没法把0x3C的报文发出去了,还有之前遗留的一些问题,比如一直切换调度表的时候总是不成功,切换完就没有lin消息了。很多地方总觉得用起来很别扭,让我们痛定思痛,决定放弃这个组件,让组里另外一个小伙子改成了Lin组件。
期间一起看过这个模块,所以也简单记录一下吧,用做和上一篇 LinStack的对比。
比较简短,只是做一个记录。
【S32K】S32K144入门笔记(5) Lin (Lin组件)_第1张图片

2. Demo

Demo用的就是上一篇里提到的lin_master_baremetal_s32k144工程。
组件用的是Lin组件。
【S32K】S32K144入门笔记(5) Lin (Lin组件)_第2张图片
初始化就是调用LIN_DRV_Init来初始化lin接口,再调用LIN_DRV_InstallCallback注册一个回调。

/* Initialize LIN network interface */
LIN_DRV_Init(INST_LIN1, &lin1_InitConfig0, &lin1_State);

/* Install callback function */
LIN_DRV_InstallCallback(INST_LIN1, (lin_callback_t)CallbackHandler);

这里,LIN_DRV_Init调用的LIN_LPUART_DRV_Init接口,进而调用LPUART_Init,可见S32K的Lin也是用正常的串口模块接口,配置中断来实现的Lin接口。
使用串口来模拟Lin的操作,具体可以看Uart模拟Lin。

具体报文发送的流程是
1.
在主程序(Demo中是按键中断)中,调用 LIN_DRV_MasterSendHeader 接口来发送报头(间隔场 + 同步场 + PID)
2.
在回调函数中调用 LIN_DRV_SendFrameData 接口发送数,或调用LIN_DRV_ReceiveFrameData 接口接收数据。
这个步骤和我们之前 Lin时序图 里看到的是一样的。
【S32K】S32K144入门笔记(5) Lin (Lin组件)_第3张图片
在回调函数中,根据当前的时间来做对应的操作。
而这个注册的回调函数,会在LIN_LPUART_DRV_IRQHandler的结尾中调用,LIN_LPUART_DRV_IRQHandler又会在发送的中断结尾处调用。

   switch (lin1_State->currentEventId)
    {
        case LIN_PID_OK:

            /* Set timeout */
            LIN_DRV_SetTimeoutCounter(INST_LIN1, TIMEOUT);

            /* If PID is FRAME_SLAVE_RECEIVE_DATA, salve node will receive data from master node */
            if(FRAME_SLAVE_RECEIVE_DATA == lin1_State->currentId)
            {
                /* Call to Send Frame DATA Function */
                LIN_DRV_SendFrameData(INST_LIN1, txBuff1, sizeof(txBuff1));
            }

            /* If PID is FRAME_MASTER_RECEIVE_DATA, master node will receive data */
            if(FRAME_MASTER_RECEIVE_DATA == lin1_State->currentId)
            {
                /* Call to Receive Frame DATA Function */
                LIN_DRV_ReceiveFrameData(INST_LIN1, rxBuff, sizeof(rxBuff));
            }

            /* If PID is FRAME_GO_TO_SLEEP, salve node will go to sleep mode */
            if(FRAME_GO_TO_SLEEP == lin1_State->currentId)
            {
                /* Go to sleep mode */
                LIN_DRV_GoToSleepMode(INST_LIN1);
            }
            break;
            ...
            ...
    }

3. 实战

实现的需求和上一篇是一样的,还是这两个超声波雷达。

3.1 正常发送流程

使用流程和Demo一样,先初始化Lin,以及注册一个回调函数。
在这里插入图片描述
然后要给超声波雷达发送初始化Lin消息,这里与之前使用LinStack组件不同,因为这几条初始化报文只需要发一遍,之前使用LinStack组件的时候,需要切换调度表来做(但是实际使用的时候,切换调度表后总是会导致Lin总线不能正常收发,所以用了比较曲折的方法,暂时表过不提),在新的Lin组件里,就灵活很多,就像正常发送串口一样,直接在初始化的时候发送一次报文即可。
【S32K】S32K144入门笔记(5) Lin (Lin组件)_第4张图片
在init函数中发送对应的PID报头,然后在中断函数中发送对应的相应。
【S32K】S32K144入门笔记(5) Lin (Lin组件)_第5张图片

这样,即可完成初始化只发送一次的功能。

3.2 遇到的问题记录

使用Lin组件的时候,遇到了偶现Lin总线报文异常,然后Lin总线不能恢复的bug。
这个情况就很类似之前做SPI时遇到的情况,SPI(lpspi组件) 3.3节。所以也采取了相同的规避手段,当完成发送之后,再下一次发送时,检测到总线busy的话,就把总线abort然后deinit再init操作,做一个暴力的恢复。
【S32K】S32K144入门笔记(5) Lin (Lin组件)_第6张图片

你可能感兴趣的:(s32k)