Linux驱动:设备树、中断(中断子系统)
一、设备树
(一)概念
1.设备树:描述硬件资源(以开发版为单位)
2..dts:描述板级资源的设备树文件(一般一个开发板对应一个文件)
3..dtsi:描述SOC的设备树文件(类似于.c对应的.h文件)
4..h:c语言的头文件,设备树编译支持预处理c文件
5..dtb:最终编译完成后生成的可加载的设备树文件(类似a.out)
(二)操作设备树步骤
1.cp arch/arm/boot/dts/imx6ull-alientek-emmc.dts arch/arm/boot/dts/wwb.dts
2.修改arch/arm/boot/dts/Makefile //新增一行,wwb.dtb(加到对应的SOC下)
3.make dtbs //编译所有的设备树文件
make wwb.dtb //只编译wwb.dts
4.设备树属性书写原则:
①该属性通用性高,则按照设备树中已有的属性名及格式定义
②该属性如果未在设备树中定义,则自行定义
5.节点查找
①of_find_node_by_path();
②of_property_read_u32_array();
③_property_read_string();
(三)GPIO子系统:内核帮我们实现操作对应接口的函数
1.设备树中定义对应的引脚及设置电器属性
pinctrl_wwbled:wwbledgrp{
fsl,pin = <MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x10B0>;
};
2.wwbled{
#address-cells = <1>;
#size-cells = <1>;
compitable = "wwbled";
pinctrl-0 = &pinctrl_wuled;
led-gpio = <&gpio1 3 1>;
status = "okay";
};
of_get_named_gpio();
3.inline:内联函数
被inline修饰的函数编译时会被原地展开在调用的位置
4.带设备树的platform的驱动:
static struct of_device_id led_table[] =
{
{
.compatible = "wu-led-subgpio"},
{}
};
static struct platform_driver pdrv =
{
.probe = probe,
.remove = remove,
.driver =
{
.name = DEV_NAME,
.of_match_table = led_table
}
};
必须定义of_device_if 结构体并初始化compatible成员 该成员和设备树中的compatible匹配,匹配成功后执行 dirver中的probe函数
二、中断(中断子系统)
(一)ptkey {
#address-cells = ;
#size-cells = ;
compatible = "pt-key";
interrupt-parent = ;
interrupts = ;
status = "okay";
};
irq_of_parse_and_map();
request_irq();
free_irq();
(二)示意图
(三)taskled和workqueue
1.中断上下文: 和中断处理相关的代码 --- 中断服务程序(中断顶半部) 、软中断、 tasklet -----------不能休眠、不能阻塞 不要做耗时操作
2.进程上下文:和进程操作相关的代码 --- open read write close 、 workqueue -----可以休眠、阻塞 可以做耗时操作
3.taskled
irq_task_fun();
struct tasklet_struct tsk;
tasklet_init(&tsk, irq_task_fun, 100);
tasklet_schedule(&tsk);
4.workqueue
irq_workqueue_fun();
struct work_struct wk;
INIT_WORK(&wk, irq_workqueue_fun);
schedule_work(&wk);