在SPI驱动里面接收SPI数据,怎么及时处理SPI数据缓冲区才不会让一帧数据跟下一帧数据起冲突。

305932515   2009-4-2 21:07 楼主
在SPI驱动里面接收SPI数据,怎么及时处理SPI数据缓冲区才不会让一帧数据跟下一帧数据起冲突。

回复评论 (26)

驱动里面处理不及时,下一帧数据又过来了.这样就把上一帧数据冲掉了,就破坏了上一帧数据.简单的用缓冲区来处理效果不好,对缓冲区数据要处理时加锁定却又怕下一帧数据不能及时被接进缓冲区.


还有就是上发给上层应用有没好的东西?数据太长要去读取太费时间了.


大家有没什么好的方法?能不能分享点经验?
点赞  2009-4-2 21:14
接收线程跟处理线程里面用到的数据缓冲区都是同一个,怎么保持两个线程对这片数据缓冲区访问的唯一?并且能够及时响应SPI中断。


1》通过关键区是一种方法,但觉得效率会低,也不能及时响应SPI中断
点赞  2009-4-3 08:47
起个软中断,然后写个中断服务程序
点赞  2009-4-3 09:22
驱动里面可以用寄存器控制速度,如果你测试发觉丢帧了就调节下速度就可以了晒。
SPPREn这个寄存器:Baud rate = PCLK/2/(Precaler Value + 1)

起个软中断,然后写个中断服务程序?????SPI不是有专门的中断吗?还起个软中断做什么,最好把驱动弄成中断模式。
点赞  2009-4-3 09:29
使用SPI中断模式。处理完一帧之后再去读

我觉得使用中断比查询要好的多。
点赞  2009-4-3 09:40
引用: 引用 5 楼 gooogleman 的回复:
使用SPI中断模式。处理完一帧之后再去读

我觉得使用中断比查询要好的多。


通过驱动层发消息通知上层AP去读,AP收到了消息,然后去读,这个时间估计蛮长的,时间太长了,SPI里面接收好的数据估计早被下一帧数据给改变了,这样做的实时性不好。
点赞  2009-4-3 11:25
建立一个适当大小的软Buffer,每次接收的数据都按照顺序缓存到Buffer中,上层根据Buffer的指针来读取需要的数据。
点赞  2009-4-3 11:30
引用: 引用 7 楼 xajhuang 的回复:
建立一个适当大小的软Buffer,每次接收的数据都按照顺序缓存到Buffer中,上层根据Buffer的指针来读取需要的数据。


上层怎么知道对应指针?驱动肯定要上发给AP知道,但这个时间间隔里面,这个指针说不定已经被更新为新的数值了。
点赞  2009-4-3 11:39
引用: 引用 7 楼 xajhuang 的回复:
建立一个适当大小的软Buffer,每次接收的数据都按照顺序缓存到Buffer中,上层根据Buffer的指针来读取需要的数据。


上层怎么知道对应指针?驱动肯定要上发给AP知道,但这个时间间隔里面,这个指针说不定已经被更新为新的数值了。
点赞  2009-4-3 11:39
typedef struct {
   int len;
   unsigned char *buf;
} myBuf;

驱动进行缓存。每个 myBuf 对应一个 frame,建立多个 myBuf 对应多个 frame。当然 myBuf 个数不宜过多,可根据实测调整。
点赞  2009-4-3 12:32
做个环形缓冲队列;
简单的用数组来实现:
定义一个结构体,结构体里有三个成员:
1.队列的头指示符
2.队列尾指示符
3.数组

具体读写是这样:
驱动往进写数据时用队列的头指示符做数组的下标把数据放进去;
应用读数据时用队列的尾指针指示符做数组的下标把数据读出来;

要做的好一点的话,单独做个库,对外只提供读写的接口;驱动要写数据时调用接口直接写;应用读数据时调用接口直接读;
库里对数组的操作和队列头指示器,队列尾指示器的操作进行封装;(主要判断队列是否为空,队列是否满等)

对于应用什么时候去读数据,要么让驱动发消息,写完一帧发条消息;要么让应用起个定时器,定时去读队列;

忘了说一点了(也是重要的一点)就是队列环形的处理,其实很简单,写数据时让头指示器自加,直到和数组元素个数相等然后让头指示器等于0(当然这个可以封装进库里),尾指示器的操作相同;
点赞  2009-4-3 13:06
这样做估计也做不到保护数据的作用-------在没读完之前,数据是完整的没被破坏。
点赞  2009-4-3 13:16
引用: 引用 10 楼 morris88 的回复:
typedef struct {
  int len;
  unsigned char *buf;
} myBuf;

驱动进行缓存。每个 myBuf 对应一个 frame,建立多个 myBuf 对应多个 frame。当然 myBuf 个数不宜过多,可根据实测调整。


象 ethernet 那样,不就行了嘛!
点赞  2009-4-3 13:18
引用: 引用 12 楼 xqhrs232 的回复:
这样做估计也做不到保护数据的作用-------在没读完之前,数据是完整的没被破坏。

应该可以吧,队列的大小要根据你系统的容限来定义,假设已连续一次最多发10包,你只要保证你的队列的大小可以容纳下10包×1.5个的大小就可以了;

因为驱动一直写队列用的是头指示器,在队列没有满之前不会破坏之前的数据;
应用用的是尾指示器,尾指示器一直在追头指示器,没有读完,只要队列不满,不会破坏的;只有在队列满时才会破坏,队列满也就是头指示器比尾指示器多跑了一圈;


点赞  2009-4-3 13:24
不过可以试试
点赞  2009-4-3 14:03
楼主说的一帧数据是什么意思。如果没接收一个数据就产生一个中断的话,是来不及的。不知道楼主用的CPU,SPI有没有FIFO?
点赞  2009-4-3 17:07
一帧数据技术一条命令数据啊。CPU是S3C6400。
点赞  2009-4-3 17:13
引用: 引用 9 楼 xqhrs232 的回复:
引用 7 楼 xajhuang 的回复:
建立一个适当大小的软Buffer,每次接收的数据都按照顺序缓存到Buffer中,上层根据Buffer的指针来读取需要的数据。


上层怎么知道对应指针?驱动肯定要上发给AP知道,但这个时间间隔里面,这个指针说不定已经被更新为新的数值了。


上层不需要知道下面的指针,只需要提供一个ReadFile的函数就行了,在ReadFile函数中你自己处理Buffer的指针就行了。
点赞  2009-4-3 17:14
也就是说Soft Buffer 只存在PDD/MDD驱动中,和应用程序无关,应用程序根本不用去管MDD驱动中有没有Buffer,只需要利用ReadFile从MDD层读取数据。
所以Buffer以及指针的管理都在MDD层的ReadFile函数中实现和管理。
点赞  2009-4-3 17:16
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复