SPI 구동 의 서브 시스템 구조 및 중요 데이터 구조
11333 단어 링크 ux 드라이버 의-spi
1. SPI 서브 시스템 구조 상세 설명
SPI 버스 에는 두 가지 장치 가 있 습 니 다. 하 나 는 주 제어 단 입 니 다. 보통 SOC 시스템 의 키 모듈 로 나타 납 니 다. 예 를 들 어 많은 내장 형 MPU 에는 SPI 모듈 이 자주 포함 되 어 있 습 니 다.하 나 는 SPI 인터페이스의 Flash, 센서 등 제어 단 이다.주 제어 단 은 SPI 버스 의 제어 자 입 니 다. SPI 프로 토 콜 을 사용 하여 SPI 버스 의 세 션 을 주동 적 으로 시작 하고 제어 단 은 SPI 주 제어 단의 명령 을 수 동적 으로 받 아들 여 해당 하 는 응답 을 합 니 다.
그림 이 아직 다 그 려 지지 않 았 는데, 나중에 보충 하고, 보충 한 후에 분석 을 좀 써 라, 하하...
2. 중요 데이터 구조
(1)spi_master
struct spi_master 는 SPI 메 인 컨트롤 러 를 설명 하 는 데 사 용 됩 니 다. 우 리 는 일반적으로 spi 컨트롤 러 구동 을 직접 작성 할 필요 가 없습니다.
/**
* master SPI , SPI ,
* SPI ,master->bus_num 。
*/
struct spi_master {
struct device dev;
struct list_head list;
/**
* , 。
* board_list boardinfo spi_board_info bus_num ,
* ( boardinfo spi_board_info , spi_board_info SPI( ) )
* spi_board_info SPI( ) , spi_new_device spi_device。
*/
s16 bus_num;
/* 。 . 0, */
u16 num_chipselect;
/* some SPI controllers pose alignment requirements on DMAable
* buffers; let protocol drivers know about these requirements.
*/
u16 dma_alignment;
/* spi_device.mode flags understood by this controller driver */
u16 mode_bits;
/* other constraints relevant to this driver */
u16 flags;
#define SPI_MASTER_HALF_DUPLEX BIT(0) /* can't do full duplex */
#define SPI_MASTER_NO_RX BIT(1) /* can't do buffer read */
#define SPI_MASTER_NO_TX BIT(2) /* can't do buffer write */
/* lock and mutex for SPI bus locking */
spinlock_t bus_lock_spinlock;
struct mutex bus_lock_mutex;
/* flag indicating that the SPI bus is locked for exclusive use */
bool bus_lock_flag;
int (*setup)(struct spi_device *spi); // spi
/**
* 。 , ,
* ( ) spi_message complete , 。
*/
int (*transfer)(struct spi_device *spi, struct spi_message *mesg);
/*cleanup spidev_release ,spidev_release spidev release */
void (*cleanup)(struct spi_device *spi);
};
spi 컨트롤 러 의 구동 은 kernel 3.0.15 / arch / arm / mach - exynos / mach - smdk4x 12. c 에서 플랫폼 장 치 를 설명 하고 등록 한 다음 kernel 3.0.15 / driver / spi 아래 플랫폼 구동 을 구축 합 니 다.spi_master 등록 과정 에서 kernel 3.0.15 / arch / arm / mach - exynos / mach - smdk4x 12. c 에서 spi 를 호출 합 니 다.register_board_info 등 록 된 정 보 는 본 버스 번호 와 같은 모든 정보 에 spi 를 만 듭 니 다.device。리 눅 스 커 널 의 구동 모델 에 따라 같은 버스 에 등 록 된 구동 과 장치 가 일치 합 니 다.spi_bus_type 버스 가 일치 하 는 근 거 는 이름 입 니 다. 이렇게 자신 이 작성 한 spidriver 와 spidevice 동명 일 때 spidriver 의 probe 방법 이 사 용 됩 니 다. spidriver 는 자신 과 일치 하 는 spi 를 볼 수 있 습 니 다.장치 입 니 다.
(2)spi_device
struct spi_device 는 장치 에서 SPI 를 설명 하 는 데 사 용 됩 니 다.
/**
* SPI , 。
* :SPI , SOC SPI master ,
* slave 。
*/
struct spi_device {
struct device dev;
struct spi_master *master; //
u32 max_speed_hz; //spi
u8 chip_select; // ,
u8 mode; // bit , /
#define SPI_CPHA 0x01 /* clock phase */
#define SPI_CPOL 0x02 /* clock polarity */
#define SPI_MODE_0 (0|0) /* (original MicroWire) */
#define SPI_MODE_1 (0|SPI_CPHA)
#define SPI_MODE_2 (SPI_CPOL|0)
#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
#define SPI_CS_HIGH 0x04 /* chipselect active high? */ //
#define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */ //
#define SPI_3WIRE 0x10 /* SI/SO signals shared */ // ,
#define SPI_LOOP 0x20 /* loopback mode */
#define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */
#define SPI_READY 0x80 /* slave pulls low to pause */
u8 bits_per_word; //
int irq; //
void *controller_state;
void *controller_data;
char modalias[SPI_NAME_SIZE]; //spi
/*
* likely need more hooks for more protocol options affecting how
* the controller talks to each chip, like:
* - memory packing (12 bit samples into low bits, others zeroed)
* - priority
* - drop chipselect after each word
* - chipselect delays
* - ...
*/
};
(3)spi_driver
struct spi_driver 는 SPI 가 장치 에서 구동 되 는 것 을 설명 하 는 데 사 용 됩 니 다.구동 핵심 은 driver. name 과 spi 에 따라board_info 의 modalias 가 일치 합 니 다. modalias 와 name 이 같 으 면 바 인 딩 드라이버 와 kernel 3.0.5 / arch / arm / mach - exynos / mach - smdk4x 12. c 에서 spi 를 호출 합 니 다.register_board_info 등 록 된 정보 에 대응 하 는 spi장치 장치.그것들의 형식 과 struct platformdriver 는 일치 합 니 다.
struct spi_driver {
const struct spi_device_id *id_table; // ,
int (*probe)(struct spi_device *spi); // spi_device .
int (*remove)(struct spi_device *spi); // spi_device spi_driver , probe
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;
};
(4) spi_transfer
struct spi_transfer 는 완전한 데이터 전송 에 대한 설명 입 니 다.각 spitransfer 는 항상 같은 길이 의 비트 수 를 읽 고 기록 하지만 빈 포인터 로 읽 거나 쓸 수 있 습 니 다. spi 입 니 다.transfer 와 spi메시지 가 분 배 된 메모 리 는 메시지 처리 기간 에 완전 하 게 보장 되 어야 합 니 다.
struct spi_transfer {
/* it's ok if tx_buf == rx_buf (right?)
* for MicroWire, one buffer must be null
* buffers must work with dma_*map_single() calls, unless
* spi_message.is_dma_mapped reports a pre-existing mapping
*/
const void *tx_buf; // ( dma_safe), NULL
void *rx_buf; // ( dma_safe), NULL
unsigned len; //tx tr ( ), , ,
dma_addr_t tx_dma; // spi_message.is_dma_mapped , tx dma
dma_addr_t rx_dma; // spi_message.is_dma_mapped , rx dma
unsigned cs_change:1; // , transfer setup
u8 bits_per_word; // , 0,
u16 delay_usecs; // ,
u32 speed_hz; // , 0,
struct list_head transfer_list; //
};
(5)spi_message
struct spi_message 는 여러 spitransfer 패키지.소식 을 전 할 때 spitransfer 자신의 transfer 를 통 해list 필드 spimessage 의 transfers 링크 머리 에 있 습 니 다.spi_message 원자 실행 spitransfer 가 표시 하 는 일련의 배열 전송 요청이 전송 대기 열 은 원자 입 니 다. 이 메시지 가 완성 되 기 전에 다른 메시지 가 버스 를 차지 하지 않 는 다 는 것 을 의미 합 니 다.메시지 의 실행 은 항상 FIFO 의 순서에 따라 밑 에 spi 를 제출 합 니 다.message 의 코드 는 메모리 공간 을 관리 해 야 합 니 다.초기 화 되 지 않 은 메모 리 는 0 을 사용 하여 초기 화 해 야 합 니 다.위 spitransfer 와 spi메시지 가 분 배 된 메모 리 는 메시지 처리 기간 에 완전 하 게 보장 되 어야 합 니 다.
struct spi_message {
struct list_head transfers; // ,
struct spi_device *spi; //
unsigned is_dma_mapped:1; // , dma cpu
/* REVISIT: we might want a flag affecting the behavior of the
* last transfer ... allowing things like "read 16 bit length L"
* immediately followed by "read L bytes". Basically imposing
* a specific message scheduling algorithm.
*
* Some controller drivers (message-at-a-time queue processing)
* could provide that as their default scheduling algorithm. But
* others (with multi-message pipelines) could need a flag to
* tell them about such special cases.
*/
/* completion is reported through a callback */
void (*complete)(void *context); //
void *context; //
unsigned actual_length; //
int status; // , 0,
/* for optional use by whatever driver currently owns the
* spi_message ... between calls to spi_async and then later
* complete(), that's the spi_master controller driver.
*/
struct list_head queue;
void *state;
};
(6) 두 가지 중요 한 판 급 구조
두 개의 판 급 구조, 그 중 spiboard_info spi 초기 화 에 사용device,s3c64xx_spi_info spi 초기 화 에 사용master。이 두 판 급 의 구 조 는 이식 할 때 kernel 3.0.15 / arch / arm / mach - exynos / mach - smdk4x 12. c 에서 초기 화 되 어야 합 니 다.
spi_board_info(kernel3.0.15/linux/include/spi/spi.h)
/* SPI (spi_device) , , SPI spi_device */
struct spi_board_info {
/* the device name and module name are coupled, like platform_bus;
* "modalias" is normally the driver name.
*
* platform_data goes to spi_device.dev.platform_data,
* controller_data goes to spi_device.controller_data,
* irq is copied too
*/
char modalias[SPI_NAME_SIZE]; //spi , spi_device . spi_device SPI spi_bus_type
const void *platform_data; //
void *controller_data;
int irq; //
/* slower signaling on noisy or low voltage boards */
u32 max_speed_hz; //SPI
/* bus_num is board specific and matches the bus_num of some
* spi_master that will probably be registered later.
*
* chip_select reflects how this chip is wired to that master;
* it's less than num_chipselect.
*/
u16 bus_num; // SPI( ) , spi_master bus_num . spi_master
u16 chip_select; // . SPI( ) SPI
/* mode becomes spi_device.mode, and is essential for chips
* where the default of SPI_CS_HIGH = 0 is wrong.
*/
u8 mode; // spi_device
/* ... may need additional spi_device chip config data here.
* avoid stuff protocol drivers can set; but include stuff
* needed to behave without being bound to a driver:
* - quirks like clock rate mattering when not selected
*/
};
s3c64xx_spi_info(kernel3.0.15/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h) struct s3c64xx_spi_info {
int src_clk_nr;
char *src_clk_name;
bool clk_from_cmu;
int num_cs; //
int (*cfg_gpio)(struct platform_device *pdev);
/* Following two fields are for future compatibility */
int fifo_lvl_mask;
int rx_lvl_offset;
int high_speed;
int tx_st_done;
};
boardinfo 는 spi 를 관리 하 는 데 쓰 인 다board_info 의 구조, spiboard_info 판 급 파일 에서 spiregister_board_info (struct spi board info const * info, unsigned n) 는 board info 에 의 해 관리 되 고 board 에 걸 립 니 다.리스트 링크 에.
boardinfo(kernel3.0.15/drivers/spi/spi.c)
struct boardinfo {
struct list_head list; // board_list
struct spi_board_info board_info; // spi_board_info
};
spi_register_board_info(kernel3.0.15/drivers/spi/spi.c) int __init
spi_register_board_info(struct spi_board_info const *info, unsigned n)
{
struct boardinfo *bi;
int i;
bi = kzalloc(n * sizeof(*bi), GFP_KERNEL);
if (!bi)
return -ENOMEM;
for (i = 0; i < n; i++, bi++, info++) {
struct spi_master *master;
memcpy(&bi->board_info, info, sizeof(*info));
mutex_lock(&board_lock);
list_add_tail(&bi->list, &board_list);
list_for_each_entry(master, &spi_master_list, list)
spi_match_master_to_boardinfo(master, &bi->board_info);
mutex_unlock(&board_lock);
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
RabbitMQ 대기열 선언 channel.queueDeclare () 매개변수 분석durable = false 시 대기열이 비지구화됩니다.대기열은 메모리에 저장되어 있기 때문에 RabbitMQ가 리셋되거나 서버가 리셋될 때 이 대기열을 잃어버립니다. durable = true 시 대기열이 지속됩니...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.