1 基础概念
此章节主要描述一些SPI和AutoSAR SPI得基本概念。在解读和设计之前,我们需要清楚这些基本概念(对SPI有接触,前往第二章节)。
1.1 SPI
SPI(Serial Peripheral Interface,串行外设接口)是一种同步的串行通信协议,用于在微控制器与外部设备(如传感器、存储器、显示器等)之间进行数据交换。SPI协议由摩托罗拉(Motorola)最早提出,并被广泛应用于各种嵌入式系统中。
SPI通过四个主要的信号线进行通信:
MOSI (Master Out Slave In):主设备输出,从设备输入。数据从主设备传输到从设备。
MISO (Master In Slave Out):主设备输入,从设备输出。数据从从设备传输到主设备。
SCK (Serial Clock):时钟信号,由主设备产生,控制数据的传输速率。
SS/CS (Slave Select/Chip Select):从设备选择信号,告诉从设备通信开始。
示例:主设备 MCU,从设备 Peripheral。
传输属性:
1 片选极性(CS/SS Polarity):
总线IDLE下,CS默认电平,由该配置确定哪种电平表示通讯。当主设备将CS拉低(或拉高)时,表示通信开始,拉高(或拉低)时通信结束。
2 时钟极性(CPOL,Clock Polarity):
时钟极性决定时钟信号(SCK)在空闲状态下得电平。
CPOL = 0 SCK 默认低电平
CPOL = 1 SCK 默认高电平
该配置与CPHA一起决定采样边沿设置,详细见CPHA。
3 时钟相位(CPHA,Clock Phase):
时钟相位决定数据在时钟的哪个边沿被采样(上升沿或下降沿)。
CPHA = 0 数据在时钟信号的第一个边沿被采样
CPHA = 1 数据在时钟信号得第二个边沿被采样
当CPOL = 0,表示SCK默认为低电平,若CPHA = 0,表示在SCK第一个边沿采样,即SCK在低电平时,产生得第一个边沿必定是高电平,所以CPOL=0 CPHA=0,数据采样边沿为上升沿,那么数据切换边沿为下降沿。
CPOL与CPHA可组成四种形式,详细波形见示例图。
4 位序(Bit Order):
位序决定数据在SPI总线上传输时的位顺序,通常有两种方式:
MSB(Most Significant Bit)先传输:最高有效位(MSB)首先发送,最低有效位(LSB)最后发送。
LSB(Least Significant Bit)先传输:最低有效位(LSB)首先发送,最高有效位(MSB)最后发送。
取值:MSB First / LSB First。
5 数据宽度(Data Width):
数据宽度指每次传输的数据位数。SPI协议支持可变的数据宽度,通常是8位(一个字节),根据不同的硬件平台,宽度可以在1到32位之间配置。
波形示例:
2 AutoSAR SPI
2.1 定义
对于通信而言,目的只有一个,将某段数据发送出去。
其重点无非两处:数据、发出去(或收回来)
在AutoSAR中,SpiDriver被赋予更多特性和定义,我们先看下最基础得定义。
从数据结构上,AutoSAR定义了Sequence、Job、Channel得概念。
从传输方式上,AutoSAR定义了Asynchronous和Synchronous得传输方式。
2.1.1 Structure
在这里我们讲着重介绍AutoSAR得数据结构。
Sequence、Job、Channel是AutoSAR下得数据结构实例,暂时我们可以认定这之间是一种包含关系(后续澄清)。
(Sequence 和 Job 主要用于搭建数据和发送间得关系,并不存放真实数据)
AutoSAR SWS示例:
示例结构:
1,Channel
Channel我们可以理解为一个数据缓冲区,实际数据得载体,接收和发送得数据均由Channel缓存。
2,Job
Job 包含 一个或多个 Channel,以及链接一个ExternalDevice(Spi硬件配置)。
3,Sequence
Sequence 包含一个或多个 Job,是传输得实例,即收发数据接口参数是 SequenceID。
这里列举一个收发数据得实例:
通过SyncTransmit接口发送Sequence 0 和 Sequence 1
SyncTransmit(0)及 SyncTransmit (1)得发送过程:
在这里我们产生一些疑问:
1,在发送Sequence 0时,使用了哪个SPI?
2,CPOL,CPHA在哪里设置?
3,片选在哪里设定?
在AutoSAR 配置项中,通过ExternalDevice配置硬件特性,包括SpiHardUnit选择,CPOL、POHA配置等,ExternalDevice同Seq、Job等一至,可配置一到多。
在Job配置中,除了链接Channel,还会链接ExternalDevice。也就是说,同一个Job下得所有Channel数据发送,具有相同得硬件属性。
需要注意,每个Job仅能有一种ExternalDevice属性
如图:
Job 0 收发数据继承ExternalDevice 0 所有硬件属性。
Job 1 、Job 2 收发数据集成ExternalDevice 1 所有硬件属性。
所以,在不同Job之间可配置不同 Chip Select、CPOL、CPHA 等。
这种方式可以固定或交叉构成多种格式配置。
重点:澄清上面得一件事情。
Sequence、Job、Channel 间并不存在真实得包含关系,他们是并列得,这些定义,以及ExternalDevice得配置均通过链接得方式,构建成联系。
在AutoSAR中,Spi得Sequence ID、Job ID等,都具有唯一标识。
他们可根据配置需求交叉索引。
每个Sequence具有唯一得JobList,Sequence 通过 JobList 链接必要得Job。
每个Job具有唯一得ChannelList,Job 通过 ChannelList 链接必要得Channel。
2.1.2 Function
在AutoSAR中,Spi已经从数据结构上被抽象出Sequence、Job 和 Channel得概念,因此收发数据仅有唯二得两个接口:Spi_AsyncTransmit 和 Spi_SyncTransmit,他们仅有一个统一得参数 Sequence ID。
Std_ReturnType Spi_AsyncTransmit( Spi_SequenceType Sequence )
Std_ReturnType Spi_SyncTransmit( Spi_SequenceType Sequence )
(两接口差异,我们会在后面展开描述)
由上述章节,我们知道传输某个Sequence,实际是将该Sequence下所有Channel中数据发送出去。那随之而来得一个问题,我们得数据,如何被放置于Channel中?在AutoSAR中,提供了三个接口,来处理这个过程。
Std_ReturnType Spi_WriteIB(
Spi_ChannelType Channel,
const Spi_DataBufferType* DataBufferPtr )
Std_ReturnType Spi_ReadIB(
Spi_ChannelType Channel,
Spi_DataBufferType* DataBufferPointer )
Std_ReturnType Spi_SetupEB(
Spi_ChannelType Channel,
const Spi_DataBufferType* SrcDataBufferPtr,
Spi_DataBufferType* DesDataBufferPtr, Spi_NumberOfDataType Length )
这里要补充一个Channel相关知识点
AutoSAR 制定了两种 Channel 类型,IB & EB。
IB:内部分配缓冲区,即配置创建Channel时,自动生成对应得内存。
EB:外部缓冲区,用户通过接口将已有的缓冲区指针绑定到Channel上。
通俗得讲,IB缓冲区在配置过程自动生成,用户直接通过两个接口读写缓冲区。EB缓冲区为用户创建得数组或内存段,通过SetupEB讲内存地址指针注册到Channel中,Spi在传输过程中,直接去缓冲区地址内读写。
我们举例一个实际得数据接收发送过程:
Eeample.A : IB-Sync
Eeample.B : EB-Sync
Eeample.C : IB&EB-Sync
2.1.3 传输模式
AutoSAR SPI规定了两种传输方式,同步传输(SyncTransmit)和异步传输(AsyncTransmit)。直白得讲,同步传输接口会阻塞等待传输完成,才退出接口调用;而异步传输仅挂起传输任务,随后退出接口调用。
异步传输在启动传输或挂起传输后,立即退出当前程序,传输过程由IRQ或Main Function调度。
2.2 机制
该章节主要阐述不同得异步传输过程。包括IRQ,Main Function,DMA。
1,通过AsyncTransmit接口发送数据,若当前SPI为IDLE状态时,启动传输,发送Sequence下的第一个Job,进入JobTransmit;若当前状态为BUSY,则不应该去干扰正在发送得消息,将准备发送的Sequence加入到发送队列中。
2,JobTransmit过程,已知Job中包含特有的硬件属性,这个过程初始化硬件模块,准备发送JobList下第一个Channel数据。
3,ChannelTransmit过程,获取Channel中数据(IB EB存在方式不同),准备数据传输。
4,对于IRQ方式传输,需要CPU将数据Copy到TFIFO中,等待数据传输及产生中断。
5,当产生中断后,读取RFIFO值到接收缓冲区,同时判断当前Channel数据是否传输完成,若未完成,继续copy数据到TFIFO。
6,在中断时,发现当前Channel数据已发送完成,则回调Job层接口,准备发送下一个Channel数据(当前Job包含多个Channel)。
7,同理,当前Job中Channel全部传输完成后,通知JobEnd接口,通过回调上层接口,准备发送下一个Job数据。
8,以此类推,直至发送队列为空。
DMA传输方式与IRQ方式得上层相同,唯一不同位置在Write FIFO过程。DMA不需要管理Channel下数据发送过程,每次DMA传输Callback都标志着一个Channel数据发送成功,可直接选择处理下一个Channel数据发送。