为了更好的理解安卓的层次关系,本文在RK3399的安卓系统上增加LED灯的外设,并使用APP打开关闭LED灯。以这样一个最简单的实例,来演示从上层到底层的调用过程。首先从最底层的kernel层开始。
一、驱动开发
Kernel层就是要将LED硬件接入到系统,完成驱动的开发。Linux下的驱动是使用C语言进行开发的,可分为三类设备类型:字符设备,块设备,网络设备。每种类型的驱动都有他自有的驱动框架,学习驱动开发就是要熟悉各种驱动架构,并根据实际需求在框架内添加内容。LED的驱动我们选择最简单的杂项字符类设备驱动即可。 从原理图中可以得到两个GPIO:GPIO1_C7和GPIO1_D0,驱动三极管来使得LED灯亮灭。图:led灯原理图
1)设备树文件(kernel/arch/arm64/boot/dts/rockchip/rk3399-nanopi4-common.dtsi)
test-leds{
compatible = "test,leds";led1-work = ;led2-work = ;status = "okay";};
2) 驱动文件(kernel/drivers/gpio/gpio-testled.c)
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include MODULE_AUTHOR("embeddedtech");MODULE_LICENSE("Dual BSD/GPL");#define LEDCTRL_MAGIC 'k'#define LED1CTRL_ON_CMD _IO (LEDCTRL_MAGIC, 1)#define LED1CTRL_OFF_CMD _IO (LEDCTRL_MAGIC, 2)#define LED2CTRL_ON_CMD _IO (LEDCTRL_MAGIC, 3)#define LED2CTRL_OFF_CMD _IO (LEDCTRL_MAGIC, 4)struct led_data {
int led1_pin; //led1引脚int led2_pin; //led2引脚};struct led_data led_info;/** Open the device; in fact, there's nothing to do here.*/int testled_open (struct inode *inode, struct file *filp){
return 0;}ssize_t testled_read(struct file *file, char __user *buff, size_t count, loff_t *offp){
return 0;}ssize_t testled_write(struct f