《linux驱动:s3c2410_ts/s3c2440_ts模块加载流程》

发布者:HarmoniousCharm最新更新时间:2024-07-09 来源: elecfans关键字:linux驱动 手机看文章 扫描二维码
随时随地手机看文章

前言

通过分析s3c2410_ts/s3c2440_ts模块加载流程,分析linux驱动中的总线-设备-驱动模型以及输入子系统框架。

主要流程分析图示

s3c2440_ts 主要流程分析




系统初始化

MACHINE_START(SMDK2410,'SMDK2410')

MACHINE_START(SMDK2410, 'SMDK2410') /* @TODO: request a new identifier and switch

    * to SMDK2410 */

/* Maintainer: Jonas Dietsche */

.phys_io = S3C2410_PA_UART,

.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

.boot_params = S3C2410_SDRAM_PA + 0x100,

.map_io = smdk2410_map_io,

.init_irq = s3c24xx_init_irq,

.init_machine = smdk2410_init,

.timer = &s3c24xx_timer,

MACHINE_END

将上面的宏展开:


static const struct machine_desc __mach_desc_SMDK2410

 __attribute_used__

 __attribute__((__section__('.arch.info.init'))) = {

 .nr = MACH_TYPE_SMDK2410, /* architecture number */

 .name = 'SMDK2410', /* architecture name */

 /* Maintainer: Jonas Dietsche */

 .phys_io = S3C2410_PA_UART, /* start of physical io */

 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,

 .boot_params = S3C2410_SDRAM_PA + 0x100, /* tagged list */

 .map_io = smdk2410_map_io, /* IO mapping function */

 .init_irq = s3c24xx_init_irq,

 .init_machine = smdk_machine_init,

 .timer = &s3c24xx_timer,

MACHINE_START主要是定义了'struct machine_desc'的类型,放在 section('.arch.info.init'),是初始化数据,Kernel 起来之后将被丢弃。各个成员函数在不同时期被调用:

1. init_machine 在 arch/arm/kernel/setup.c 中被 customize_machine 调用,放在 arch_initcall() 段里面,会自动按顺序被调用;

2. init_irq在start_kernel() -> init_IRQ() -> init_arch_irq() 被调用;

3. map_io 在 setup_arch() -> paging_init() -> devicemaps_init()被调用;

其他主要都在 setup_arch() 中用到;

smdk2410_init

static void __init smdk2410_init(void)

{

        s3c24xx_fb_set_platdata(&smdk2410_lcd_cfg);

platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));

smdk_machine_init();

}

smdk_machine_init

void __init smdk_machine_init(void)

{

/* Configure the LEDs (even if we have no LED support)*/


s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);

s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP);

s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP);

s3c2410_gpio_cfgpin(S3C2410_GPF7, S3C2410_GPF7_OUTP);


s3c2410_gpio_setpin(S3C2410_GPF4, 1);

s3c2410_gpio_setpin(S3C2410_GPF5, 1);

s3c2410_gpio_setpin(S3C2410_GPF6, 1);

s3c2410_gpio_setpin(S3C2410_GPF7, 1);


if (machine_is_smdk2443())

smdk_nand_info.twrph0 = 50;


s3c_device_nand.dev.platform_data = &smdk_nand_info;

#ifdef CONFIG_TOUCHSCREEN_S3C2410

set_s3c2410ts_info(&s3c2410_ts_cfg);

#endif

platform_add_devices(smdk_devs, ARRAY_SIZE(smdk_devs));


s3c2410_pm_init();

}

platform_add_devices

int platform_add_devices(struct platform_device **devs, int num)

{

int i, ret = 0;


for (i = 0; i < num; i++) {

ret = platform_device_register(devs[i]);

if (ret) {

while (--i >= 0)

platform_device_unregister(devs[i]);

break;

}

}


return ret;

}

platform_device_register注册smdk_devs数组中的各设备

static struct platform_device __initdata *smdk_devs[] = {

&s3c_device_nand,

&smdk_led4,

&smdk_led5,

&smdk_led6,

&smdk_led7,

#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)

    &s3c_device_dm9k,

#endif    

#ifdef CONFIG_SERIAL_EXTEND_S3C24xx

    &s3c_device_8250,

#endif

#ifdef CONFIG_TOUCHSCREEN_S3C2410

&s3c_device_ts,

#endif

};

自此,s3c_device_ts设备被注册到平台总线。

内核加载触摸模块

编译进内核加载驱动

编译内核设置,make menuconfig

