컴퓨터 지식 네트워크 - 컴퓨터 구성 - 리눅스 spi 장치 드라이버에서 프로브 기능은 언제 호출됩니까?

리눅스 spi 장치 드라이버에서 프로브 기능은 언제 호출됩니까?

지난 이틀 동안 기기 파일에 미쳐 있었는데, 그것에 대해 많이 알지 못했다고 자책했습니다. 며칠 동안 작업한 끝에 마침내 정리할 수 있었습니다. 장치 등록이 조금 필요합니다. 잊지 않도록 spi 하위 장치 등록을 예로 들어 요약해 보겠습니다.

먼저 spidev 장치 등록을 예로 들어 보겠습니다.

static struct spi_board_info imx5_spi_printer_device[] __initdata =

{

{

p>

.modalias = "spidev",

.max_speed_hz = 8000000,

.bus_num = 1,

. Chip_select = 1,

p>

.mode = SPI_MODE_0,

},

};

spi_register_board_info(imx5_spi_printer_device,ARRAY_SIZE(imx5_spi_printer_device) ));

mx5_loco.c 파일에 위의 구조 spi_board_info를 추가합니다. Modalias는 기존 드라이버를 지정해야 합니다. 여기에는 상위 드라이버의 Bus_num이 있어야 합니다. 이는 상위 클래스의 bus_num과 일치해야 합니다. 그렇지 않으면 장치 파일을 생성할 수 없습니다. spi에 클럭 신호가 없으면 버스 번호가 잘못되었을 가능성이 높습니다.

시스템이 시작되면 spidev1.1이라는 장치 파일이 /dev 디렉터리에 나타납니다. 이 파일을 읽고 쓰면 spi 작업을 구현할 수 있습니다.

다음과 같은 경우도 있습니다. :

static struct spi_board_info prt_spi_device[] __initdata = {

{

.modalias = "HotPRT",

.max_speed_hz = 12500000 , /* 최대 spi 클럭(SCK) 속도(HZ) */

.bus_num = 1,

.chip_select = 1,

// . SPI_MODE_0,

.platform_data = 0,

},

};

spi_register_board_info(prt_spi_device, ARRAY_SIZE(prt_spi_device)) ;

Spi 드라이버를 직접 구현한 후 장치 파일을 생성해야 했습니다. 프로브에서 장치 파일 생성이 완료되었습니다.

static struct spi_driver prt_driver = {

.driver = {

.name = "HotPRT",

.bus = &spi_bus_type,

.owner = THIS_MODULE,

},

.probe = prt_probe,

.remove = __devexit_p(prt_remove),

p>

p>

};

spi_register_driver(&prt_driver);

그런데 처음에 프로브를 촉발할 수가 없어서 계속 검색하다가 결국 나는 다음과 같이 프로브의 호출 프로세스를 알고 있었습니다:

int spi_register_driver(struct spi_driver *sdrv)

{

sdrv->driver.bus = &spi_bus_type ;

if (sdrv-> 프로브)

sdrv->driver.probe = spi_drv_probe;

if (sdrv->remove)

sdrv->driver.remove = spi_drv_remove;

p>

if (sdrv->종료)

sdrv->driver.shutdown = spi_drv_shutdown;

return driver_register(&sdrv->driver);

}

그런 다음 drivers_register를 호출하세요

intdriver_register( struct device_driver *drv)

{

int ret;

struct device_driver *other;

BUG_ON(!drv->bus- >p);

if ((drv ->버스->탐색 && drv->탐색) ||

(drv->버스->제거 && drv->제거) ||

(drv->bus- >shutdown && drv->shutdown))

printk(KERN_WARNING "'%s' 드라이버를 업데이트해야 합니다 - 다음을 사용하십시오. "

"bus_type 메소드\n", drv->name) ;

other = 드라이버_find(drv->name, drv->bus);

if (other) {

put_driver(other);

printk(KERN_ERR "오류: '%s' 드라이버가 이미 등록되었습니다. "

"중단하는 중...\n" , drv->이름);

return -EBUSY;

}

ret =bus_add_driver(drv);

if (ret )

ret 반환;

ret = 드라이버_추가_그룹(drv, drv->그룹);

if (ret)

버스_제거_드라이버( drv);

return ret;

p>

}

bus_add_driver를 직접 살펴보세요

klist_init(&priv->klist_devices, NULL, NULL);

priv->driver = drv;

drv->p = priv;

priv->kobj.kset = 버스->p- >drivers_kset;

error = kobject_init_and_add(&priv->kobj , &driver_ktype, NULL,

"%s", drv->name);

if ( error)

goto out_unregister;

if (drv->bus->p->drivers_autoprobe) {

error = drivers_attach(drv);

if (오류)

goto out_unregister;

}

klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);

module_add_driver(drv->owner, drv);

p>

여기서 일부만 가로채고 마지막 호출은 driver_attach입니다.

intdriver_attach( struct device_driver * drv)

{

return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);

}

실제로 작동하는 것은 __driver_attach:

static int __driver_attach(struct device * dev, void * data)

{

입니다. . .

if (!dev->driver)

driver_probe_device(drv, dev);

. . .

}

intdriver_probe_device(struct device_driver * drv, struct device * dev)

{

. . .

//1. 먼저 버스가 일치하는지 확인합니다:

if (drv->bus->match && !drv->bus->match(dev, drv))< / p>

완료;

//2. 구체적으로 프로브를 실행합니다:

ret = really_probe(dev, drv);

. . .

}

really_probe는 우리가 찾고 있는 함수입니다:

static int really_probe(struct device *dev, struct device_driver *drv)

{

. . .

//1. 먼저 드라이버가 속한 버스의 프로브 기능을 호출합니다:

if (dev->bus->probe) {

ret = dev->bus->probe(dev);

if (ret)

goto|probe_failed;

} else if (drv->probe) {

//2. 그런 다음 드라이버에서 프로브 기능을 호출합니다:

ret = drv->probe(dev);

if (ret)

probe_failed로 이동;

}

. . .

}

그 중 drv->probe(dev)는 실제로 드라이버 구현을 호출하는 특정 프로브 함수입니다. 이 시점에서 프로브 함수가 호출됩니다.

보드 파일에 spi_board_info를 추가하고, 보드 파일에 spi_board_info를 추가하세요

上篇: 중국어로 음성은 무엇을 뜻하나요? 下篇: videoleap은 어떻게 동영상을 더 선명하게 만들어 주나요?
관련 내용