ARM学习(16)CortexM4外设地址了解以及SPI异常问题分析
笔者来聊聊碰到的一个SPI作为应用层通信协议的问题
1、CortexM4外设地址
准确来说,CortexM4 并没有对外设的地址进行规定,外设的地址一般都是厂商自定义的,但是一般都遵循一个区间范围,比如下图所示:一般0x4000 0000 ~ 0x5FFF FFFF 为外设的地址(512MByte 空间,足够自由发挥了)
比如STM32的SPI地址空间为:
NXP的SPI地址空间为:0x4008 000 到 0x4010 C000区间内,NXP的SPI外设地址是不固定的,与STM32不同,其走的是Flexcomm 接口,该接口可以映射到USART、SPI、I2C/I2S,相当于每个接口复用为三个功能,10个Flexcomm,相当于可同时有10个SPI等,方便对于不同外设个数的需求。
其具体复用情况如下图所示:
2、SPI通信原理简介
SPI的通信原理如下图所示:(Master发16个Byte,同时就收到Slave16个Byte,相当于挤出Slave的16个Byte),具体的介绍就不多说,网络上有很多介绍。
3、SPI异常问题分析
笔者在使用SPI 作为通信协议的时候碰到问题,如下图所示。
首先介绍背景,MCU作为slaver,只能被动等待传输数据,Host为上位机,主动发起SPI读取数据,这样以来的话,每次与Host交互数据,就需要两次数据交互。
第一次:
- host 发送 req 请求数据,此时MCU提前预填数据,等待Host读走,因为该数据没什么含义,所以为dummy数据。
- 收发完成之后,MCU收到请求数据,开始处理并把处理好的数据放到Buf或者FIFO,等待Host端读走数据,而Host此时收到了dummy数据,该dummy数据可以进行校验,为特定的预填的dummy数据。
第二次:
- Host 主动去读数据,因为其是获取结果的,所以发送的cmd填充dummy数据即可,然后将MCU预填的处理结果数据读走,这样就完成了一次数据交互。
- 同时MCU收到了dummy数据,也可以进行校验,因为是特定的dummy数据,同时将该数据填充到buf,以便于下一次通信需要。
如果都是上述那种理想情况,确实可以正常通信,无需担心。
但是如果碰到超时重传的情况,就打乱了两次交互数据的流程。比如碰到如下场景(上图第二次通信情况):
- 第一次上位机给下位机传输命令,由于某种情况,传输命令超时,但是MCU(下位机)收到了数据,上位机没收到dummy数据,
- 第二次上位机的超时重传机制等待一定时间后,重传命令,此时数据交互正常,上位机收到了MCU的同步回传数据,但是却不是dummy数据,因此认为MCU通信异常。(为上图 dummy check fail)
要解决上述的问题,就需要梳理一下通信流程,核心问题就是MCU每次需要预填数据,等待上位机来取数据,假如流程没有按照MCU期望的流程走,就会导致预填数据错误,导致整个流程异常。
假如还是按照通常(常见)的命令交互来处理,收到什么数据进行什么数据处理,然后响应什么数据,即可化解该问题,如下图所示,收到请求,就回resp,收到dummy就回dummy数据。
接着再回到刚刚的问题,如果收到多次请求req cmd,那就填充多次resp cmd,但是此时需要上位机不检测dummy数据,认为有数据响应就OK,下次再把正确数据读回来即可。
就上图6所示,再增加一个这样读走正确数据的流程即可。
由于MCU是被动等待上位机获取数据,假设MCU要处理一个耗时较长的任务,由于中途无法被打断,所以需要提前欲填好下位机忙得命令,上位机获取到下位机忙得命令后,就会等待一段时间再去获取结果,这就完成了一次特殊的任务交互。
版权声明:
作者:ZhangYixi
链接:http://zyixi.xyz/arm%e5%ad%a6%e4%b9%a0%ef%bc%8816%ef%bc%89cortexm4%e5%a4%96%e8%ae%be%e5%9c%b0%e5%9d%80%e4%ba%86%e8%a7%a3%e4%bb%a5%e5%8f%8aspi%e5%bc%82%e5%b8%b8%e9%97%ae%e9%a2%98%e5%88%86%e6%9e%90/
来源:一西站点
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论