拿到新开发板代码分析入口和gpiolib库
来源:互联网 发布:阿里云 按流量收费 编辑:程序博客网 时间:2024/05/01 08:17
☆ 程序分析入口
==>拿个一个新的开发板,一般分析的入口的文件路径(x210为例,分析makefile得出) /kernel/arch/arm/mach-s5pv210/mach-x210.c,
为进一步确定可先编译一下看看这个文件是不是被编译称为.o文件
==>分析mach-x210.c从文件最下面的MACHINE_START宏处入手
#ifdef CONFIG_MACH_SMDKC110
MACHINE_START(SMDKC110, "SMDKC110")
#elif CONFIG_MACH_SMDKV210
MACHINE_START(SMDKV210, "SMDKV210")
#endif
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.phys_io = S3C_PA_UART & 0xfff00000,
.io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
//.fixup = smdkv210_fixup,
.init_irq = s5pv210_init_irq,
.map_io = smdkc110_map_io,
.init_machine = smdkc110_machine_init,
.timer = &s5p_systimer,
MACHINE_END
展开后得到
static const struct machine_desc __mach_desc_SMDKV210 __used
__attribute__((__section__(".arch.info.init"))) = {
.nr = MACH_TYPE_SMDKV210,
.name = SMDKV210,
.phys_io = S3C_PA_UART & 0xfff00000,
.io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = smdkc110_map_io,
.init_machine = smdkc110_machine_init,
.timer = &s5p_systimer,
};
内核会根据相应的配置找到这个结构体并调用其中的函数,这个下一节来分析,每个新的开发板
只需要提供相应的函数即可
☆ gpiolib的创建是x210开发板移植人员做的,其调用流程为
__mach_desc_SMDKV210.map_io
smdkc110_map_io
s5pv210_gpiolib_init();
☆ 先分析s5pv210的GPIOLIB设计到的结构体:
==>struct s3c_gpio_chip {
struct gpio_chipchip;
struct s3c_gpio_cfg*config;
struct s3c_gpio_pm*pm;
void __iomem *base; //这个base会被赋值为真正的gpio虚拟地址
int eint_offset;
spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[7];
#endif
};
==>struct gpio_chip {
const char *label;
struct device *dev;
struct module *owner;
.....一系列函数......
int base; //这个base要和上面的base区别开,base是基编号
u16 ngpio;
const char *const *names;
unsigned can_sleep:1;
unsigned exported:1;
};
==>struct gpio_desc {
struct gpio_chip*chip;
unsigned long flags;
#ifdef CONFIG_DEBUG_FS
const char *label;
#endif
};
☆ 分析s5pv210_gpiolib_init()函数:
==> 结构体数组s5pv210_gpio_4bit描述了
.base这里如果某GPIO特殊也可以在这里赋值,不然后面会统一赋值
.chip.base 基地址,属于一个相对地址
.chip.ngpio 代表每个GPIO(A/B/C/D......)有效的端口数量
.chip.label 名称
.chip.to_irq 对应的中断号
==> 如果.base为NULL,调用S5PV210_BANK_BASE(i) 赋值gpio的虚拟地址(注意和.chip.base区分)
==> samsung_gpiolib_add_4bit_chips 根据s3c_gpio_chip结构体的成员 挨个调用下面两个函数
■samsung_gpiolib_add_4bit(chip); 里指明了部分GPIO的部分控制操作(不想用默认的就在这里设置)
■s3c_gpiolib_add(chip); --先是指明了GPIO的控制操作(如果amsung_gpiolib_add_4bit没有定义这里就赋值为默认值,
--然后调用gpiochip_add把gpio_chip(也就是s3c_gpio_chip里的chip)和gpio_desc关联在一起
==>gpiochip_add函数把gpio_desc结构体数组 和 gpio_chip结构体数组的关联主要是下面的for循环
base = chip->base;
for (id = base; id < base + chip->ngpio; id++) {
gpio_desc[id].chip = chip;
gpio_desc[id].flags = !chip->direction_input
? (1 << FLAG_IS_OUT)
: 0;
}
执行完之后,gpio_desc[0]~[7]的chip就是 s3c_gpio_chip的GPIOA
gpio_desc[9]~[12]的chip就是 s3c_gpio_chip的GPIOB
.............
以后通过gpio_desc[i] 就能找到GPIOX的y口
==> 其他地方调用gpio_request就会去gpio_desc获得对应的 gpio_chip结构体然后将其做个标志标志已被申请一次
举个例子:gpio_request(S5PV210_GPH0(6), "GPH06");
S5PV210_GPH0(6) --> S5PV210_GPIO_H0_START+6 --> S5PV210_GPIO_NEXT(S5PV210_GPIO_G3) + 6 -->
S5PV210_GPIO_G3_START + S5PV210_GPIO_G3_NR + CONFIG_S3C_GPIO_SPACE + 1 -->
S5PV210_GPIO_G3_START + 7 + CONFIG_S3C_GPIO_SPACE + 1
然后把S5PV210_GPIO_G3_START 宏继续展开可以一直得到 CONFIG_S3C_GPIO_SPACE + 1 + 某一个整数
这个意思就是gpiolib把所有的gpio进行了一个编号,S5PV210_GPA0(0)就是0,S5PV210_GPA0(1)就是1
而CONFIG_S3C_GPIO_SPACE 宏就是定了GPIOA,GPIOB,GPIOC编号的空白距离,例如 GPIOA8和 GPIOB0
的编号差CONFIG_S3C_GPIO_SPACE + 1
==> 其他地方调用gpio_direction_output就会去gpio_desc获得对应的 gpio_chip结构体,
然后gpio -= chip->base;gpio值就是相对于基址的偏移值
再调用direction_output(chip, gpio, value);
也就是前面赋值的samsung_gpiolib_4bit_output(struct gpio_chip *chip,unsigned int offset, int value)
==>其他函数调用类似,经常被调用的接口有
gpio_request(unsigned gpio, const char *label)
gpio_free(unsigned gpio)
gpio_direction_input(unsigned gpio)
gpio_direction_output(unsigned gpio, int value)
__gpio_get_value(unsigned gpio)
__gpio_set_value(unsigned gpio, int value)
__gpio_to_irq(unsigned gpio)
==> 重点说下__gpio_to_irq(unsigned gpio)
gpio_to_irq()返回的中断编号可以传给request_irq()和free_irq()。
关于中断下一节来说明
==>拿个一个新的开发板,一般分析的入口的文件路径(x210为例,分析makefile得出) /kernel/arch/arm/mach-s5pv210/mach-x210.c,
为进一步确定可先编译一下看看这个文件是不是被编译称为.o文件
==>分析mach-x210.c从文件最下面的MACHINE_START宏处入手
#ifdef CONFIG_MACH_SMDKC110
MACHINE_START(SMDKC110, "SMDKC110")
#elif CONFIG_MACH_SMDKV210
MACHINE_START(SMDKV210, "SMDKV210")
#endif
/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
.phys_io = S3C_PA_UART & 0xfff00000,
.io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
//.fixup = smdkv210_fixup,
.init_irq = s5pv210_init_irq,
.map_io = smdkc110_map_io,
.init_machine = smdkc110_machine_init,
.timer = &s5p_systimer,
MACHINE_END
展开后得到
static const struct machine_desc __mach_desc_SMDKV210 __used
__attribute__((__section__(".arch.info.init"))) = {
.nr = MACH_TYPE_SMDKV210,
.name = SMDKV210,
.phys_io = S3C_PA_UART & 0xfff00000,
.io_pg_offst = (((u32)S3C_VA_UART) >> 18) & 0xfffc,
.boot_params = S5P_PA_SDRAM + 0x100,
.init_irq = s5pv210_init_irq,
.map_io = smdkc110_map_io,
.init_machine = smdkc110_machine_init,
.timer = &s5p_systimer,
};
内核会根据相应的配置找到这个结构体并调用其中的函数,这个下一节来分析,每个新的开发板
只需要提供相应的函数即可
☆ gpiolib的创建是x210开发板移植人员做的,其调用流程为
__mach_desc_SMDKV210.map_io
smdkc110_map_io
s5pv210_gpiolib_init();
☆ 先分析s5pv210的GPIOLIB设计到的结构体:
==>struct s3c_gpio_chip {
struct gpio_chipchip;
struct s3c_gpio_cfg*config;
struct s3c_gpio_pm*pm;
void __iomem *base; //这个base会被赋值为真正的gpio虚拟地址
int eint_offset;
spinlock_t lock;
#ifdef CONFIG_PM
u32 pm_save[7];
#endif
};
==>struct gpio_chip {
const char *label;
struct device *dev;
struct module *owner;
.....一系列函数......
int base; //这个base要和上面的base区别开,base是基编号
u16 ngpio;
const char *const *names;
unsigned can_sleep:1;
unsigned exported:1;
};
==>struct gpio_desc {
struct gpio_chip*chip;
unsigned long flags;
#ifdef CONFIG_DEBUG_FS
const char *label;
#endif
};
☆ 分析s5pv210_gpiolib_init()函数:
==> 结构体数组s5pv210_gpio_4bit描述了
.base这里如果某GPIO特殊也可以在这里赋值,不然后面会统一赋值
.chip.base 基地址,属于一个相对地址
.chip.ngpio 代表每个GPIO(A/B/C/D......)有效的端口数量
.chip.label 名称
.chip.to_irq 对应的中断号
==> 如果.base为NULL,调用S5PV210_BANK_BASE(i) 赋值gpio的虚拟地址(注意和.chip.base区分)
==> samsung_gpiolib_add_4bit_chips 根据s3c_gpio_chip结构体的成员 挨个调用下面两个函数
■samsung_gpiolib_add_4bit(chip); 里指明了部分GPIO的部分控制操作(不想用默认的就在这里设置)
■s3c_gpiolib_add(chip); --先是指明了GPIO的控制操作(如果amsung_gpiolib_add_4bit没有定义这里就赋值为默认值,
--然后调用gpiochip_add把gpio_chip(也就是s3c_gpio_chip里的chip)和gpio_desc关联在一起
==>gpiochip_add函数把gpio_desc结构体数组 和 gpio_chip结构体数组的关联主要是下面的for循环
base = chip->base;
for (id = base; id < base + chip->ngpio; id++) {
gpio_desc[id].chip = chip;
gpio_desc[id].flags = !chip->direction_input
? (1 << FLAG_IS_OUT)
: 0;
}
执行完之后,gpio_desc[0]~[7]的chip就是 s3c_gpio_chip的GPIOA
gpio_desc[9]~[12]的chip就是 s3c_gpio_chip的GPIOB
.............
以后通过gpio_desc[i] 就能找到GPIOX的y口
==> 其他地方调用gpio_request就会去gpio_desc获得对应的 gpio_chip结构体然后将其做个标志标志已被申请一次
举个例子:gpio_request(S5PV210_GPH0(6), "GPH06");
S5PV210_GPH0(6) --> S5PV210_GPIO_H0_START+6 --> S5PV210_GPIO_NEXT(S5PV210_GPIO_G3) + 6 -->
S5PV210_GPIO_G3_START + S5PV210_GPIO_G3_NR + CONFIG_S3C_GPIO_SPACE + 1 -->
S5PV210_GPIO_G3_START + 7 + CONFIG_S3C_GPIO_SPACE + 1
然后把S5PV210_GPIO_G3_START 宏继续展开可以一直得到 CONFIG_S3C_GPIO_SPACE + 1 + 某一个整数
这个意思就是gpiolib把所有的gpio进行了一个编号,S5PV210_GPA0(0)就是0,S5PV210_GPA0(1)就是1
而CONFIG_S3C_GPIO_SPACE 宏就是定了GPIOA,GPIOB,GPIOC编号的空白距离,例如 GPIOA8和 GPIOB0
的编号差CONFIG_S3C_GPIO_SPACE + 1
==> 其他地方调用gpio_direction_output就会去gpio_desc获得对应的 gpio_chip结构体,
然后gpio -= chip->base;gpio值就是相对于基址的偏移值
再调用direction_output(chip, gpio, value);
也就是前面赋值的samsung_gpiolib_4bit_output(struct gpio_chip *chip,unsigned int offset, int value)
==>其他函数调用类似,经常被调用的接口有
gpio_request(unsigned gpio, const char *label)
gpio_free(unsigned gpio)
gpio_direction_input(unsigned gpio)
gpio_direction_output(unsigned gpio, int value)
__gpio_get_value(unsigned gpio)
__gpio_set_value(unsigned gpio, int value)
__gpio_to_irq(unsigned gpio)
==> 重点说下__gpio_to_irq(unsigned gpio)
gpio_to_irq()返回的中断编号可以传给request_irq()和free_irq()。
关于中断下一节来说明
0 0
- 拿到新开发板代码分析入口和gpiolib库
- 小e开发板用户代码入口user_init函数分析
- ARM入口代码分析
- vdsm代码入口分析
- 拿到一个新 bug 怎样分析
- 驱动开发之gpiolib库的学习及使用
- osworkflow的入口代码分析
- osworkflow的入口代码分析
- osworkflow的入口代码分析
- gpiolib的调用过程分析
- gpiolib的调用过程分析
- LCC编译器的源程序分析(45)函数代码入口和出口的代码生成
- [转载]LCC编译器的源程序分析(45)函数代码入口和出口的代码生成
- 配置电脑开发环境-拿到一个新电脑之后
- Linux 4.x 之Gpio分析(一)Gpiolib库1
- [Linux笔记]gpiolib的调用过程分析
- 入口分析
- linux驱动(七)gpiolib库详解
- 了解你所不知道的SMON功能(十二):Shrink UNDO
- 大数据系统-在硬盘上需要注意的事情
- Pycharm快捷键
- android 横竖屏切换壁纸背景
- VM安装Linux系统
- 拿到新开发板代码分析入口和gpiolib库
- 2016年年终总结
- Cordova webapp?
- Android根据文件路径使用File类获取文件相关信息
- plsql远程连接数据库的详细步骤
- Android中的WebView(一)
- PHP绿色集成环境在云服务器上的应用,PHPWAMP在服务器上搭建网站案例
- Android笔记:自定义锁屏
- SR-IOV技术优化DPDK架构下Local port性能