Struct devicedriver platformdevice driver miscdevice fileoperations struct devicedriver

  • Slides: 21
Download presentation

알아두어야 할 구조체 Struct device_driver platform_device & driver miscdevice file_operations

알아두어야 할 구조체 Struct device_driver platform_device & driver miscdevice file_operations

struct device_driver 구조체 #include <linux/device. h> 기타 장치 파일을 등록하는데 필요한 함수를 포함 struct

struct device_driver 구조체 #include <linux/device. h> 기타 장치 파일을 등록하는데 필요한 함수를 포함 struct device_driver { const char *name; //디바이스 드라이버의 이름(필수) struct bus_type *bus; //버스 네임(필수) struct kobject kobj; //커널이 관리 struct module *owner; // 보통 THIS_MODULE int (*probe) (struct device *dev); // 초기화 루틴 int (*remove) (struct device *dev); // 디바이스 제거 루틴 int (*suspend) (struct device *dev, pm_message_t state, u 32 level); //절전모드 (필수) int (*resume) (struct device *dev, u 32 level); //절전모드 off (필수) …. 생략 };

Struct platform_device #include <platform_device> struct platform_device { const char * name; //platform_driver에 정의된 이름과

Struct platform_device #include <platform_device> struct platform_device { const char * name; //platform_driver에 정의된 이름과 같아야 한다. int id; struct devicedev; u 32 num_resources; struct resource * resource; struct platform_device_id *id_entry; /* arch specific additions */ struct pdev_archdata; };

Miscdevice 구조체 #include <linux/miscdevice. h> struct miscdevice { int minor; //Device driver minor number

Miscdevice 구조체 #include <linux/miscdevice. h> struct miscdevice { int minor; //Device driver minor number (지정하지 않을시 커널이 동적으로 할당) const char *name; //device file Name const struct file_operations *fops; // 파일 연산을 할 때 호출될 함수 정의 … 생략 }

struct file_operations 구조체 struct file_operations { struct module *owner; //보통 THIS_MODULE ssize_t (*read) (struct

struct file_operations 구조체 struct file_operations { struct module *owner; //보통 THIS_MODULE ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); // Read와 Write만으로 구현하기 곤란한 입출력 처리 int (*open) (struct inode *, struct file *); // 응용 프로그램에서 디바이스를 처음 사용하는 경우(필수) int (*release) (struct inode *, struct file *); // 종료 …. 생략 };

ADC Platform_driver static struct platform_driver s 3 c_adc_driver = {. probe = s 3

ADC Platform_driver static struct platform_driver s 3 c_adc_driver = {. probe = s 3 c_adc_probe, . remove = s 3 c_adc_remove, . suspend = s 3 c_adc_suspend, . resume = s 3 c_adc_resume, . driver ={. owner = THIS_MODULE, . name = "s 3 c-adc", }, };

Device Dirver Init 어떤 디바이스 드라이버든지 최초는 Init 함수를 통한 등록이다. int __init s

Device Dirver Init 어떤 디바이스 드라이버든지 최초는 Init 함수를 통한 등록이다. int __init s 3 c_adc_init(void){ printk(banner); return platform_driver_register(&s 3 c_adc_driver); } // Platform_driver 등록 } module_init(s 3 c_adc_init);

Probe 함수가 호출되기 전에! /kernel/arch/arm/plat-s 5 p/devs. c static struct resource s 3 c_adc_resource[]

Probe 함수가 호출되기 전에! /kernel/arch/arm/plat-s 5 p/devs. c static struct resource s 3 c_adc_resource[] = { [0] = {. start = S 3 C_PA_ADC, // ADC Register주소. end = S 3 C_PA_ADC + SZ_4 K - 1, // 주소 마지막 값. flags = IORESOURCE_MEM, // resource type }, #include <mach/map. h> #define S 3 C_PA_ADC S 3 C_ADDR(0 x. E 1700000) // 주소값 정의

Probe 함수가 호출되기 전에! struct platform_device s 3 c_device_adc = {. name = "s

Probe 함수가 호출되기 전에! struct platform_device s 3 c_device_adc = {. name = "s 3 c-adc", //platform_driver와 이름이 같아야 한다. . id = -1, // 여러 개의 플랫폼 디바이스가 있을경우 id로 구분. num_resources = ARRAY_SIZE(s 3 c_adc_resource), //리소스 테이블 수. resource = s 3 c_adc_resource, 리소스 테이블 시작 주소 };

Probe 함수가 호출되기 전에! /kernel/arch/arm/mach-s 5 pv 210/mach-mango 210. c static struct platform_device *mango

Probe 함수가 호출되기 전에! /kernel/arch/arm/mach-s 5 pv 210/mach-mango 210. c static struct platform_device *mango 210_devices[] __initdata = { &s 3 c_device_adc, // platform_device name 매칭 } static void __init mango 210_machine_init(void){ s 3 c_adc_set_platdata(&s 3 c_adc_platform); platform_add_devices(mango 210_devices, ARRAY_SIZE(mango 210_devices)); // 플랫폼 등록 } 위와같이 최종적으로 Platform 디바이스 드라이버의 등록이 되고 Probe함수가 동작된다.

ADC Probe 조금더 상세하게 들어가서 Probe함수는 어떤 동작을 하는가 보자 static int __init s

ADC Probe 조금더 상세하게 들어가서 Probe함수는 어떤 동작을 하는가 보자 static int __init s 3 c_adc_probe(struct platform_device *pdev) { struct resource *res; struct device *dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); //리소스(디바이스에 할당된 자원 범위) 가져오기 dev = &pdev->dev; //// pdev 라는 플랫폼 디바이스의 멤버들을 dev 의 멤버들로 cast 시킨 다. 따라서 pdev는 dev를 가르키게 된다 <platform_device. h> extern struct resource *platform_get_resource (struct platform_device *, //플랫폼 디바이스 네임 unsigned int, // flags unsigned int);

ADC Probe static struct resource *adc_mem; // Global define static void __iomem *base_addr; //

ADC Probe static struct resource *adc_mem; // Global define static void __iomem *base_addr; // Global define ////static void __iomem 변수명 선언을 하는 이유 Writel, readl 같은 core register접근 함수에 위와같은 데이터형으로 선언이 되어있기 때문이다. size = (res->end - res->start) + 1; // 메모리 사이즈 설정 base_addr = ioremap(res->start, size); // 가상 메모리 번지 생성 adc_clock = clk_get(&pdev->dev, "adc"); // 클럭 생산자 생성 clk_enable(adc_clock); … 생략 (생략 내용 : prescaler, delay 등등 register init) ret = misc_register(&s 3 c_adc_miscdev); //miscdevice와 매칭을 한다.

Miscdevice static struct miscdevice s 3 c_adc_miscdev = {. minor = ADC_MINOR, . name

Miscdevice static struct miscdevice s 3 c_adc_miscdev = {. minor = ADC_MINOR, . name = "adc", //device file name. fops = &s 3 c_adc_fops, }; Miscdev 등록이 끝나면 File. System 상에서 /dev/adc라는 디바이스 파일이 생성이 되어있다. 이것은 /etc/udev의 규칙파일에 의해서 자 동적으로 된다.