Symbol: TOUCHSCREEN_S3C2410 [=y]                                                                                                                                           │   

  │ Prompt: S3C2410/S3C2440 touchscreens                                                                                                                                       │   

  │   Defined at drivers/input/touchscreen/Kconfig:14                                                                                                                          │   

  │   Depends on: !S390 && INPUT && INPUT_TOUCHSCREEN                                                                                                                          │   

  │   Location:                                                                                                                                                                │   

  │     -> Device Drivers                                                                                                                                                      │   

  │       -> Input device support                                                                                                                                              │   

  │         -> Generic input layer (needed for keyboard, mouse, ...) (INPUT [=y])                                                                                              │   

  │           -> Touchscreens (INPUT_TOUCHSCREEN [=y])  

然后make uImage,将s3c2410_ts驱动编译进内核,系统启动便会加载,即执行驱动的s3c2410ts_init函数。

驱动被加载调用其初始化函数s3c2410ts_init

static int __init s3c2410ts_init(void)

{

// init_MUTEX(&gADClock);

return platform_driver_register(&s3c2410ts_driver);

}

s3c2410ts_driver结构体

static struct platform_driver s3c2410ts_driver = {

       .driver         = {

       .name   = 's3c2410-ts',

       .owner  = THIS_MODULE,

       },

       .probe          = s3c2410ts_probe,

       .remove         = s3c2410ts_remove,

};

自此,s3c2410_ts驱动被注册到平台总线。

平台总线-设备-驱动模型

s3c2410_ts设备通过platform_device_register注册到平台总线。

s3c2410_ts驱动通过platform_driver_register注册到平台总线。

在总线层处,调用s3c2410_ts驱动的probe函数。

调用s3c2410_ts驱动的probe函数的过程

platform_driver_register->

driver_register->

bus_add_driver->

driver_attach->

bus_for_each_dev->

__driver_attach->

driver_probe_device->

really_probe->

drv->probe(dev)

__driver_attach(kernel 2.6.22)

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

{

struct device_driver * drv = data;


/*

* Lock device and try to bind to it. We drop the error

* here and always return 0, because we need to keep trying

* to bind to devices and some drivers will return an error

* simply if it didn't support the device.

*

* driver_probe_device() will spit a warning if there

* is an error.

*/


if (dev->parent) /* Needed for USB */

down(&dev->parent->sem);

down(&dev->sem);

if (!dev->driver)

driver_probe_device(drv, dev);

up(&dev->sem);

if (dev->parent)

up(&dev->parent->sem);


return 0;

}

__driver_attach(kernel 3.4)

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

