第一章 Android系统移植与驱动开发概述

一、Android系统架构

1)应用程序层

         Android平台不仅仅是操作系统,也包含了许多应用程序,诸如SMS短信客户端程序、电话拨号程序、图片浏览器、Web浏览器等应用程序。这些应用程序都是  用Java语言编写的,并且这些应用程序都是可以被开发人员开发的其他应用程序所替换,这点不同于其他手机操作系统固化在系统内部的系统软件,更加灵活和个性化。

2)应用程序框架层

         应用程序框架层是我们从事Android开发的基础,很多核心应用程序也是通过这一层来实现其核心功能的,该层简化了组件的重用,开发人员可以直接使用其提    供的组件来进行快速的应用程序开发,也可以通过继承而实现个性化的拓展。

3)系统运行库层         

   从图中可以看出,系统运行库层可以分成两部分,分别是系统库和Android运行时。

4)Linux内核层

        Android是基于Linux2.6内核,其核心系统服务如安全性、内存管理、进程管理、网路协议以及驱动模型都依赖于Linux内核。

二、Android版本与Linux内核的关系

关于Android对应Linux内核版本,大家可以到自己手机中的设置---关于手机查看

查Linux 系统的内核版本方法:

①uname -a      

1 uname -a

 

②cat /proc/version

1 cat /proc/version

 

注:/proc 不是普通的文件系统,而是系统内核的映像,也就是说,该目录中的文件是存放在系统内存之中的,它以文件系统的方式为访问系统内核数据的操作提供接
口。而uname 命令就是从/proc/version 文件中获取信息的,当然直接查看/proc/version文件的内容(方法2 )也可以获取同样的信息. uname 命令加上参数“-a” 可以获取更多的信息,否则只显示当前的系统名,也就是只会输出“Linux”.

 

三、Linux设备驱动

设备的分类:

字符设备

块设备

网络设备

例子(s3c6410小灯):

  1 #include <linux/fs.h>
  2 #include <linux/cdev.h>
  3 #include <linux/pci.h>
  4 #include <asm/uaccess.h>
  5 #include <mach/map.h>
  6 #include <mach/regs-gpio.h>
  7 #include <mach/gpio-bank-m.h>
  8 
  9 #define DEVICE_NAME "s3c6410_leds"
 10 #define DEVICE_COUNT 1               //  设备数量
 11 #define S3C6410_LEDS_MAJOR 0  
 12 #define S3C6410_LEDS_MINOR 234
 13 #define PARAM_SIZE  3
 14 static unsigned char mem[4]; // 保存4个Leds的设置状态
 15 static int major = S3C6410_LEDS_MAJOR;
 16 static int minor = S3C6410_LEDS_MINOR; 
 17 static dev_t dev_number; //  设备号
 18 static int leds_state = 1;
 19 static char *params[] = {"string1", "string2","string3"};
 20 static int param_size = PARAM_SIZE;
 21 
 22 static struct class *leds_class = NULL;
 23 
 24 static long s3c6410_leds_ioctl(struct file *filp, unsigned int cmd,
 25         unsigned long arg)
 26 {
 27 
 28     switch (cmd)
 29     {
 30         unsigned tmp;
 31 
 32         case 0:
 33         case 1:
 34         if (arg > 4)
 35         {
 36             return -EINVAL;
 37         }
 38         tmp = ioread32(S3C64XX_GPMDAT);
 39 
 40         if (cmd == 1)
 41         {
 42             tmp &= (~(1 << arg));
 43         }
 44         else
 45         {
 46             tmp |= (1 << arg);
 47         }
 48 
 49         iowrite32(tmp, S3C64XX_GPMDAT);
 50 
 51         return 0;
 52         default:
 53         return -EINVAL;
 54     }
 55 }
 56 static ssize_t s3c6410_leds_write(struct file *file, const char __user *buf,
 57         size_t count, loff_t *ppos)
 58 {
 59 
 60     unsigned tmp = count;
 61     unsigned long i = 0;
 62     memset(mem, 0, 4);
 63 
 64     if (count > 4)
 65     {
 66         tmp = 4;
 67     }
 68 
 69     if (copy_from_user(mem, buf, tmp))
 70     {
 71         return -EFAULT;
 72     }
 73     else
 74     {
 75         for (i = 0; i < 4; i++)
 76         {
 77             tmp = ioread32(S3C64XX_GPMDAT);
 78             if (mem[i] == '1')
 79             {
 80                 tmp &= (~(1 << i));
 81             }
 82             else
 83             {
 84                 tmp |= (1 << i);
 85             }
 86 
 87             iowrite32(tmp, S3C64XX_GPMDAT);
 88 
 89         }
 90         return count;
 91     }
 92 
 93 
 94 }
 95 
 96 static struct file_operations dev_fops =
 97 { .owner = THIS_MODULE, .unlocked_ioctl = s3c6410_leds_ioctl, .write =
 98         s3c6410_leds_write };
 99 static struct cdev leds_cdev;
