IT/리눅스마스터1급

probe 구조체 platform_driver, platform_device

알콩달콩아빠 2022. 5. 2. 10:27
728x90
반응형
Platform device 등록 방법.
 
아래 방법은 별도의 파일을 만들어 컴파일....
 
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/platform_device.h>
 
#define NAME "batt_dev"
 
static struct platform_device batte_device = { 
    .name   =       NAME,
    .id     =       -1,     //
};
 
static struct platform_device *rt_batte_devices[] __initdata = { 
    &batte_device,
};
 
int __init init_rt_batt(void)
{
    platform_add_devices(rt_batte_devices, ARRAY_SIZE(rt_batte_devices));
    return 0;
}
device_initcall(init_rt_batt);
 
platform_device의 id값은 

디바이스가 하나만 일 경우  -1 로 설정.

2개 이상일 경우 id 는 0 부터 시작해서 각 디바이스마다  고유한 값을 설정. (대게 1씩 순서대로 값을 넣는다.)

 

 

[ device_initcall(init_rt_batt);

디바이스 드라이버는 module_init() 호출로 마지막 커널에 적재 되는데....

인자에 따라 

1. 모듈이 아닌 정적으로 링크.

- device_initcall()에 의해서 init6.init 섹션에 등록되어 커널 초기화 과정에서 등록.

2. 모듈일 경우 모듈 드라이버 로딩 과정에서 호출 할수 있도록 함.

- inittest라는 static 함수 생성 후, 이를 모듈 드라이버 로딩 과정에서 호출 할 수 있도록 해줌.

 

더 자세한 내용은 -> http://blog.naver.com/jjong_w/60161193500

 

platform_device 구조체에는 디바이스와 보드간 연결된 실제 물리메모리를 리소스 변수에 초기화 한다.  platform_device .name변수는 platform_driver구조체(2.6.15미만 버젼에서는 device_driver구조체라고 알고있음) 에서 사용하는 .name변수와 매칭되어야 platform_driver의 probe함수가 호출된다.

 

smdk2440_devices[]는 다음함수를 통해 차례대로 platform_device를 등록하게 된다.

platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));

 

[ platform_add_devices()       여러개의 디바이스들을 한번에 등록

  platform_device_register()   하나의 디바이스를 등록 ]

 

 

 

 

#include <linux/init.h>

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/interrupt.h>

//#include <linux/fs.h>

#include <linux/platform_device.h>

#include <linux/device.h>

 

 

#define NAME    "batt_dev"

 

#define DBG1 printk("[___%s___] : line (%d)\n", __func__, __LINE__);

#define DBG2 printk("[___%s___] : line (%d) _ ", __func__, __LINE__);

 

static int __init batt_probe(struct platform_device *pdev)

{

 

    DBG1;

    return 0;

}

 

static int __exit batt_remove(struct platform_device *pdev)

{

    DBG1;

    return 0;

}

 

static struct platform_driver batt_driver = { 

    .driver     = { 

        .name   = NAME,

        .owner  = THIS_MODULE,

    },  

    .probe      = batt_probe,

    .remove     = batt_remove,

    .suspend    = NULL,

    .resume     = NULL,

};

 

int __init init_button()

{

    DBG1;

                                                                                                                                                        

    ret = platform_driver_register(&batt_driver);
    DBG2;
    printk("return : %d \n", ret);
 
    return ret;
}
 
void __exit exit_button()
{
    DBG1;
}
module_init(init_button);
module_exit(exit_button);
 

자세한 내용은 -> http://blog.naver.com/jjong_w/60158536044

 

 

[출처] http://forum.falinux.com/zbxe/?document_srl=567697

이제  커널의 driver  디렉토리의 무수한 소스파일들을 보자 

모두다  struct platform_driver  구조체를 품고 있다.

이제 struct platform_driver 구조체의 주요한 멤버를 보자

  • probe         초기 실행함수
  • remove       드라이버 제거시 실행되는 함수
  • driver  =  {  .name       드라이버 이름

이 구조체는  platform_driver_register() 함수를 통해 등록된다.

 

 

이제 흐름을 따라가 보자

커널 시작시 디바이스들이 등록된다.  리소스가 등록되는 것이다.  UART칩이  16개 있다면 디바이스가 16 등록된다.

잠시후에 커널 드라이버가 등록된다.  이때 드라이버의 이름과 동일한 디바이스의 이름이 발견되면 probe() 함수가 호출된다.

동일한 이름의 디바이스가 16개 있다면 이 probe() 함수가 16번 호출된다.

 

참고해야 할것은 struct platform_device 구조체의 id 이다.

디바이스가 하나만 있다면 이값은 -1 로 설정한다.  하지만 2개 이상일 경우 id 는 0 부터 시작해서 각 디바이스마다  고유한 값을 넣는다.,

대게 1씩 순서대로 값을 넣는다.

 

struct platform_device 의 멤버 name 과  struct platform_driver 의  멤버 driver.name 은 동일한 값을 갖는다.

디바이스가 하나일 경우 디바이스의 이름과  드라이버의 이름은 같다.

하지만 디바이스가 여러개 일 경우  드라이버 이름은 보이는 대로의 이름이지만

디바이스의 경우   uart.0   uart.1  이렇게  숫자를 달고 나온다.   id 로 확장된 것이다.

아래의 매크로를 이용하여 디바이스 이름을 얻는다.

  • dev_name(&platform_device->dev)
728x90
반응형

'IT > 리눅스마스터1급' 카테고리의 다른 글

pcap  (0) 2022.05.02
soap  (0) 2022.05.02
am 명령어  (0) 2022.04.29
i/o 스케줄러  (0) 2022.04.29
프로세스 스케줄링  (0) 2022.04.28