{

struct device_driver *drv = data;


/*

* Lock device and try to bind to it. We drop the error

* here and always return 0, because we need to keep trying

* to bind to devices and some drivers will return an error

* simply if it didn't support the device.

*

* driver_probe_device() will spit a warning if there

* is an error.

*/


if (!driver_match_device(drv, dev))

return 0;


if (dev->parent) /* Needed for USB */

device_lock(dev->parent);

[1] [2]
关键字:linux驱动 引用地址:《linux驱动:s3c2410_ts/s3c2440_ts模块加载流程》

上一篇:《Linux驱动:s3c2410/s3c2440 ts驱动分析》
下一篇:嵌入式学习笔记之点亮一个LED

推荐阅读最新更新时间:2024-11-04 13:10

Linux-2.6.32.2内核在mini2440上的移植(三)---DM9000网卡驱动移植
移植环境 1,主机环境:VMare下CentOS 5.5 ,1G内存。 2,集成开发环境:Elipse IDE 3,编译编译环境:arm-linux-gcc v4.4.3,arm-none-linux-gnueabi-gcc v4.5.1。 4,开发板:mini2440,2M nor flash,128M nand flash。 5,u-boot版本:u-boot-2009.08 6,linux 版本:linux-2.6.32.2 7,参考文章: 【1】嵌入式linux应用开发完全手册,韦东山,编著。 【2】Mini2440 之Linux 移植开发实战指南 【3】 http://linux.chinaunix.net/techd
[单片机]
<font color='red'>Linux</font>-2.6.32.2内核在mini2440上的移植(三)---DM9000网卡<font color='red'>驱动</font>移植
Linux设备驱动开发 - 混杂设备驱动
混杂设备共享一个主设备号MISC_MAJOR(10),次设备号不同。 混杂设备本质上仍然是一个字符设备,所以混杂设备的操作跟字符设备基本相同。 在字符设备中,描述字符设备的结构体为struct cdev,在混杂设备中同样有一个描述混杂设备的结构体struct miscdevice。 1 struct miscdevice { 2 int minor; /* 次设备号 */ 3 const char *name; /* 设备名 */ 4 const struct file_operations *fops; /* 文件操作 */ 5 struct list
[单片机]
<font color='red'>Linux</font>设备<font color='red'>驱动</font>开发 - 混杂设备<font color='red'>驱动</font>
linux驱动程序之电源管理之标准linux休眠和唤醒机制分析(二)
三、pm_test属性文件读写 int pm_test_level = TEST_NONE; static const char * const pm_tests = { = none , = core , = processors , = platform , = devices , = freezer , }; // core processors platform devices freezer, 控制范围示意 cat pm_test的时候最终会调用函数pm_test_show(),在终端上打印出上面数组中的字符串,当前的模式用 表示出来。 echo d
[单片机]
CH9434嵌入式Linux与安卓系统驱动移植和使用教程
1 前言 CH9434是一款SPI转四串口转接芯片,提供四组全双工的9线异步串口,用于单片机/嵌入式/安卓系统扩展异步串口。提供25路GPIO,以及支持RS485收发控制引脚TNOW。本篇基于STM32MP157处理器平台,介绍CH9434在嵌入式Linux系统/安卓系统的驱动移植和使用方法。 CH9434相关资料下载链接: CH9434评估板设计原理图,单片机端操作例程,LINUX驱动及应用例程下载 2 驱动移植流程 2.1 移植准备 1、配置系统SPI设备信息,若支持DTS设备树可以直接在DTS文件中直接定义此SPI结构体信息,如下所示: &spi5 { pinctrl-names = default
[单片机]
CH9434嵌入式<font color='red'>Linux</font>与安卓系统<font color='red'>驱动</font>移植和使用教程
Linux驱动入门
阅读此文的方法: 阅读以下2个文件: hello.c,asdf.c。 此文假设读者: 已经能用C语言编写Linux应用程序, 理解"字符设备文件, 块设备文件, 主设备号, 次设备号", 会写简单的Shell脚本和Makefile。 1. "hello.c" -------------------------------- /* * 这是我们的第一个源文件, * 它是一个可以加载的内核模块, * 加载时显示"Hello,World!", * 卸载时显示"Bye!"。 * 需要说明一点,写内核或内核模块不能用写应用程序时的系统调用或函数库, * 因为我们写的就是为应用程序提供系统调用的代码。 * 内核有专用的函数库,如 linux/
[嵌入式]
Linux驱动STN彩色LCD
伴随着高性能嵌入式处理器的飞速发展与普及,特别是ARM处理器系列的出现,嵌入式系统的功能也变得越来越强大。以前的单色LCD已不能满足现今的各种多媒体应用,彩色LCD被越来越多地应用到嵌入式系统中。同时,在应用需求的促使下,许多工作在Linux下的图形界面软件包的开发和移植工作中都涉及到底层LCD驱动的开发问题。 在硬件采用Intel ASSABET开发板,软件采用Linux 2.4.19平台,编译器为arm-linux-gcc的交叉编译器作为开发的前提下,因为ASSABET开发板上使用的是Sharp 3.9英寸320%26;#215;240 TFT彩色LCD,现改用Kyocera 7.7英寸640%26;#215;480 S
[应用]
linux设备驱动之USB数据传输分析 一
三:传输过程的实现 说到传输过程,我们必须要从URB开始说起,这个结构的就好比是网络子系统中的skb,好比是I/O中的bio.USB系统的信息传输就是打成URB结构,然后再过行传送的. URB的全称叫USB request block.下面从它的接口说起. 3.1:URB的相关接口 1:URB的创建 URB的创建是由usb_alloc_urb()完成的.这个函数会完成URB内存的分配和基本成员的初始化工作.代码如下: struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) { struct urb *urb; urb = kmalloc(sizeof(struc
[单片机]
Linux-2.6.30.4在2440上的移植之触摸屏驱动
一、移植环境 主 机:VMWare--Fedora 9 开发板:Mini2440--64MB Nand 编译器:arm-linux-gcc-4.3.2 二、移植步骤 1. 准备驱动源码。因为linux-2.6.30.4内核中没有提供合适的ADC驱动和触摸屏驱动,所以这里就直接用友善提供的驱动 s3c24xx-adc.h #ifndef _S3C2410_ADC_H_ #define _S3C2410_ADC_H_ #define ADC_WRITE(ch, prescale) ((ch) 16|(prescale)) #define ADC_WRITE_GETCH(data) (((data) 16)&0x7)
[单片机]
<font color='red'>Linux</font>-2.6.30.4在2440上的移植之触摸屏<font color='red'>驱动</font>
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved