Android系统移植与驱动开发总结
发布时间:2021-11-18 18:45:00 所属栏目:教程 来源:互联网
导读:一、Android系统架构 Android系统移植与驱动开发概述 1)应用程序层 Android平台不仅仅是操作系统,也包含了许多应用程序,诸如SMS短信客户端程序、电话拨号程序、图片浏览器、Web浏览器等应用程序。这些应用程序都是 用Java语言编写的,并且这些应用程序都
一、Android系统架构 Android系统移植与驱动开发概述 1)应用程序层 Android平台不仅仅是操作系统,也包含了许多应用程序,诸如SMS短信客户端程序、电话拨号程序、图片浏览器、Web浏览器等应用程序。这些应用程序都是 用Java语言编写的,并且这些应用程序都是可以被开发人员开发的其他应用程序所替换,这点不同于其他手机操作系统固化在系统内部的系统软件,更加灵活和个性化。 2)应用程序框架层 应用程序框架层是我们从事Android开发的基础,很多核心应用程序也是通过这一层来实现其核心功能的,该层简化了组件的重用,开发人员可以直接使用其提 供的组件来进行快速的应用程序开发,也可以通过继承而实现个性化的拓展。 3)系统运行库层 从图中可以看出,系统运行库层可以分成两部分,分别是系统库和Android运行时。 4)Linux内核层 Android是基于Linux2.6内核,其核心系统服务如安全性、内存管理、进程管理、网路协议以及驱动模型都依赖于Linux内核。 二、Android版本与Linux内核的关系 关于Android对应Linux内核版本,大家可以到自己手机中的设置---关于手机查看 Android系统移植与驱动开发概述 查Linux 系统的内核版本方法: ①uname -a uname -a ②cat /proc/version cat /proc/version Android系统移植与驱动开发概述 注:/proc 不是普通的文件系统,而是系统内核的映像,也就是说,该目录中的文件是存放在系统内存之中的,它以文件系统的方式为访问系统内核数据的操作提供接 口。而uname 命令就是从/proc/version 文件中获取信息的,当然直接查看/proc/version文件的内容(方法2 )也可以获取同样的信息. uname 命令加上参数“-a” 可以获取更多的信息,否则只显示当前的系统名,也就是只会输出“Linux”. 三、Linux设备驱动 设备的分类: 字符设备 块设备 网络设备 例子(s3c6410小灯): #include <linux/fs.h> #include <linux/cdev.h> #include <linux/pci.h> #include <asm/uaccess.h> #include <mach/map.h> #include <mach/regs-gpio.h> #include <mach/gpio-bank-m.h> #define DEVICE_NAME "s3c6410_leds" #define DEVICE_COUNT 1 // 设备数量 #define S3C6410_LEDS_MAJOR 0 #define S3C6410_LEDS_MINOR 234 #define PARAM_SIZE 3 static unsigned char mem[4]; // 保存4个Leds的设置状态 static int major = S3C6410_LEDS_MAJOR; static int minor = S3C6410_LEDS_MINOR; static dev_t dev_number; // 设备号 static int leds_state = 1; static char *params[] = {"string1", "string2","string3"}; static int param_size = PARAM_SIZE; static struct class *leds_class = NULL; static long s3c6410_leds_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch (cmd) { unsigned tmp; case 0: case 1: if (arg > 4) { return -EINVAL; } tmp = ioread32(S3C64XX_GPMDAT); if (cmd == 1) { tmp &= (~(1 << arg)); } else { tmp |= (1 << arg); } iowrite32(tmp, S3C64XX_GPMDAT); return 0; default: return -EINVAL; } } static ssize_t s3c6410_leds_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { unsigned tmp = count; unsigned long i = 0; memset(mem, 0, 4); if (count > 4) { tmp = 4; } if (copy_from_user(mem, buf, tmp)) { return -EFAULT; } else { for (i = 0; i < 4; i++) { tmp = ioread32(S3C64XX_GPMDAT); if (mem[i] == '1') { tmp &= (~(1 << i)); } else { tmp |= (1 << i); } iowrite32(tmp, S3C64XX_GPMDAT); } return count; } } static struct file_operations dev_fops = { .owner = THIS_MODULE, .unlocked_ioctl = s3c6410_leds_ioctl, .write = s3c6410_leds_write }; static struct cdev leds_cdev; //创建设备文件(/dev/s3c6410_leds) static int leds_create_device(void) { int ret = 0; int err = 0; // 初始化cdev的成员,并建立cdev和file_operations之间的连接 cdev_init(&leds_cdev, &dev_fops); leds_cdev.owner = THIS_MODULE; if (major > 0) { // 获取设备号(主设备号和次设备号) dev_number = MKDEV(major, minor); err = register_chrdev_region(dev_number, DEVICE_COUNT, DEVICE_NAME); if (err < 0) { printk(KERN_WARNING "register_chrdev_region() failedn"); return err; } } else { err = alloc_chrdev_region(&leds_cdev.dev, 10, DEVICE_COUNT, DEVICE_NAME); if (err < 0) { printk(KERN_WARNING "alloc_chrdev_region() failedn"); return err; } major = MAJOR(leds_cdev.dev); minor = MINOR(leds_cdev.dev); //dev_number = MKDEV(major, minor); dev_number = leds_cdev.dev; } ret = cdev_add(&leds_cdev, dev_number, DEVICE_COUNT); leds_class = class_create(THIS_MODULE, DEVICE_NAME); device_create(leds_class, NULL, dev_number, NULL, DEVICE_NAME); return ret; } static void leds_init_gpm(int leds_default) { int tmp = 0; // 初始化端口配置寄存器 tmp = ioread32(S3C64XX_GPMCON); tmp &= (~0xFFFF); tmp |= 0x1111; // 0001000100010001 iowrite32(tmp, S3C64XX_GPMCON); // 初始化端口上拉电路寄存器 tmp = ioread32(S3C64XX_GPMPUD); tmp &= (~0xFF); tmp |= 0xAA; // 01010101 iowrite32(tmp, S3C64XX_GPMPUD); // 初始化端口数据寄存器 tmp = ioread32(S3C64XX_GPMDAT); tmp &= (~0xF); tmp |= leds_default; iowrite32(tmp, S3C64XX_GPMDAT); } // 初始化LED驱动 static int leds_init(void) { int ret; ret = leds_create_device(); leds_init_gpm(~leds_state); printk(DEVICE_NAME"tinitializedn"); printk("param0t%sn", params[0]); printk("param1t%sn", params[1]); printk("param2t%sn", params[2]); return ret; } static void leds_destroy_device(void) { device_destroy(leds_class, dev_number); if (leds_class) class_destroy(leds_class); unregister_chrdev_region(dev_number, DEVICE_COUNT); return; } static void leds_exit(void) { leds_destroy_device(); printk(DEVICE_NAME"texit!n"); } module_init(leds_init); module_exit(leds_exit); module_param(leds_state, int, S_IRUGO|S_IWUSR); module_param_array(params, charp, ¶m_size, S_IRUGO|S_IWUSR); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Lining"); 总结一下学习Linux 驱动要做些什么: 1.准备一个自己熟悉的Linux 操作系统,用于开发和测试Linux 驱动,建议使用Ubuntu Linux14.04 及以上版本。 2.准备一块开发板(建议采用基于ARM11的开发板〉。 3.学习GNUC。 4.学习相关的硬件知识。 5.不断地实践。 (编辑:常州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |