2016-06-03 8 views
2

사용자 지정 하드웨어 용 SPI 드라이버를 구현하려고합니다. 필자는 필요한 거의 모든 것을 지원하는 spidev 드라이버의 복사본을 가지고 시작했습니다.lseek 구현을위한 사용자 지정 SPI 드라이버

우리는 명령 비트 (읽기/쓰기)와 임의의 양의 데이터를 갖는 프로토콜을 사용합니다.

간단히 말해서 lseek 기능을 추가하는 것이 최선의 방법이라고 생각했습니다. 원하는 주소로 "Seek"한 다음 바이트 수를 읽거나 씁니다. 새 드라이버의 file_operations에서 custom .llseek를 만들었지 만 그 함수가 호출되는 것을 본 적이 없습니다. 나는 fseek(), lseek(), pread()를 사용해 보았고 그 함수들 중 어느 것도 새로운 my_lseek() 함수를 호출하지 않는 것으로 보인다. 내가 주로하기 때문에, dev에 파일이 만들어 얻을하는 방식에 뭔가가 없다고 생각

static struct spi_board_info my_spi_board_info[] __initdata = { 
[0] = { 
    .modalias  = "myspi", 
    .bus_num  = 1, 
    .chip_select = 0, 
    .max_speed_hz = 3000000, 
    .mode   = SPI_MODE_0, 
    .controller_data = &spidev_mcspi_config, 
}, ... 

:

장치가 board.c 파일에 정의를 "errno를 29 ESPIPE 불법 탐색"모든 통화 보고서 예 내가

static int myspi_llseek(struct file *filp, loff_t off, int whence) 
{ 
    ... 
    newpos = filp->f_pos + off; 
    ... 
} 

그래서 내 질문은

f_pos> filp- 참조를 발견 :이 드라이버 (약간 수정 spidev) (가) "추구"지원을하는 방법이 전화를? 이것이 errno 29를 반환하기 위해 어느 시점에 정의됩니까? 새 드라이버에서 시작하고 spi_board_info() 및 spi_register_board_info() 설정에 의존 할 수 없습니까?

/drivers/spi 디렉토리 (spi-dw)에있는 하나의 드라이버 만 lseek를 참조하며 default_llseek 구현을 사용합니다. 우리가 모든 것을 해내 고 실행하기 위해 생각해 낸 몇 가지 "해킹"이 있지만, 올바른 방법을 얻는 법을 배우려는 사람이되는 경향이 있습니다.

모든 의견을 매우 높이 평가합니다. (PS, 커널 버전은 OMAP 안드로이드 시스템의 경우 3.4.48 임)

+0

나는 어딘가에 * 초기 위치를'-1' 대신'0'으로 설정해야한다고 생각합니다.하지만이 작업을 한 적이 없습니다. – o11c

+0

* "/ drivers/spi 디렉토리 (spi-dw)에있는 하나의 드라이버 만 lseek를 참조합니다 ..."* - 그건 완전히 관련이없는 사실입니다. 이 디렉토리 (spidev.c 제외)는 SPI 마스터 컨트롤러 용이며 SPI 슬레이브 디바이스 용입니다. SPI 슬레이브 장치 용 SPI 프로토콜 드라이버는 해당 하위 시스템 디렉터리에 저장됩니다. IOW는 그들의 (SPI) 인터페이스가 아닌 * 기능 *에 의해 제공됩니다. * "어느 시점에서 이것이 errno 29를 반환하도록 정의됩니까?"* - ESPIPE에 대한 grep을 시도 했습니까? 잊어 버리고 코드에 ** no_llseek() ** 호출이 여전히 있습니까? – sawdust

+0

@sawdust 필자는 확실히 file_operations 구조체에서 "my_llseek()"함수를 구현했습니다. – ColoradoIcculus

답변

4

Spi 드라이버는 어떤 llseek 또는 fseek 기능도 지원하지 않습니다. 그것은 많은 콜백 함수를 가지고 있습니다.

struct spi_driver { 
    const struct spi_device_id *id_table; 
    int      (*probe)(struct spi_device *spi); 
    int      (*remove)(struct spi_device *spi); 
    void     (*shutdown)(struct spi_device *spi); 
    int      (*suspend)(struct spi_device *spi, pm_message_t mesg); 
    int      (*resume)(struct spi_device *spi); 
    struct device_driver driver; 

}}; ; S_IRUGO, dws-> debugfs의 (무효 *) DWS, & dw_spi_regs_ops) |

