您的位置:首页 > 文旅 > 美景 > 神农架网页设计_拍摄宣传片的流程简要_重庆seo优化_自己开一个培训机构流程

神农架网页设计_拍摄宣传片的流程简要_重庆seo优化_自己开一个培训机构流程

2024/12/28 4:08:08 来源:https://blog.csdn.net/weixin_44767571/article/details/142514065  浏览:    关键词:神农架网页设计_拍摄宣传片的流程简要_重庆seo优化_自己开一个培训机构流程
神农架网页设计_拍摄宣传片的流程简要_重庆seo优化_自己开一个培训机构流程

总体说明: 这个结构 我肯定 一次是 写不完的, 框架有了, 以后 有机会了,就会 不断去填充这些内容。

一、 首先是  在 对于 linux  spi 框架的 了解。

这是它的 总体的结构, 接口部分就是 spi core 。

1.5编程的内容 跟这个就很像了。

也就是 说 , 芯片原厂 实现的 就是 在 spi_sync 以下的部分。

这个接口 我之前看过 ,但是没看懂。

这个spi_locked  的目的 是什么呢?

这个控制器的 初始化的流程 我也没看懂。

先截图下来。

二、 然后是 对于具体的函数的了解。

spi_read()

spi_write()

spi_write_then_read()

这是具体的函数的实现,

drivers/spi/spi.c

 int spi_write_then_read(struct spi_device *spi,▎   ▎   const void *txbuf, unsigned n_tx,▎   ▎   void *rxbuf, unsigned n_rx){▎   static DEFINE_MUTEX(lock);▎▎   int         status;▎   struct spi_message  message;▎   struct spi_transfer x[2];▎   u8          *local_buf;▎▎   /* Use preallocated DMA-safe buffer if we can.  We can't avoid▎   ▎* copying here, (as a pure convenience thing), but we can▎   ▎* keep heap costs out of the hot path unless someone else is▎   ▎* using the pre-allocated buffer or the transfer is too large.▎   ▎*/▎   if ((n_tx + n_rx) > SPI_BUFSIZ || !mutex_trylock(&lock)) {▎   ▎   local_buf = kmalloc(max((unsigned)SPI_BUFSIZ, n_tx + n_rx),▎   ▎   ▎   ▎       GFP_KERNEL | GFP_DMA);▎   ▎   if (!local_buf)▎   ▎   ▎   return -ENOMEM;▎   } else {▎   ▎   local_buf = buf;▎   }▎▎   spi_message_init(&message);▎   memset(x, 0, sizeof(x));▎   if (n_tx) {▎   ▎   x[0].len = n_tx;▎   ▎   spi_message_add_tail(&x[0], &message);▎   }▎   if (n_rx) {▎   ▎   x[1].len = n_rx;▎   ▎   spi_message_add_tail(&x[1], &message);▎   }▎▎   memcpy(local_buf, txbuf, n_tx);▎   x[0].tx_buf = local_buf;▎   x[1].rx_buf = local_buf + n_tx;▎▎   /* do the i/o */▎   status = spi_sync(spi, &message);▎   if (status == 0)▎   ▎   memcpy(rxbuf, x[1].rx_buf, n_rx);▎▎   if (x[0].tx_buf == buf)▎   ▎   mutex_unlock(&lock);▎   else▎   ▎   kfree(local_buf);▎▎   return status;}EXPORT_SYMBOL_GPL(spi_write_then_read);

重点关注这两个地方。

首先是 关于 tx_buf , 与 rx_buf.

local_buf+n_tx, 它这里的意思是说, 将rx_buf 的地址,放到 tx_buf 地址的 后面。

直接 重新开一个buf 不是更好吗?

疑问: 还有就是 这里有两个 spi_transfer , 一个 设置了tx_buf 的内容, 另一个 只是设置了 rx_buf 的地址,没有设置发送什么内容。这样可以吗?

网上找了一个截图:

我感觉 这里的意思是:

如果我只是 设置了 rx_buf 的地址,tx_buf 没有设置, 那么我默认就在 tx_buf 中填null ,这也是发送, 还记得 spi_transfer 中有一个 len  吗? 这个length 既是在说 发送的长度,也是在说 接收的长度。

这只是我猜的,具体的 这块的实现, 我没找到。

关于 kthread_worker , kthread_work 的理解。

先来看看这两个函数的使用

网上的截图:

在 kthread_work 中  有真正的执行的函数

kthread_worker 中 有一个 tast_struct ,我比较感兴趣。

首先是初始化  kthread_worker

注意 : kthread_worker_fn 函数 并不执行spi 的逻辑。

然后是  kthread_work 的初始化。

注意: 这里的 这个 xxx_work_fn 才是 真正的 执行 spi 的逻辑的函数。

注意: kthread_queue_work 将 work 与worker 联系起来了。

然后是   kthread_run() 函数

网上的截图:

我的理解是, threadfn 这个只是一个 进程, 我设计做具体的事情, 后面肯定还有 某些流程,将worker 里面的具体的  spi 的 执行函数, 挂到这个进程上。

然后是  kthread_worker_fn  函数

代码如下:

int kthread_worker_fn(void *worker_ptr)
{struct kthread_worker *worker = worker_ptr;struct kthread_work *work;/** FIXME: Update the check and remove the assignment when all kthread* worker users are created using kthread_create_worker*() functions.*/WARN_ON(worker->task && worker->task != current);worker->task = current;if (worker->flags & KTW_FREEZABLE)set_freezable();repeat:set_current_state(TASK_INTERRUPTIBLE);	/* mb paired w/ kthread_stop */if (kthread_should_stop()) {__set_current_state(TASK_RUNNING);spin_lock_irq(&worker->lock);worker->task = NULL;spin_unlock_irq(&worker->lock);return 0;}work = NULL;spin_lock_irq(&worker->lock);if (!list_empty(&worker->work_list)) {work = list_first_entry(&worker->work_list,struct kthread_work, node);list_del_init(&work->node);}worker->current_work = work;spin_unlock_irq(&worker->lock);if (work) {__set_current_state(TASK_RUNNING);work->func(work);} else if (!freezing(current))schedule();try_to_freeze();cond_resched();goto repeat;
}
EXPORT_SYMBOL_GPL(kthread_worker_fn);

可以看到 比较重要的是   worker->task = current  这一句。

将 worker 的 tast ,设置成了 当前进程。

但是具体的还不是很了解。

九 、 我自己 关于 spi 有设备树 与没有设备树的 配置的区别,以及 对于 spi_board_info 的理解。

三 、 然后是 关于 mcp2515 的数据手册的解析。

四、 然后是 一些 需要注意的小点。

比如 spi 时钟的 时延的理解。

关于spi bit_word 的理解。

然后是 mcp2515 的 晶振 与 can 总线速率的关系。

五、 然后是 关于 通用的 spidev 的理解。

六 、然后是关于 gpio 模拟 spi 的理解。

七、 然后是关于 移植 mcp2515 的理解。

八、  是关于 stm32 对于 mcp2515 的使用。

这部分估计我没有时间做。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com