加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 教程 > 正文

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.不断地实践。

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读