spi数据传输分为同步、异步两种:
同步方式是指数据发出后一直等待成功;
异步方式是指数据发出后不用等待成功,设置传输成功回调函数提醒发送成功;
问题:在异步方式情况下,如下状况,如何解决?
对于同一个数据发送者,当上一次spi_message还没有发送完成的情况下,如何发送下一个
spi_message
答案:引入队列,将等待传输的spi_message放入一个等待队列中,系统不断检测队列是否为空;
-------------------------------------------------------------------
spi_transfer 队列化 :
struct spi_transfer {
......
const void *tx_buf;
void *rx_buf;
......
struct list_head transfer_list;//链表头
};
struct spi_message {
struct list_head transfers; //挂接在本 message下的transfers链表头
void (*complete)(void *context); //传输完成 回调函数
struct spi_device *spi;
......
struct list_head queue; //挂接等待传输的spi_mastert
......
};
//将需要传输的spi_transfer 挂接添加在 spi_message transfers链表下
spi_message_add_tail(struct spi_transfer *t, struct spi_message *m)
//spi 核心层的数据传输以一个 spi_message 为单位,
transfer_one_message
---------------------------------------------------------------------------------
spi_message的队列化 :
多个 spi_mastert 申请传输的时候, 等待的传输spi_mastert被挂接在 控制器spi_mastert的
queue队列下;
发起 spi_mastert 传输:异步传输
spi_async(struct spi_device *spi, struct spi_message *message);
spi_async 会发起一个 异步传输,将spi_message结构挂接在 spi_message的queue字段下,
然后启动专门为spi传输准备的内核工作线程,一般情况下,当这个工作线程被唤醒的时候,
spi_message queue队列下已经挂接了多个spi_message等待传输,每一个spi_messag传送完
成之后,会调用 complete 回调函数提示本次 spi_message 传输完成,叫下一个,
--------------------------------------------------------------------------------------------
总结: spi传输数据是以 spi_message 为单位的,我们需要传输的内容在 spi_transfer 中
1 : 将本次需要传输的 spi_transfer 以 spi_transfer->transfer_list为链表项,连接成一个
transfer_list链表,挂接在本次传输的spi_message spi_message->transfers链表下;
2 : 将所有等待传输的 spi_message 以 spi_message->queue 为链表项,连接成个链表挂接在queue下
同步方式是指数据发出后一直等待成功;
异步方式是指数据发出后不用等待成功,设置传输成功回调函数提醒发送成功;
问题:在异步方式情况下,如下状况,如何解决?
对于同一个数据发送者,当上一次spi_message还没有发送完成的情况下,如何发送下一个
spi_message
答案:引入队列,将等待传输的spi_message放入一个等待队列中,系统不断检测队列是否为空;
-------------------------------------------------------------------
spi_transfer 队列化 :
struct spi_transfer {
......
const void *tx_buf;
void *rx_buf;
......
struct list_head transfer_list;//链表头
};
struct spi_message {
struct list_head transfers; //挂接在本 message下的transfers链表头
void (*complete)(void *context); //传输完成 回调函数
struct spi_device *spi;
......
struct list_head queue; //挂接等待传输的spi_mastert
......
};
//将需要传输的spi_transfer 挂接添加在 spi_message transfers链表下
spi_message_add_tail(struct spi_transfer *t, struct spi_message *m)
//spi 核心层的数据传输以一个 spi_message 为单位,
transfer_one_message
---------------------------------------------------------------------------------
spi_message的队列化 :
多个 spi_mastert 申请传输的时候, 等待的传输spi_mastert被挂接在 控制器spi_mastert的
queue队列下;
发起 spi_mastert 传输:异步传输
spi_async(struct spi_device *spi, struct spi_message *message);
spi_async 会发起一个 异步传输,将spi_message结构挂接在 spi_message的queue字段下,
然后启动专门为spi传输准备的内核工作线程,一般情况下,当这个工作线程被唤醒的时候,
spi_message queue队列下已经挂接了多个spi_message等待传输,每一个spi_messag传送完
成之后,会调用 complete 回调函数提示本次 spi_message 传输完成,叫下一个,
--------------------------------------------------------------------------------------------
总结: spi传输数据是以 spi_message 为单位的,我们需要传输的内容在 spi_transfer 中
1 : 将本次需要传输的 spi_transfer 以 spi_transfer->transfer_list为链表项,连接成一个
transfer_list链表,挂接在本次传输的spi_message spi_message->transfers链表下;
2 : 将所有等待传输的 spi_message 以 spi_message->queue 为链表项,连接成个链表挂接在queue下