100 
101 //创建设备文件(/dev/s3c6410_leds)
102 static int leds_create_device(void)
103 {
104     int ret = 0;
105     int err = 0;
106 
107     //  初始化cdev的成员,并建立cdev和file_operations之间的连接
108     cdev_init(&leds_cdev, &dev_fops);
109     leds_cdev.owner = THIS_MODULE;
110     if (major > 0)
111     {
112         //  获取设备号(主设备号和次设备号)
113         dev_number = MKDEV(major, minor);
114         err = register_chrdev_region(dev_number, DEVICE_COUNT, DEVICE_NAME);
115         if (err < 0)
116         {
117             printk(KERN_WARNING "register_chrdev_region() failed\n");
118             return err;
119         }
120     }
121     else
122     {
123         err = alloc_chrdev_region(&leds_cdev.dev, 10, DEVICE_COUNT,
124                 DEVICE_NAME);
125         if (err < 0)
126         {
127             printk(KERN_WARNING "alloc_chrdev_region() failed\n");
128             return err;
129         }
130 
131         major = MAJOR(leds_cdev.dev);
132         minor = MINOR(leds_cdev.dev);
133         //dev_number = MKDEV(major, minor);
134         dev_number = leds_cdev.dev;
135 
136     }
137     ret = cdev_add(&leds_cdev, dev_number, DEVICE_COUNT);
138     leds_class = class_create(THIS_MODULE, DEVICE_NAME);
139     device_create(leds_class, NULL, dev_number, NULL, DEVICE_NAME);
140 
141     return ret;
142 }
143 
144 static void leds_init_gpm(int leds_default)
145 {
146     int tmp = 0;
147     //  初始化端口配置寄存器
148     tmp = ioread32(S3C64XX_GPMCON);
149     tmp &= (~0xFFFF);
150     tmp |= 0x1111; // 0001000100010001
151     iowrite32(tmp, S3C64XX_GPMCON);
152 
153     //  初始化端口上拉电路寄存器
154     tmp = ioread32(S3C64XX_GPMPUD);
155     tmp &= (~0xFF);
156     tmp |= 0xAA; // 01010101
157     iowrite32(tmp, S3C64XX_GPMPUD);
158 
159     //  初始化端口数据寄存器
160     tmp = ioread32(S3C64XX_GPMDAT);
161     tmp &= (~0xF);
162     tmp |= leds_default;
163     iowrite32(tmp, S3C64XX_GPMDAT);
164 }
165 
166 //  初始化LED驱动
167 static int leds_init(void)
168 {
169     int ret;
170     ret = leds_create_device();
171     leds_init_gpm(~leds_state);
172     printk(DEVICE_NAME"\tinitialized\n");
173 
174     printk("param0\t%s\n", params[0]);
175     printk("param1\t%s\n", params[1]);
176     printk("param2\t%s\n", params[2]);
177 
178     return ret;
179 }
180 static void leds_destroy_device(void)
181 {
182     device_destroy(leds_class, dev_number);
183 
184     if (leds_class)
185         class_destroy(leds_class);
186     unregister_chrdev_region(dev_number, DEVICE_COUNT);
187 
188     return;
189 
190 }
191 static void leds_exit(void)
192 {
193     leds_destroy_device();
194     printk(DEVICE_NAME"\texit!\n");
195 }
196 
197 module_init(leds_init);
198 module_exit(leds_exit);
199 module_param(leds_state, int, S_IRUGO|S_IWUSR);
200 module_param_array(params, charp, &param_size, S_IRUGO|S_IWUSR);
201 MODULE_LICENSE("GPL");
202 MODULE_AUTHOR("Lining");

 

总结一下学习Linux 驱动要做些什么:

1.准备一个自己熟悉的Linux 操作系统,用于开发和测试Linux 驱动,建议使用Ubuntu Linux14.04 及以上版本。

2.准备一块开发板(建议采用基于ARM11的开发板〉。

3.学习GNUC。

4.学习相关的硬件知识。

5.不断地实践。

http://www.cnblogs.com/zhuixinshaonian/

posted @ 2016-04-17 18:24  追鑫少年  阅读(263)  评论(0编辑  收藏  举报