AUTOSAR Mcal SPI - 基于Ifx TC37x
文章目录
- 1. 术语/缩略语
- 2. 主要功能
- 3. 主要概念
- 3.1. Sequence/Job/Channel
- 3.2. SpiLevelDelivered
- 3.3. SpiChannelBuffersAllowed
- 3.4. SpiInterruptibleSeqAllowed
- 3.5. SpiSupportConcurrentSyncTransmit
- 4. 部分程序流程图
- 4.1. 初始化流程图
- 4.2. 同步发送流程图
- 4.3. 异步发送流程图
- 5. 参考资料
记录Mcal SPI开发和使用过程中的疑问,包括基本概念、重要配置项的介绍,最终提供主要的程序流程图,用于了解代码框架,方便后续调试代码定位问题。
部分笔记参考其他大佬的文章,具体见“参考资料”章节
1. 术语/缩略语
- IB:驱动内部的Buffer,无需用户指定buffer,即可完成数据传输,传输完成后,通过Spi_ReadIB读取接收到的数据。
- EB:驱动外部的Buffer,由用户自行提供,EB类型的Channel需要先调用Spi_SetupEB设置源/目的地址、长度信息才能正确传输数据。
2. 主要功能
SPI驱动程序给那些通过SPI总线连接的设备提供读写服务。比如EEPROM、外挂Watchdog等设备。主要有如下功能:
- 支持Master模式,不支持Slave模式
- 支持全双工模式(此处AUTOSAR SWS的要求,实际也可以支持半双工,Master和Slave发送/接收引脚短接,两个SPI设备通过一根物理总线进行连接,两端发送引脚设置为开漏输出,外接上拉电阻,利用线与特性完成数据传输,Master发送时,接收Buffer设置为空;Master接收时,发送全1)
- 支持同步/异步/同步+异步三种模式
- 异步模式下支持优先级传输,以job为单位
- 支持SPI硬件和GPIO控制片选信号
- 支持2~32bit传输数据
- 支持IB/EB/IB+EB三种buffer
3. 主要概念
3.1. Sequence/Job/Channel
- Channel:此处的Channel和Ifx硬件上的Channel0~15不同,此处是软件层面的,代表1个或多个2 ~ 32bit的数据块,可以简单理解为硬件上一帧短连续的数据。
- Job:1个或多个Channel组成,与硬件的Module和Channel绑定(例如QSPI0的Channel0),job下每个Channel的数据长度、大小端可不同,每个job可以4级优先级(值越大优先级越高),使能可中断序列(SpiInterruptibleSeqAllowed)的前提下,按照优先级顺序发送每个job
- Seq:1个或多个Job组成,在TC3xx中,所有job可以由同一个Module的不同Channel组成(必须是相同的Module),每个Job的波特率、奇偶校验、片选极性可不同。
备注
1、一个Seq下至少一个job,一个job下至少一个Channel
2、异步/同步传输是以Seq为单位,接收是放到具体某个Channel中,若Channel是IB,需要用户自行读取,若配置为EB,传输完成后,接收的数据则存放到用户指定的buffer中。
3.2. SpiLevelDelivered
SPI支持同步/异步/增强(同步+异步)三种模式,具体介绍如下
3.3. SpiChannelBuffersAllowed
分为IB/EB/IB+EB三种模式,对应配置值为:
IB: 静态分配。 EB: 可以是静态分配,也可以是动态分配,取决于用户的使用环境。
有些硬件层面提供了比较大的Buffer,这种情况IB类型可以充分发挥硬件特性,提高其性能(这是IB Buffer的设计初衷)。如果硬件没有Buffer,则需要软件来模拟实现,Ifx硬件上存在两个深度为4的Buffer(一个Tx,一个Rx)但Mcal任然使用软件模拟实现。
- IB类型的Buffer其大小是固定的。EB类型Buffer可以通过API进行设置。
SPI驱动不负责保证IB Buffer里数据的连续性。如果某个Channel被多个Job/Seq使用,SPI驱动也不负责维护该Buffer被多个Job/Seq重写这种场景。
但是发送和接收的Buffer是分开独立的。也就是发送Buffer不会被接收的数据覆盖。 - EB Buffer的设计初衷是为了尽量重用外部(这里指用户)Buffer,因为很多情况下,用户已经有了一个Buffer,那么使用EB类型Buffer,只需要将用户Buffer的指针提供给SPI驱动以达到共用的目的。所以SPI驱动也是无法对该Buffer管理的,需要用户来保证其一致性。还有一种场景是,有时候我们的Buffer大小是变化的(比如多个使用者的需求可能不同,或者一个使用者数据长度是变化的),这种情况也需要使用EB类型Buffer来解决(因为IB类型Buffer是固定大小的)。当然EB类型Buffer也可以是固定大小。但是Buffer大小的最大值需要静态配置。总的来说EB类型Buffer使用更灵活。
Channel传输有自己的参数(Spi_SetupEB),但参数(source/target)也可以是NULL,如果发送的时候Source为NULL,则会使用默认参数传输,如果接收的时候Target为NULL,则会忽略接收到的数据。每个Channel,Spi_SetupEB函数只能在发起传输请求前调用一次,除非有信息需要变更,比如长度信息。
3.4. SpiInterruptibleSeqAllowed
可中断序列功能仅支持异步模式(Level1或Level2),配置为FALSE,不支持可中断序列,以Seq为单位进行传输,每个Seq下的所有job拥有相同的优先级;配置为TURE,支持可中断序列,以job为单位进行按照优先级顺序进行传输(值越大优先级越高,相同优先级的情况下,先压入队列的job先进行传输),一个Seq在传输过程中,若出现优先级更高的异步请求,当前job传输传输完成后,打断当前Seq,开始传输优先级更高的job。
备注
1、EB工具配置时,Seq下的job应该按照优先级顺序进行摆放(高到低),若不满足,工具会报错。
2、支持可中断序列的情况下,用户需要清楚是否存在多个Sequence共用同一个Channel的情况,如果有,则自己需要管理好Channel的数据,防止传输过程中被更高优先级的Job将原来Channel里面的数据覆盖掉。
3.5. SpiSupportConcurrentSyncTransmit
并发同步传输功能仅支持同步模式(Level0或Level2),配置为TRUE时,允许用户发起多笔不同的请求,不同请求使用的Module必须不同,否则上报SEQ_IN_PROCESS错误。
备注:仅多线程 or 多核的情况下存在,因为在发送的过程中会产生阻塞,同一线程下不可能两次调用。
4. 部分程序流程图
4.1. 初始化流程图
4.2. 同步发送流程图
4.3. 异步发送流程图
5. 参考资料
AUTOSAR MCAL详解:SPI(1)
AUTOSAR MCAL详解:SPI(2)