지금 드라이버/SPI/SPI-dw.c은 (a 전세 드라이버로 등록 debugfs_create_file ("등록"인 S_IFREG). 따라서 그들은 debugfs 파일 시스템에 파일을 생성하기 위해 구현합니다. lseek 콜백 함수를 구현합니다.

static const struct file_operations dw_spi_regs_ops = { 
    .owner   = THIS_MODULE, 
    .open   = simple_open, 
    .read   = dw_spi_show_regs, 
    .llseek   = default_llseek, 

}}; file_operations 구조체는 linux/fs.h에 정의되어 있으며 장치에서 다양한 작업을 수행하는 드라이버가 정의한 함수에 대한 포인터를 보유합니다. 구조체의 각 필드는 요청한 작업을 처리하기 위해 드라이버가 정의한 일부 함수의 주소에 해당합니다.

lseek - : lseek는 a의 읽기/쓰기 포인터 위치를 변경하는 데 사용되는 시스템 호출입니다. 파일 기술자.

SPI - : "SPI (Serial Peripheral Interface)"는 마이크로 컨트롤러를 센서, 메모리 및 주변 장치에 연결하는 데 사용되는 동기식 4 와이어 직렬 링크입니다. SPI는 lseek 및 fseek 기능을 제공 할 수 없습니다.

컨트롤러 드라이버 ... 컨트롤러는 시스템 - 온 - 칩 프로세서에 내장 할 수있다 SPI 드라이버 (https://www.kernel.org/doc/Documentation/spi/spi-summary)의 두 가지 유형, 종종 마스터 및 슬레이브 역할을 모두 지원합니다. 이 드라이버는 하드웨어 레지스터를 처리하고 DMA를 사용할 수 있습니다. 아니면 그냥 GPIO 핀이 필요한 PIO 비트 밴거 일 수 있습니다.

프로토콜 드라이버 ... 드라이버를 통해 메시지를 전달하여 SPI 링크의 다른 쪽에서 슬레이브 또는 마스터 장치와 통신합니다.

사용자가 읽고 쓰고 llseek을 원한다면 SPI 위에 전세기를 등록해야합니다. 그렇다면 당신은 당신의 습득을 성취 할 수 있습니다.

+0

-1 분명히 SPI (예 : [Documentation/spi/spi-summary] (https://www.kernel.org/doc/Documentation/spi/spi-summary))에서 Linux 문서를 읽지 않았기 때문입니다. * "Spi 드라이버 SPI 드라이버는 두 종류가 있기 때문에 성명서가 모호하여 오해의 소지가 있습니다. – sawdust

+0

네 가지 유형의 SPI 드라이버가 있지만 둘 다 lseek, SPI Protocal 드라이버를 지원하지 않습니다 file_operations 구조체는 linux/fs.h에 정의되어 있으며 디바이스에서 다양한 연산을 수행하는 드라이버가 정의한 함수에 대한 포인터를 가지고있다. 구조체의 각 필드는 드라이버가 정의한 함수의 주소와 일치한다. –

+0

내 기본으로 spidev.c를 사용하여 SPI 위에 일반 문자 드라이버를 사용하고 있다고 생각했습니다. 오늘 아침에 조금 더 파고 들었고 다음 줄을 발견했습니다. 'nonseekable_open (inode, filp); ' 그것은 범인 가능성이 높습니다! – ColoradoIcculus