garfield

使用XGATE在HCS12X系列单片机上实现LIN通信

0
阅读(5100)

1 引言.

本文介绍了使用HCS12X系列微处理器系列进行LIN通讯在创建主节点时所需要的底层驱动,超时管理以及调度功能。在该系列MCU上有2种可能的实现方式,即通讯功能既可以通过MCU核又可以通过XGATE协处理器实现。本文介绍后者,使用XGATE协处理器在HCS12X中实现LIN通讯功能。

1.1XGATE的基本内容.

XGATE是一个独立的外设协处理器,它能够自由利用片上RAM和外设,它的运行对主MCU内核不会造成负担。

XGATE是一个由事件驱动的RISC内核处理器。它有自己的指令集和代码。XGATE的代码和数据全都储存在片上RAM中。共享内存是XGATE各线程之间以及XGATE各线程与主MCU之间交换数据的主要方法。从用户的角度来看,HCS12X系列器件是一个多处理器环境,它提供硬件信号量用以不同在不同内核中运行的线程间的任务同步及资源管理。

XGATE执行线程作为对事件的响应,而事件则是由片上外设及MCU内核的中断模块发出的。

1.2LIN

本地互联网络是一个低功耗,低速率的汽车网络。它允许一个主器件和多个从器件来完成信号传输。每个帧最多可以包含八个字节,帧数据交换是通过调度表实现的。调度表被存储在主节点,主节点依照此表发起通信。主节点可能会有多个不同的调度表并可在它们之间切换,调度表详细说明了传输帧的标识符,以及从当前帧的开始到下一帧的开始的时间间隔(每一帧都会分配一段时间)。

  1. 软件结构

2.1功能

实现LIN通信的软件由一下三个独立的部分组成:

  1. 底层接收/发送驱动程序

这个驱动程序服务于单独的SCI通道来实现LIN通信的硬件接口,由于XGATE信号处理体系的特殊性质,即使是需要在一个芯片上实现多个的LIN节点,也只需要一个驱动程序。

        2.超时管理程序

 这个函数被由片上定时器的中断处理程序周期性的调用,函数的功能是检查所有LIN通道上有无超时状况。

        3.调度程序

这个函数管理调度表和发起帧传输。同超时管理程序类似,调度表程序也会在定时器的中断处理程序中被定期调用。

3.数据表示

  3.1数据结构

在实现上述函数之前,必须定义描述LIN节点和总线上传输帧的结构体。

(1) 帧描述符详细描述了调度表中一个成员的内存使用情况。它包含调度表中以下内容的详细描述:分配给这一帧的时间;帧内容包括ID,数据长度以及它本身的数据;帧传递方向(由主器件发送还是由从器件发送);指向下一帧描述符的指针。定义如下所示:

  typedef struct LINframe{

    struct LINframe * next_frame;

    tU16   time;

    tU08   data[8];

    tU08   Id;

    tU08   dir:1;

    tU08   len:4;

  }tLINframe;

 

2.LIN节点描述符提供了一个指向被当前节点使用的SCI外设的指针;一个指向调度表中当前处理帧的指针;一个给当前帧计时的时间变量;当前要传输或接收到帧的存储空间,这包括ID、数据长度、数据本身、校验和;发送/接收状态机的当前状态;一个用于超时检测的计时变量。结构体定义如下所示:

  typedef struct {

    tSCI *pSCI;

    tU16 checksum;

    tLINframe * frame;

    tU16 frame_time;

    tU08 data[8];

    tU08 Id;

    tU08 dir:1;

    tU08 len:4;

    tU08 state;

    tS08 timer;

  }tLINnode;

 

3.2调度表

调度表创建为环,每一个指向下一帧。调度函数会遍历这个环并在给定的时间内发送一帧数据。图一是一个带有四个帧的环的例子。

 

 

4.接收、发送驱动

HCS12X系列MCU提供了增强型的SCI模块,它支持在LIN网络中完成通信所需的扩展功能,例如冲突检测、扩展终止、唤醒。但是,SCI接口只支持字节层面的发送和接收,不提供帧层次上的抽象层。这意味着在帧层次上必须有对SCI中断事件响应的软件驱动。

因为仅看单个的字节不可能区分LIN帧内的数据字节,发送接收驱动程序必须实现一个状态机,它能够识别当前是哪一个字节正在被传输。详细工作过程见图二。

 

 

 

 

LIN帧数据交换由调度表启动,程序将LIN节点描述符的状态由空闲转位发送,并使能SCI发送缓冲区空中断。这会引发发送、接收驱动程序被执行,帧的传输也同时会启动。发送数据时驱动以空闲状态结束,接收数据时驱动以缓冲区满结束。在帧接收时如果校验和出错驱动程序进入接收错状态。如果总线上发生位错误事件,驱动程序进入位错误状态。

收发驱动程序具体实现如下:

表一

 

5.超时管理

