关于 s3c2416 hspi spi linux 驱动
2009-09-27 12:45
267 查看
最近在做samsung
s3c2416
在linux下的spi驱动程序,测试了下samsung发布的spi的内核源代码,无论是采用dma或者非dma模式都无法工作。阅读该驱动代码,发现
这码应该是一个未完成的版本,存在很多的bug。于是在这个版本的基础上进行修改,重写一个可用的、支持全双工的通讯的驱动。目前测试基本能够正常工作,
支持半双工、全双工、spi硬件中断模式和dma模式。
对hspi-s3c2443.[ch]源文件根据数据发送和接收的流程进行分析,在未采用dma模式下,函数调用的流程:s3c_spi_xfer
-> s3c_spi_doxfer -> s3c_spi_message_start ->
down_interruptible(&spi->sem),到这里,硬件会产生spi中断,进入到中断服务程序
s3c_spi_irq 中,中断函数调用 spi_s3c_irq_nextbyte
进行数据发送,根据spi->state的值做相应的操作,数据发送或接收完成后,调用 s3c_spi_stop
关闭spi,并up(&spi->sem),程序流程回到了s3c_spi_doxfer函数的
down_interruptible(&spi->sem),函数返回退出,一个spi的数据收发流程完成。
在这个发送接收流程中,中断服务程序存在很多不足的地方。
先看spi发送,发送最终调用的是:
while(!(tx_msgend(spi)))
s3c_spi_write_fifo(spi);
这两行代码的功能是判断写缓冲里是否还有数据,有的话就写入到spi发送寄存器(S3C_SPI_TX_DATA)中。我们知道spi的硬件能够缓冲64
个字节的数据,如果我们一次发送的数据长度小于64个字节,并且下一次发送数据时缓冲中的数据发送完成,那么这段代码表面上应该是没什么问题。如果我们发
送的数据长度大于64个字节,那么这段代码至少造成的后果是产生一个SPI transmit over run error。
在看spi接收,接收调用的代码是:
while(!(rx_msgend(spi))){
spi->msg->rbuf[spi->msg_rd_ptr ] = readl(spi->regs S3C_SPI_RX_DATA);
}
这个代码判断通过读取S3C_SPI_RX_DATA寄存器,把数据写到接收缓冲去中,同样这段代码存在很多的漏洞,假如我们接收的数据长度小于64个字
节,并且接收完成,这时在中断服务程序中做次操作,那么,问题应该不是很大。同样,如果我们需要接收大于64个字节长度的数据呢。那么,这段代码同样也是
存在bug。
< -- 未完待续,修改后的代码稍后贴出来。第一次在网上写关于程序开发经验,而且网页编辑不是很熟悉,现在的感觉是不太好用。如果内容描述不清楚,希望大家多提提意见 -- >
s3c2416
在linux下的spi驱动程序,测试了下samsung发布的spi的内核源代码,无论是采用dma或者非dma模式都无法工作。阅读该驱动代码,发现
这码应该是一个未完成的版本,存在很多的bug。于是在这个版本的基础上进行修改,重写一个可用的、支持全双工的通讯的驱动。目前测试基本能够正常工作,
支持半双工、全双工、spi硬件中断模式和dma模式。
对hspi-s3c2443.[ch]源文件根据数据发送和接收的流程进行分析,在未采用dma模式下,函数调用的流程:s3c_spi_xfer
-> s3c_spi_doxfer -> s3c_spi_message_start ->
down_interruptible(&spi->sem),到这里,硬件会产生spi中断,进入到中断服务程序
s3c_spi_irq 中,中断函数调用 spi_s3c_irq_nextbyte
进行数据发送,根据spi->state的值做相应的操作,数据发送或接收完成后,调用 s3c_spi_stop
关闭spi,并up(&spi->sem),程序流程回到了s3c_spi_doxfer函数的
down_interruptible(&spi->sem),函数返回退出,一个spi的数据收发流程完成。
在这个发送接收流程中,中断服务程序存在很多不足的地方。
先看spi发送,发送最终调用的是:
while(!(tx_msgend(spi)))
s3c_spi_write_fifo(spi);
这两行代码的功能是判断写缓冲里是否还有数据,有的话就写入到spi发送寄存器(S3C_SPI_TX_DATA)中。我们知道spi的硬件能够缓冲64
个字节的数据,如果我们一次发送的数据长度小于64个字节,并且下一次发送数据时缓冲中的数据发送完成,那么这段代码表面上应该是没什么问题。如果我们发
送的数据长度大于64个字节,那么这段代码至少造成的后果是产生一个SPI transmit over run error。
在看spi接收,接收调用的代码是:
while(!(rx_msgend(spi))){
spi->msg->rbuf[spi->msg_rd_ptr ] = readl(spi->regs S3C_SPI_RX_DATA);
}
这个代码判断通过读取S3C_SPI_RX_DATA寄存器,把数据写到接收缓冲去中,同样这段代码存在很多的漏洞,假如我们接收的数据长度小于64个字
节,并且接收完成,这时在中断服务程序中做次操作,那么,问题应该不是很大。同样,如果我们需要接收大于64个字节长度的数据呢。那么,这段代码同样也是
存在bug。
< -- 未完待续,修改后的代码稍后贴出来。第一次在网上写关于程序开发经验,而且网页编辑不是很熟悉,现在的感觉是不太好用。如果内容描述不清楚,希望大家多提提意见 -- >
相关文章推荐
- 基于6467T的linux平台下的SPI驱动编写
- Linux驱动修炼之道-SPI驱动框架源码分析(中)
- S3C2440 Linux驱动移植——SPI
- Linux驱动修炼之道-SPI驱动框架源码分析(上)
- Linux驱动修炼之道-SPI驱动框架源码分析(上)
- Linux X86驱动intel core i7中关于HD-Audio的配置关键描述翻译
- Linux SPI总线和设备驱动架构之二:SPI通用接口层
- Linux驱动修炼之道-SPI驱动框架源码分析
- EM9280 Linux SPI 驱动简介
- Linux的spi驱动分析
- SPI在linux3.14.78 FS_S5PC100(Cortex A8)和S3C2440上驱动移植(deep dive)_0
- Linux SPI总线和设备驱动架构之一:系统概述
- Linux驱动修炼之道-SPI驱动框架源码分析(中)
- 基于S3C2440的嵌入式Linux驱动——SPI子系统解读(一)
- Linux SPI总线设备驱动模型详解
- Linux3.6.9下AD7490的SPI通信驱动设计
- 和菜鸟一起学linux总线驱动之初识spi驱动数据传输流程
- LINUX设备驱动之SPI总线驱动分析
- Linux驱动基础:三星平台Linux SPI驱动
- Linux SPI驱动之笔记