超时管理程序的主要功能是确保所有的从机能够在调度表所分配的时间内响应,超时管理程序的另一个功能是确保系统能在从机故障时恢复。(例如从机根本不传送请求的数据或没有传输要求的字节数)。

另一方面,从主机到从机的帧传输不需要做超时检查,这是因为在这种情况下主机仅仅发送数据,并不需要从机配合。因此在主机方面不可能发生死锁。

为实现超时管理,LIN节点描述符包含了时间变量。在帧接收期间,它保存有一个时间值,所有的从机必须在此时间之内将下一字节发送出去而不会违背LIN协议。这个时间值由超时管理程序定时递减。如果这个变量减为零,这意味着从机没有及时做出响应,LIN节点处于超时状态。

5.1超时检测精度

LIN协议规范规定帧的最大传输时间为正常传输时间的140%。

图3

不同长度帧的正常传输时间和最大传输时间可以用上面的信息计算。正常帧传输时间与最大帧传输时间的差即是在不违反协议规则的前提下从机可用最长时间,尽管这为超时检测提供了一个极好的准则但是主机不能轻易的检测到响应间隔。基于测量响应时间的超时管理更容易实现,结果总结见表1:

 

帧字节数

TNOMINAL/bits

TMAXIMUM/bits

TRESP_MAX/bits

0

44

61.6

27.6

1

54

75.6

31.6

2

64

89.6

35.6

3

74

103.6

39.6

4

84

117.6

43.6

5

94

131.6

47.6

6

104

145.6

51.6

7

114

159.6

55.6

8

124

173.6

59.6

表1

超时管理程序的最优实现严重依赖于以调度表表示的应用要求。如果调度表给每个帧的传输都提供了充足的时间,超时管理就可以很轻松,对装载XGATE的影响也会较小。但是,如果调度表提供的时间接近于TMAXIMUM门限值,超时管理就必须十分精确,而这会给XGETE造成很大负担。

此处描述的实现方法是基于下面的假设:调度表提供的每帧传输时间不少于TNOMINAL的160%。为了满足这个要求,定时器的分辨率应该达到5个bits。为了简化这个实现方法,定时器的初始化装载值选择为7+帧传输数据的字节数。

最坏的超时情况出现在从机传输的字节数比期望的字节数少一时,例如从机传输了所有的数据但是没有传输校验和。另一方面,当从机根本不作出任何响应时超时检测完成速度最快。表2显示了在这种实现下超时情况发生的相对于TNOMINAL的时间。

 

帧字节数

超时时间/5bits ticks

最早超时检测/% of TNOMINAL

最晚超时检测/% of TNOMINAL

0

7

145.5

156.8

1

8

127.8

155.6

2

9

115.6

154.7

3

10

100.0

154.1

4

11

94.0

153.6

5

12

89.4

153.2

6

13

85.6

152.9

7

14

82.5

152.6

8

15

75.8

152.4

表2

 

由表2可以看出,所有的最坏情况下超时检测时间都在TNOMINAL的160%以内,类似的超时管理算法可以应用于任何特定的定时需求。例如,如果调度表提供给每帧传输的时间至少为TNOMINAL的170%,定时器分辨率可以降低到10个bits时间,在这种情况下超时管理对XGATE造成的负担将会减半。

5.2算法描述

一旦解决时间基准的要求超时管理自身就可以简化,函数实现也可以缩短。函数循环遍历LIN的所有节点来查看是否有节点正在接收。计时变量会为所有的接收节点递减,当定时器变量的值达到零时程序标记超时状况,具体实现见清单2:

清单2

6调度表

调度程序使用存储在调度环中的信息调用数据收发程序在LIN总线上传输数据帧。在这个实现方式中调度程序所用的时基的分辨率是1ms,分配给帧传送的时间被存放在LIN节点描述符的帧时间变量中,变量为16为宽度,所以分配给每帧的最大传输时间为65.535秒。

调度程序循环遍历所有的LIN节点描述符并每次使帧时间变量减一,如果到零调度程序就会使帧指针指向属于此LIN节点的调度环的下一帧并发起帧传输。当从从机接收到期望的字节数后调度程序会从LIN节点描述符中将数据复制回帧描述符。

在访问缓冲区之前信号量会被锁定以确保缓冲区中的数据始终有效。同样,在应用程序代码中访问缓冲区时需要锁定同样的信号量以确保一个新旧数据的混合体不会被应用程序或调度程序使用。具体实现见列表3:

列表3

6.1在运行时更改调度表

一些应用程序要求调度表在程序运行时能根据应用状态可以改变,到目前为止有如下几种方式可以实现此功能:

  1. 直接改变LIN节点描述符来立即改变调度表。这涉及改变帧变量使其指向新的调度环,调度函数将会在分配给当前帧的时间耗尽之后推进到新调度环中的下一个帧。
  2. 在当前调度环中选取的帧传送完成后改变调度表,在这种情况下当前调度环会在帧传输完成之后打开,并指向新的调度表,这种情况由图4描述。此时,调度函数不会对LIN节点描述符做任何改动而推进到新的调度表。

 

图4