ANDROID Platform GT818 驱动移植说明书

ANDROID Platform GT818 驱动移植说明书
ANDROID Platform GT818 驱动移植说明书

Android平台GT818驱动移植说明书

【程序总揽】

本程序针对Android2.1系统,移植的硬件平台为华天正科技开发的Real6410(基于S3C6410)。本驱动支持多指,能够在系统支持的情况下在主控进入关屏状态时自动调整GT818工作状态,达到省电的目的。

1.1系统资源使用

1.2系统运行流程

为了便于移植,程序中采用了中断和定时查询两种方式,并建议使用中断方式。以中断方式为例,系统的主运行流程如下所示:

1.创建Guitar对应的i2c_client对象,其中完成了该适配器的相关信息设置;

2.加载触摸屏驱动,注意该驱动必须在I2C总线驱动已经加载的情况下才能进行,否则I2C通信将

出错。程序中将其加载优先级设为最低;

3.创建驱动结构体,探测Guitar设备,并将其挂载到I2C总线驱动上;测试I2C通信,注册input

设备,申请IO口和中断资源,完成Guitar初始化工作(如有需要,烧录升级在此进行);

4.开启触摸屏中断,等待数据接收;

5.收到触摸屏数据中断,关中断;

6.通过I2C传输数据,分析手指信息,;

7.更新按键信息,上报手指坐标、按键等信息,开中断;

8.重复4-7之间的循环。

【移植指南】

4.准备工作

本驱动采用GPL许可证,代码没有采用模块方式,所以使用本驱动前需要重新编译内核。在编译内核前,

我们需要做好以下准备工作:

1、在硬盘上或使用虚拟机(如VmWare)安装Linux系统,推荐使用Ubuntu9.10;

2、安装gcc及arm-linux-gcc和其他编译工具,将CC和LD指定为arm-linux-gcc;

3、获取平台对应的Android源码,解压到自己的工作目录。

4、了解移植平台的IO口、中断、I2C总线的使用方式。

5.内核编译配置

在编译代码前我们需要进行内核编译配置,可以使用下面命令中的一个:

#make xconfig (基于QT的图形配置界面,非常直观,推荐使用)

#make menuconfig (基于文本菜单的配置界面)

下面我们以make xconfig为例,将我们的驱动增加到内核中去。假定我们源代码目录为:

~/android/kernel/

将编写的源代码复制到Linux内核源代码的相应目录:

~/android/kernel/driver/input/touchscreen/goodix_touch.c

~/android/kernel/include/linux/goodix_touch.h

~/android/kernel/include/linux/goodix_update.h //如果不做烧录则可以不加

1.在目录touchscreen的Kconfig文件中增加新源代码对应项目的编译配置选项:

#-----------------------------------------------------------------

config TOUCHSCREEN_GOODIX_GT818

# 配置项名称

tristate "S3C6410 TouchScreen Driver"

#选择项,选择Y标识要将其编译进内核

default y #默认编译选项

depends on I2C #依赖项,本驱动必须工作在I2C总线驱动的基础上

help #帮助信息

It is a android driver to support Gooidx's touchscreen whose name

is guitar on s3c6410 platform. The touchscreen can support multi-touch

not more than two fingers.

Say Y here to enable the driver for the touchscreen on the

S3C SMDK board.

If unsure, say N.To compile this driver as a module, choose M here:

the module will be called goodix_touch.ko.

#-----------------------------------------------------------------

注意:

当将编译选项设置为M时,编译生成的驱动需要我们手动挂载。如需要系统启动时自动挂载,需要将模块goodix_touch.ko拷贝到系统模块加载目录,并修改对应的启动过程的rc脚本。

2.在目录touchscreen的makefile文件中增加对新源代码的编译条目;

#这里的二进制文件名必须与源文件名移植,如goodix_touch

obj-$(CONIDG_ TOUCHSCREEN_GOODIX_GT818) += goodix_touch.o

3.进入内核源码目录,执行make xconfig,查看driver项中是否增加了GOODIX_TOUCHSCREEN条

目。

6.如果只需要支持一款触摸屏,在内核设置中需要我们设定只编译一个触摸屏的驱动,此时与之前触摸屏

的关联设置需要屏蔽。以S3C开发板提供的电阻屏驱动为例:

自带电阻屏的驱动配置选项为TOUCHSCREEN_S3C或TOUCHSCREEN_S3C_ANDROID,而

s3c_ts_set_platdata、s3c_device_ts是在arch/arm/plat-s3c/dev-ts.c文件中定义的,而这个源文件必须在CONFIG_TOUCHSCREEN_S3C或者CONFIG_TOUCHSCREEN_S3C_ANDROID有定义的情况下才会被编译,因此对这这个源文件中的函数或者变量的引用相应地应该加上诸如下面的这个编译控制宏:#if defined(CONFIG_TOUCHSCREEN_S3C) || defined(CONFIG_TOUCHSCREEN_S3C_ANDROID)

……

#endif

这样能够避免修改了内核编译配置而造成的编译错误,并方便地通过make config设置来调整我们对触摸屏的支持。

7.多指驱动支持

要支持多点触摸,首先需要linux 内核的支持,也就是input 子系统需要提供多点触摸的接口,其次是GUI 库要能处理多点触摸的事件,后者在Android2.0及以上版本已经支持。内核方面,自2.6.30 以后的内核的input 子系统开始增加了多点触摸的支持,而比这更早的版本我们可以通过修改input子系统源文件来完成支持。

以内核2.6.28为例,主要修改的部分为:(红色部分为添加部分)

在文件(内核源文件目录)/include/input.h

#define SYN_REPORT 0

#define SYN_CONFIG 1

#define SYN_MT_REPORT 2

//-------------------------------------------

#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */

#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */

#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */

#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */

#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */

#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */

#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */

#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */

#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */

#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */

#define ABS_MT_PRESSURE 0x3a /* Pressure on contact area */

//----------------------------------------------------------

#define ABS_MAX 0x3f

#define ABS_CNT (ABS_MAX+1)

/*

* MT_TOOL types

*/

#define MT_TOOL_FINGER 0

#define MT_TOOL_PEN 1

在同一文件添加一下相应处理函数:

static inline void input_mt_sync(struct input_dev *dev)

{

input_event(dev, EV_SYN, SYN_MT_REPORT, 0);

}

在文件(内核源文件目录)/drivers/input/input.c 添加:

static unsigned int __initdata input_abs_bypass_init_data[] = { ABS_MT_TOUCH_MAJOR,

ABS_MT_TOUCH_MINOR,

ABS_MT_WIDTH_MAJOR,

ABS_MT_WIDTH_MINOR,

ABS_MT_ORIENTATION,

ABS_MT_POSITION_X,

ABS_MT_POSITION_Y,

ABS_MT_TOOL_TYPE,

ABS_MT_BLOB_ID,

ABS_MT_TRACKING_ID,

ABS_MT_PRESSURE,

};

static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)];

static void input_handle_event(struct input_dev *dev,

……

disposition = INPUT_PASS_TO_HANDLERS;

}

break;

case SYN_MT_REPORT:

dev->sync = 0;

disposition = INPUT_PASS_TO_HANDLERS;

break;

}

break;

……

case EV_ABS:

if (is_event_supported(code, dev->absbit, ABS_MAX)) {

if (test_bit(code, input_abs_bypass)) {

disposition = INPUT_PASS_TO_HANDLERS;

break;

}

value = input_defuzz_abs_event(value,

dev->abs[code], dev->absfuzz[code]);

static void __init input_init_abs_bypass(void)

{

const unsigned int *p;

for (p = input_abs_bypass_init_data; *p; p++)

input_abs_bypass[BIT_WORD(*p)] |= BIT_MASK(*p);

}

static int __init input_init(void)

{

int err;

input_init_abs_bypass();

err = class_register(&input_class);

其他版本的内核的input子系统文件可以根据https://www.360docs.net/doc/481521279.html,/kernel/ 上提供的文件更新比较来作出对应的修改。

8.New-style形式驱动信息配置(probe方式)

如果采用的是New-style驱动探测方式,在挂载驱动前需要预先建立在主板的i2c_board_info 数组中添加I2C地址、名字、中断等相关结构信息,以便于系统自动建立i2c_client用于probe,需要修改的文件为:

//mach-smdk6410.c

//i2c总线0上需要建立的设备client列表,挂载在哪个适配器列表上取决于硬件配置

static struct i2c_board_info i2c_devs0[] __initdata = {

{ I2C_BOARD_INFO("24c08", 0x50), },

/* { I2C_BOARD_INFO("WM8580", 0x1b), }, */

}

修改为:

static struct i2c_board_info i2c_devs0[] __initdata = {

{ I2C_BOARD_INFO("24c08", 0x50, },

{ I2C_BOARD_INFO("Goodix-TS", 0x5d), //0x5d为I2C从设备7位地址,需要根据实际情况修改

//注意名字"Goodix-TS"与代码中GOODIX_I2C_NAME的值一致.irq=IRQ_EINT(18), }, //程序中使用的系统中断号,示例代码已在头文件中指定……,//需要根据实际情况修改

};

与此对应的是,如果采用的adapter方式(LEGACY)的I2C驱动,需要手动建立client。请注意确保驱动中使用的i2c总线i2c_board_info数组上不存在与GT80X相同地址的client。另芯片缺省从设备地址是0x5d,如果一致,请注释掉头文件中的NO_DEFAULT_ID宏定义,如果需要修改成别的设备地址(还提供了两个地址,0x37和0x14),请必须同时打开INT_PORT和NO_DEFAULT_ID的宏定义,也就是说必须要有INT口才可以设置其它从设备地址。

9.Guitar触摸屏的配置信息

Guitar触摸屏在上电初始化的过程中,需要主控发送配置信息,配置信息共分为106 字节(红色部分),适合不同机型按键板的配置信息由汇顶科技公司面向windows 系统的GuitarTestPlatform工具自动产生,由于IC不同算法其配置信息也不全相同,因此需要根据读出的版本信息来发送相应的配置,具体配置信息详细内容可参阅Guitar的用户手册。下面以4.3 inch屏为例:

static int goodix_init_panel(struct goodix_ts_data *ts)

{

short ret=-1;

int ic_size = 0;

uint8_t config_info_c[] = { //试例

0x06,0xA2,

0x00,0x02,0x04,0x06,0x08,0x0A,0x0C,0x0E,

0x10,0x12,0xE0,0x00,0xD0,0x00,0xC0,0x00,

0xB0,0x00,0xA0,0x00,0x90,0x00,0x80,0x00,

0x70,0x00,0x00,0x00,0x10,0x00,0x20,0x00,

0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,

0x00,0x00,0x01,0x13,0x80,0x88,0x90,0x14,

0x15,0x40,0x0F,0x0F,0x0A,0x50,0x3C,0x0C,

0x00,0x00,MAX_FINGER_NUM,(TOUCH_MAX_WIDTH&0xff),(TOUCH_MAX_WIDTH>>8),(TOUC H_MAX_HEIGHT&0xff),(TOUCH_MAX_HEIGHT>>8),0x00,

0x00,0x46,0x5A,0x00,0x00,0x00,0x00,0x03,

0x19,0x05,0x00,0x00,0x00,0x00,0x00,0x00,

0x20,0x10,0x00,0x04,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x38,

0x00,0x3C,0x28,0x00,0x00,0x00,0x00,0x00,

0x00,0x01

};

uint8_t config_info_d[] = { //Touch key devlop board

0x06,0xA2,

……….//内容略

……….

};

ret = goodix_read_version(ts);

if (ret < 0)

return ret;

if((ts->version&0xff) < TPD_CHIP_VERSION_D_FIRMWARE_BASE)

{

dev_info(&ts->client->dev," Guitar Version: C\n");

config_info_c[57] = (config_info_c[57]&0xf7)|(INT_TRIGGER<<3); //中断方式,头文件定义

ret=i2c_write_bytes(ts->client,config_info_c, (sizeof(config_info_c)/sizeof(config_info_c[0])));

}

else

{

dev_info(&ts->client->dev," Guitar Version: D\n");

config_info_d[57] = (config_info_d[57]&0xf7)|(INT_TRIGGER<<3);

ret=i2c_write_bytes(ts->client,config_info_d, (sizeof(config_info_d)/sizeof(config_info_d[0])));

}

if (ret < 0)

return ret;

msleep(10);

return 0;

}

只有发送正确的配置信息才能让Guitar运行在最佳状态,注意不同模组的配置信息一般都不相同。发送错误的配置信息还可能导致无法读取版本号。

10.系统资源使用

Guitar的硬件I2C传输有最大速率限制(具体速率限制可以通过查询Guitar主控编程说明,不超过600K),过大将通信失败,需要预设移植系统的I2C总线速度低于此速度;I2C系统的上拉电阻应保证小于一定阈值,请注意i2c工作电压和Guitar的工作电压;

驱动中使用的SHUTDOWN管脚为GPF3,移植时需要修改为移植芯片上的对应管脚。

系统使用的中断管脚为GPL10(系统中断119),移植时需要根据具体的芯片手册来修改系统中断号。

为了便于移植调试,这里可以采用编译控制宏的方式来方便地控制GPIO的使用:

中断不使用为例:

请将goodix_touch.h文件中的

……

#define INT_PORT S3C64XX_GPL(10) //Int IO port

……

删除或注释掉;

不使用中断管脚时驱动将以16ms的周期查询坐标。

11.头文件需要设定的部分

A.Touch芯片的分辨率(注意,配置信息中也要相应配置)与屏的像素。头文件中的TOUCH_MAX_HEIGHT和

TOUCH_MAX_WIDTH,如未要求我司修改,默认分别是7680和5120。一般屏的长边对应

TOUCH_MAX_HEIGHT,短边对应TOUCH_MAX_WIDTH,请根据实际屏的像素的大小设置,比如800×600的像素,TOUCH_MAX_HEIGHT设为800,TOUCH_MAX_WIDTH设为600。

B.上报坐标方式设置。如果采用轮询上报坐标,请注释#define INT_PORT的定义。如果采用中断上报坐

标,需要设置中断是上升沿触发还是下降沿触发(注意,配置信息中也要相应配置),INT_TRIGGER定义为1代表上升沿触发,为0代表下降沿触发。

C.手指数的设置(注意,配置信息中也要相应配置)。MAX_FINGER_NUM定义为5代表5指,本芯片最

大支持5指。

D.按键的设置(注意,配置信息中也要相应配置)。头文件中需要定义

HAVE_TOUCH_KEY,而touch_key_array数组就定义了相应的按键,按键的顺序通过调整其在数组元素的位置。最多支持4个按键。

12、上报坐标

由于每个平台定义的X,Y有可能不同,如果发现X,Y方向是反的,可以将程序中goodix_ts_work_func 函数中

input_report_abs(ts->input_dev, ABS_MT_POSITION_X,

(*(coor_point+3*(position-1)+1)));

input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,

SCREEN_MAX_WIDTH-(*(coor_point+3*(position-1))));

ABS_MT_POSITION_X和ABS_MT_POSITION_Y位置对调

13、在线升级

为了让客户可以在不拆机的情况下升级guitar以获得最好的工作状态,因此在驱动中加了支持固件升级模块,该模块支持上电自动检测版本并升级最新版本方式。GOODIX提供的驱动参考代码默认自带固件升级模块,并依赖于AUTO_UPDATE_GT818与CONFIG_TOUCHSCREEN_GOODIX_IAP宏编译开关和升级数据

gt818_update.h(文件数组大小为3824 byte错误的数据文件将导致IC无法正常工作)。

#define AUTO_UPDATE_GT818 //启动开机自动检测升级功能

#define CONFIG_TOUCHSCREEN_GOODIX_IAP //开启APK升级接口

若开了自动检测升级模式,则上电执行probe时会调用函数gt818_downloader,根据当前IC版本是否比可升级版本高来决定是否需要升级,如果当前版本比可升级版本高,则不会升级,否则会自动升级为最新程序;

Probe中自动升级入口

#ifdef AUTO_UPDATE_GT818

goodix_read_version(ts);

ret = gt818_downloader( ts, goodix_gt818_firmware, update_path);

if(ret < 0)

{

dev_err(&client->dev, "Warnning: GT818 update might be ERROR!\n");

}

#endif

APK升级读写节点:

#ifdef CONFIG_TOUCHSCREEN_GOODIX_IAP

goodix_proc_entry = create_proc_entry("goodix-update", 0666, NULL);

if(goodix_proc_entry == NULL)

{

dev_info(&client->dev, "Couldn't create proc entry!\n");

ret = -ENOMEM;

goto err_create_proc_entry;

}

else

{

dev_info(&client->dev, "Create proc entry success!\n");

goodix_proc_entry->write_proc = goodix_update_write;

goodix_proc_entry->read_proc = goodix_update_read;

goodix_proc_entry->owner =THIS_MODULE;

}

#endif

APK升级方式即上层APK通过goodix_update_write发送升级数据文件路径给驱动,然后从文件中读取所需的数据存到goodix_gt818_firmware数组中,再调用烧录模块

ret = gt818_downloader( ts, goodix_gt818_firmware, update_path);

进行数据烧录。

升级过程中会使用到中断脚与复位脚,具体动作请参考818编程指南,请在升级完后保证中断口为输入口且中断使能,以免读不到坐标。

安装GOODIX提供的Android固件升级程序GOODiX在线升级程序.apk,程序运行后的界面如下图所示:

第一个路径栏用于选择用于升级中要使用固件文件(*.bin),第二个路径栏用于选择升级过程中要使用的配置文件(目前暂不开放),程序会自动保存上次升级所使用升级文件的路径,通过”浏览”按钮可以从存储器中选择升级文件相应的升级文件,选择升级文件的界面如下图所示:

进入相应文件夹选择用于升级的*.bin文件时,程序将弹出警告提示,如果您确认该文件为GOODIX提供的正确的bin文件,请选择”强制升级”返回升级主界面,否则请”重新选择”正确的bin文件。(注意:错误的升级文件将导致触摸屏失效,请慎重操作!)

选择完升级文件后,升级主界面的地址栏中将显示您所选择的路径,如果升级同时不需要升级配置,则配置地址栏显示为不可用状态:

点击”升级”按钮进入升级后,将出现确认升级对话框,可以点击”是”直接进入升级,或者点击”否”返回升级主界面:

进入升级后,将在屏幕中央打印出升级过程的各个步骤,并用进度条显示升级进度,可以对比升级前后所读取的版本号,来判断升级是否成功:

如果升级失败,触摸屏将可能无法正常工作,重启系统后升级程序将自动运行,并倒计时10s后自动进入升级,如果是由于上次升级选择的文件错误导致触摸屏失效,请删除上次升级的文件,并将正确的升级文件保持与上次升级的文件名和路劲都相同,然后重新启动系统,让程序自动升级,如果程序找不到上次升级的文件,则会出现以下提示,此时请将升级文件按照程序的按照上次升级的路径和文件名存放,然后重启系统,程序将自动进行升级:

如果路径不对则会出现如下提示:

点击工具按键则会进入工具栏界面,在该界面可以进行配置信息的读写与读取版本号:

注意:

1、由于该模式会与gt818_update.h比较软件版本,因此当开了AUTO_UPDATE_GT818时,只能

升比当前更高的版本;

2、升级前请确保系统电量充足,以防升级过程中出现意外;

3、请确保升级文件为GOODIX提供的对应的GT818触摸模组的BIN文件或gt818_update.h;

4、升级结束后请把相关APK删除,防止误操作;

【注意事项】

1、程序中可以设定支持的手指数目,双指情况良好;可以支持更多手指,但由于Android 2.3以前文件系统

的原因有手指ID交换问题;在Android 2.3以后Google已经修改该Bug。

主要问题:以三指为例,操作时如果先按键的手指先离开,可能发生ID交换或其他情况。

android系统开发工作介绍

android系统开发工作介绍 一、android的开发工作 Android的开发分为三个类型:移植开发移动设备系统;android系统级开发和应用程序开发。 1、移植开发移动设备系统 2、Android系统级开发,指的是扩展android的框架或者是修改bug,这方面比较少,除非有些开发移动设备的厂商,比如做gps,可以往里面加入一些自己的特定系统东西,这可能导致一些不兼容。当然也可能是简单的修复bug,详细的内容后面还有说。 3、开发应用程序,这应该是比较主流的开发,也就是给android系统写应用程序。当然我们这里主要是研究android的framework如何给这些应用程序提供服务的。 总结一下,我们可以把android分为四个层次,从底层往上依次为:linux内核、C/C++库、java 框架和java应用程序。移植开发移动设备涉及到linux内核(包括其驱动);android系统级开发涉及到C/C++库的开发及给上层java框架;android应用程序开发就是调用java的框架写应用程序。 简单的从上到下,android应用程序需要有java框架支持,比如它要发送短信,就需要java 框架,java框架其实就是将C/C++库包装成为了一个JNI,而实现具体的功能是C/C++库,最后驱动硬件完成功能,这也就是linux内核部分。 所谓framework,也就是系统级开发,这将是本文的重点,虽然android的framework 开发比较少,但是对其了解后更有利于整体开发的进行,当然很多设备厂商还是非常需这要些的。 二、android系统架构

Linux内核及驱动、C/C++框架、java框架、java应用程序。 1)、Linux内核及驱动 其中linux内核及驱动是内核层的(本人对linux内核也有过痴迷的时候,就像现在android 痴迷一样),系统总是需要操作系统的支持的,比如内存管理、进程管网理、络协议栈等。 2)、android的C/C++框架 系统C库:用的是libc,没什么好说的,C程序员都知道。多媒体库SurFace Manager:显示子系统的管理器LibWebCore:web浏览器引擎,支持android浏览器SGL:skia图形库,底层的2D图形引擎 3D库:OpenGL FreeType:字体显示Android的运行环境,这个也应该属于这个框架里面的,android的虚拟机叫做Dalvik,运行环境就是由这个虚拟机和基础的java类库组成。 3)、android应用框架 提供一系列的服务和系统,包括视图、内容提供器、资源管理器、通知管理器活、动管理器。 视图非常丰富:list、grid、text box、button等。内容提供器是使得应用程序可以访问另一个程序的数据。资源管理器是提供访问非代码的资源访问,如布局文件。通知管理器,使得程序可以在状态栏中显示自定义的提示信息。活动管理器,用来管理程序生命周期。 4)、android应用程序Android所有的应用程序都是用java写的,当然现在好像也支持一些脚本语言,如 ruby,但是不支持C开发,所谓支持C开发是指jni的形式。 。。。。。。。。。

虚拟声卡驱动程序VirtualAudioCable使用方法

一:安装软件 点击 选择是(Y) 选择I accept 选择Install 安装成功,点击“确定”按钮即完成安装。 二、软件的设置 点击桌面开始按钮所有程序---Virtual Audio Cable —Control panel 进入软件初始化 设置。 在Cables 中选择1(即首次设置一个虚拟通道),点击旁边的Set 按钮生成通道Cable1. 在参数设置区将Line 、Mic (可选可不选)、S/PDIF (可选可不选)三个选项后面的方框打钩,选中之后点击参数设置区内的设置按钮Set ,即完成了,对虚拟声卡通道1 的设置。 鼠标右键点击桌面右下角的喇叭------ 调整音频属性---- < 或者点击开始—控制面板--- 声音、 语音和音频设备--- 声音和音频设备>弹出: 选择语音 此时语音部分的设置为原系统默认的设备,保持不变。 选择音频: 改变声音播放、录音的选项内容:

如上图将声音播放、录音的默认设备全部改为Virtual Cable 1 。点击应用--- 确定即可。 三、打开录音机录音--- 录制电脑里播放出来的音频(不包含麦克风 里的声音) - 即“内录” 开始--- 所有程序—附件--- 娱乐--- 录音机 点击确定即可开始录音(注:此时可在电脑中打开相应的音频文件,开始录音) 此时音频波段显示有声音输入,但是电脑的耳机听不到正在播放的音频文件(属正常现象)。若想同时听到音频文件的内容点击桌面开始按钮所有程序---Virtual Audio Cable —Audio Repeater 。 修改为 点击Start 即可听到正在录制的音频文件。此时的录音即是通过虚拟声卡通道录制电脑里的声音的。 四、同时录电脑里播放的声音和麦克风收集的外部声音----- 即混录 <通过这种方法解决现有笔记本无“立体声混音”或“波形音”选项的问题> 在《三打开录音机录音--- 录制电脑里播放出来的音频(不包含麦克风里的声音)------------ 即“内录”》的同时,在打开一个irtual Audio Cable —Audio Repeater 窗口将其设置为: 即将外部麦克风收集的声音转移到虚拟声卡通道Cable1 中,同电脑里播放的声音一起被录音软件收录为音频文件。

安卓Android ROM定制、移植:第六篇:boot.img、recovery解包和打包

太抱歉了,因为教程实在是有点粗浅了,其实很多东西都不知道怎么去写,这不是复制粘贴,当然很多只是一步步的走的,不过也许我自己觉得已经阐述的很清楚了,可是一旦别人看起来,还是感觉很深奥,没办法,本人就这点能力了,呵呵! 大家都知道安卓的核心更换呢,那是在boot.img里面,那么如何在WINDOWS下去解开它呢,LINUX的自己略过。。。。 首先百度BOOTIMG.EXE,然后你懂的,会出来一大堆,这得感谢制作bootimg.exe的作者,本来是为华为的机器做的分解工具,不过我们也可以拿来分解boot.img、recovery.img等,OK!先来谈谈这两个文件的基础,部分来自网络。 boot和recovery映像的文件结构 boot和recovery映像并不是一个完整的文件系统,它们是一种android自定义的文件格式,该格式包括了2K的文件头,后面紧跟着是用gzip压缩过的内核,再后面是一个ramdisk 内存盘,然后紧跟着第二阶段的载入器程序(这个载入器程序是可选的,在某些映像中或许没有这部分)。此类文件的定义可以从源代码android-src/system/core/mkbootimg找到一个叫做bootimg.h的文件。 (译者的话,原文是一个叫做mkbootimg.h的文件,但从Android 2.1的代码来看,该文件名应该是改为bootimg.h了)。 /* ** +-----------------+ ** | boot header | 1 page ** +-----------------+ ** | kernel | n pages ** +-----------------+ ** | ramdisk | m pages ** +-----------------+ ** | second stage | o pages ** +-----------------+

编译hello设备驱动程序详细过程

编译hello world设备驱动程序详细过程 1、安装与你的开发板相同的内核版本的虚拟机,我的板子内核是2.6.8.1,虚拟机是2.6.9, 一般是虚拟机的内核只能比板子内核新,不能旧 #uanme –a [1](在任何目录下,输入此命令,查看虚拟机的内核版本,我的内核版本是2.6.9) 2、在虚拟机上设置共享目录,我的共享目录在linux下的/mnt/hgfs/share [2]share是自己命名的,我的物理机上,即Windows下的目录是G:/share, 3、在Windows下,把开发板的的交叉开发工具链[3],内核源码包[4],复制到物理机的共享目录下[5] 即Windows下的目录是G:/share, 4、#cp /mnt/hgfs/share/cross-3.3.2.tar.bz2 /usr/local/arm [6] 在Linux下,把交叉工具链,复制到/usr/local/arm目录下 5、#cd /usr/local/arm 6、#tar jxvf cross-3.3.2.tar.bz2 [7] 并在当前目录/usr/local/arm下解压它cross-2.95.3.tar.bz2和gec2410-linux-2.6.8.tar.bz2也是用同样的命令去解压 7、#export PATH=/usr/local/arm/3.3.2/bin:$PATH [8] 安装交叉工具链,在需要使用交叉编译时,只要在终端输入如下命令 #export PATH=/usr/local/arm/版本/bin:$PATH 即可,在需要更改不同版本的工具链时,重新启动一个终端,然后再一次输入上面的命令即可,使用哪个版本的交叉工具链,视你要编译的内核版本决定,编译2.4版本的内核,则用2.95.3版本的交叉工具链,而2.6版本内核的,则要用3.3.2版本的交叉工具链。 8、#cp gec2410-linux-2.6.8.tar.bz2 /root [9]把内核拷贝到/root目录下, 9、#cd /root 10、#tar gec2410-linux-2.6.8.tar.bz2 [10] 在/root解压开发板的内核源码压缩包gec2410-linux-2.6.8.tar.bz2,得到gec2410-linux-2.6.8.1文件夹 11、#cd /root/ gec2410-linux-2.6.8.1 12、#cp gec2410.cfg .config [11] gec2410.cfg文件是广嵌开发板提供的默认内核配置文件,在这里首先把内核配置成默认配置,然后在此基础上用make menuconfig进一步配置,但在这里,不进行进一步的配置,对于内核配置,还需要看更多的知识,在这里先存疑。 13、#make [12]在内核源代码的根目录gec2410-linux-2.6.8.1下用make命令编译内核,注意,先安装交叉工具链,再编译内核,因为这里编译的hello.ko驱动模块最终是下载到开发板上运行的,而不是在虚拟机的Linux系统运行的,如果是为了在虚拟机的Linux系统运行的,则不用安装交叉编译工具链arm-linux-gcc,而直接用gcc,用命令#arm-linux-gcc –v 可以查看当前已经安装的交叉编译工具链的版本。这里编译内核不是为了得到内核的映象文件zImage(虽然会得到内核的映象文件zImage),而是为了得到编译hello.o模块需要相关联,相依赖(depends on)的模块。 14、#cd /root 12、#mkdir hello [13]在/root目录下建立hello文件夹, 13、#cd hel 14 、#vi hello.c [12]编辑hello.c文件,内容是《Linux设备驱动程序》第三版22页的hello world程序。 15、#vi Makefile [13]在hello文件夹下编辑Makefile文件, 16、obj-m := module.o [14] 这是Makefile的内容,为obj-m := module.omodule.o视你编辑的.c文件而定,这里则要写成hello.o,写完后,保存退出。 17、cd /root/hello

S3C6410 移植Android 内核移植经验

主要过程: . 安装lunux 环境 . 安装编译工具 . 下载Linux kernel . 安装Android SDK . 获得root file system . 修改Linux kernel 源码 . 配置Linux kernel . 修改root file system . 编译Linux kernel . 下载kernel Image 1.安装linux 环境 安装Ubuntu Linux 系统,从网站上下载操作系统安装光盘映像,地址: https://www.360docs.net/doc/481521279.html,/ubuntu/releases/8.04/ 下载ubuntu-8.04.2-desktop-i386.iso,刻录成光盘安装,安装可以在windows 系统下进行, 选取有15G 空间的硬盘安装,输入用户密码开始安装 这一步结束退出光盘重启进入Ubuntu 系统,完成余下系统安装。 Linux 安装完成,进入Ubuntu 系统,确保电脑连接Internet,安装一些必要软件。 打开终端输入命令框,进行下面的操作: $ sudo apt-get install ssh $ sudo apt-get install flex bison gperf libsdl-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl

$ sudo apt-get install valgrind $ sudo apt-get install sun-java6-jdk $ sudo apt-get install libncurses5-dev 所有软件系统会自动从网络下载安装,完成后可以开始Android 的移植。 2.安装编译工具 下载: $ wget https://www.360docs.net/doc/481521279.html,/public/gnu_toolchain/arm-none-linux-gnuea bi/arm-2008q1-126-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 安装: $ tar -xjvf arm-2008q1-126-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 3.下载Linux kernel 从下面地址获得: https://www.360docs.net/doc/481521279.html,/p/android/downloads/list?can=1&q=&colspec=File name Summary Uploaded Size DownloadCount Kernel : linux-2.6.23-android-m5-rc14.tar.gz 解压文件 $ tar -xf linux-2.6.23-android-m5-rc14.tar.gz 4.安装Android SDK 从网上下载linux 版本的Android SDK,如下 https://www.360docs.net/doc/481521279.html,/android/android-sdk_m5-rc15_linux-x86.zip 下载后解压,获得android-sdk_m5-rc15_linux-x86 文件 5.获得root file system ⑴下载busybox 工具从下面地址 http://benno.id.au/blog/2007/11/14/android-busybox(linux 环境中下载)⑵运行emulator 获取root file system $ cd <目录>/ android-sdk_m5-rc15_linux-x86/tools $ ./emulator& 等待emulator 启动,看到出现Android 系统画面,进入菜单ALL/Dev Tools/Development Settings 下,将Wait for debugger,Show running processes,Show screen updates 这三项打勾,回到命令输入终端。 $ ./adb push /busybox /data $ ./adb shell # /data/busybox tar -czf system.tar.gz /system # /data/busybox tar -czf data.tar.gz /data # /data/busybox tar -czf etc.tar.gz /etc # /data/busybox tar -czf sbin.tar.gz /sbin # exit $ ./adb pull /system.tar.gz ./ $ ./adb pull /data.tar.gz ./

【IT专家】yolo模型移植到android手机端

本文由我司收集整编,推荐下载,如有疑问,请与我司联系 yolo模型移植到android手机端 2017/08/18 665 之前写了android demo在手机上的运用,但是模型都是官方给的,想要替换成自己的模型,因此尝试了下将自己训练的yolo模型来替换demo给的模型。首先,darknet的训练和.weight文件到.pb文件的转化,以及android demo 的实现见之前的博客。在此不再叙述sdk,nkd等配置问题,且直接使用.pb文件。其次,默认已安装android studio。 (1)终端进入(android安装目录)/bin,输入./stuodio.sh开启android studio ?(2)点击new,import project导入(tensorflow所在路径)/tensorflow/examples/android文件夹(可连接手机先run,保证demo能够正常运行后再行修改) ?(3)将build.gradle中68行的bazelLocation改为自己bazel的路径:def bazelLocation = ‘/home/seven/bin/bazel’185行apply from: “download-models.gradle”注释掉,并在第112行,增加//*/(不然后面的内容都被当做注释了): ?if (nativeBuildSystem == ‘bazel’ || nativeBuildSystem == ‘makefile’) { // TensorFlow Java API sources. java { srcDir ‘../../java/src/main/java’ exclude ‘**/examples/**’//*/ } // Android TensorFlow wrappers, etc. java { 最后,将第76行开始的内容改为自己需要的版本号: android { compileSdkVersion 25 buildToolsVersion “26.0.1” if (nativeBuildSystem == ‘cmake’) { defaultConfig { applicationId = ‘org.tensorflow.demo’ minSdkVersion 21 targetSdkVersion 25 ndk { abiFilters “${cpuType}” } (4)将转化得到的.pb文件放在(tensorflow所在路径)/tensorflow/examples/android/assets文件夹内,为方便起见,可将此.pb重命名为graph-tiny-yolo-voc.pb。若文件夹中已存在此文件名的文件,删除之。 ?(5)该项目将一次性生成三个app,因为我只需要detect一个,在AndroidManifest.xml中删除关于另外的两个activity,修改后的文件如图 ?

虚拟设备驱动程序的设计与实现

虚拟设备驱动程序的设计与实现 由于Windows对系统底层操作采取了屏蔽的策略,因而对用户而言,系统变得 更为安全,但这却给众多的硬件或者系统软件开发人员带来了不小的困难,因为只要应用中涉及到底层的操作,开发人员就不得不深入到Windows的内核去编写属 于系统级的虚拟设备驱动程序。Win 98与Win 95设备驱动程序的机理不尽相同,Win 98不仅支持与Windows NT 5.0兼容的WDM(Win32 Driver Mode)模式驱动程序 ,而且还支持与Win 95兼容的虚拟设备驱动程序VxD(Virtual Device Driver)。下面介绍了基于Windows 9x平台的虚拟环境、虚拟设备驱动程序VxD的基本原理和 设计方法,并结合开发工具VToolsD给出了一个为可视电话音频卡配套的虚拟设备 驱动程序VxD的设计实例。 1.Windows 9x的虚拟环境 Windows 9x作为一个完整的32位多任务操作系统,它不像Window 3.x那样依 赖于MS-DOS,但为了保证软件的兼容性,Windows 9x除了支持Win16应用程序和 Win32应用程序之外,还得支持MS-DOS应用程序的运行。Windows 9x是通过虚拟机 VM(Virtual Machine)环境来确保其兼容和多任务特性的。 所谓Windows虚拟机(通常简称为Windows VM)就是指执行应用程序的虚拟环 境,它包括MS-DOS VM和System VM两种虚拟机环境。在每一个MS-DOS VM中都只运 行一个MS-DOS进程,而System VM能为所有的Windows应用程序和动态链接库DLL(Dynamic Link Libraries)提供运行环境。每个虚拟机都有独立的地址空间、寄存器状态、堆栈、局部描述符表、中断表状态和执行优先权。虽然Win16、Win32应用程序都运行在System VM环境下,但Win16应用程序共享同一地址空间, 而Win32应用程序却有自己独立的地址空间。 在编写应用程序时,编程人员经常忽略虚拟环境和实环境之间的差异,一般认为虚拟环境也就是实环境。但是,在编写虚拟设备驱动程序VxD时却不能这样做 ,因为VxD的工作是向应用程序代码提供一个与硬件接口的环境,为每一个客户虚 拟机管理虚设备的状态,透明地仲裁多个应用程序,同时对底层硬件进行访问。这就是所谓虚拟化的概念。 VxD在虚拟机管理器VMM(Virtual Machine Manager)的监控下运行,而VMM 实 际上是一个特殊的VxD。VMM执行与系统资源有关的工作,提供虚拟机环境(能产

Android_ROM制作移植及精简教程

Android_ROM制作,精简及移植教程 本教程主要内容有:Android系统文件夹结构解析、应用软件说明、定制精简、ROM签名把包等内容。刷机有风险,出问题自负。其实这个教程一早就想写的,但由于时间及本人的懒惰,一直拖着。今晚终于静下心来写好本文,本文有部份内容来自于网络。 速度与华丽,你喜欢那个。是不是想要一个又够速度又华丽的ROM呢?我是一个追求新鲜的人,对于手机的ROM,我又追求稳定、精简、美观、省电。现在Hero ROM有很多,最新的有第三方Android 2.1版本,但这些ROM的制作者都会跟据自已的个人喜欢会增加和增少相应的功能或是界面,但我们往往不喜欢这些ROM的某些小方面,所以随着而来面对的问题就是怎样把这个ROM修改成为一个自已真正需要的ROM呢?以往一直是依靠“大杀器”来解决,但觉得还是过于麻烦,所以寻求办法自己动手修改ROM。于是有了本文。废话少说,进入题。 一、Android系统文件夹结构 一个完整的ROM根目录会有以下几个文件夹及文件: data META-IN system boot.img 系统目录说明 1. 应用程序安装目录 1) 系统应用程序所在目录 /system/app/*.apk 2)用户安装应用程序所在目录 /data/app/*.apk 3) 注意: a)在模拟器中,每重启一次,/system/app/下的应用都会被还原,有时/data/app下也会被清除 b)若在/system/app和/data/app下有重名的应用,不一定会启动哪一个,尤其是在adb install杀死正在运行的程序时,有时旧的就会被启动 2.用户数据所在目录 /data/data/应用包名/shared_prefs 配置文件 /data/data/应用包名/databases/* 库文件所在目录 3. SD卡对应目录 /sdcard/

安卓系统移植经验之谈,教你三分钟移植

每当我闲下来时不发Rom时,就会整理一下思路,发发教程啥的,我觉得能带动机油们自己打造、改造Rom,共同提升,才是Romer的追求。 发Rom也好,教程也好,我的宗旨是不设回复可见,如果你觉得好,回复或者评分鼓励一下,我就很开心了。 不过这样做的一个遗憾就是,我的帖子通常回复率不够高,沉得快。 好了,闲话少说,上教程。 注:可能你会觉得文字教程比较干枯,不够形象生动,但是请精心看,我会尽量讲得具体、清晰。 首先,我并不算是移植高手,这个教程只是我在自己移植过程中的的一些收获体会,一些经验之谈。 如果你觉得有什么不对或值得改进的地方,欢迎和我交流,我们一起来完善这个教程。 因为移植所涉及的机型、配置相当多变和复杂,所以我无法讲具体细节,只能讲大致的原则。 可以结合我移植U8800+的JoyOS到U8860的例子作为参考进行理解。 我把这些原则抽象出来,命名为Rom移植5步法,具有一定的通用性。 Rom移植的方向有正向和逆向之分: 正向的做法通常就是,找个目标机型的底包,然后把要移植的包的app和framework提取出来替换进去。 这样的优点是改动无需太大,非常快捷;缺点是经常因为一些bin下的程序或者

库文件的差异而导致成功率不够高。 逆向的做法是,拿要移植的包作为底包,把目标机型的内核、wifi驱动、传感器库文件、配置文件等替换进去。 这样做要复杂一些,需要准确两个包的差异,知道应该改哪里; 优点自然是不成则已,一旦移植成功能最大限度地发挥Rom性能,因为框架、程序与底层的契合度要比正向法好。 我这个教程以逆向法为例。 另外,Rom移植有风险,刷机测试需谨慎,如有本人操作不当导致出现任何问题,本人概不负责。 Rom移植5步法: 1.Rom移植涉及的东西比较偏底层,所以在移植之前必须清楚目标机型的硬件配置,分区结构。 这里的配置不是说主频多少、内存多少,这两个参数基本上不会影响移植的进行。对于移植,最关键的因素是主板平台,通常采用同一系列的cpu的不同机型的Rom移植的成功率要高很多。 比如,U8800+和U8860均是高通8255处理器,虽然主频不一样,但它们却同属于同样的MSM7x30平台。 他们之间的互相移植,绝对要比与MSM7K平台的中兴V880互相移植来的容易得多。 至于为什么要弄清分区结构,会在下面讲到。

《设备驱动程序开发技术》大作业

《设备驱动程序开发技术》 大作业 WDM驱动程序的开发流程和要点班级:计算机科学与技术1004

摘要 DWDM(Windows Driver Model)是Microsoft公司推出的一种符合Windows2k/XP下的内核模式驱动程序的分层体系结构的驱动程序模式。它源于 Windows NT的分层32位设备驱动程序模型,它支持更多的特性,如即插即用( PnP ,Plug and Play )、电源管理( PM ,Power Management )、Windows管理诊断( WMI ,Windows Management Instrumentation )和 NT 事件。它为Windows操作系统的设备驱动程序提供了统一的框架,在Windows平台上,WDM将成为主流的驱动模式。WDM是Windows98和Windows2000使用的新的驱动程序设计规范。使用WDM使得硬件驱动程序更加稳定,让操作系统对硬件更加有效地控制硬件。除了定义一个驱动程序与操作系统连接的标准接口以外,WDM也指明了驱动程序应该采用的更加模块化的设计。 关键词: WDM、驱动程序、操作系统

1 概述 WDM(Windows Driver Model)是Microsoft公司推出的一种符合Windows2k/XP下的内核模式驱动程序的分层体系结构的驱动程序模式。相对于以前的KDM、VXD来说,它的性能更高、系统之间移植更加方便。随着Microsoft的操作系统的不断升级,WDM已逐步取代了KDM、VXD,成为了Microsoft系统下驱动程序开发的主流。 WDM是通过一个128位的全局唯一标识符(GUID)实现驱动程序的识别。应用程序与WDM 驱动程序通信时,应用程序将每个用户请求形成I/O请求包(IRP)发送到驱动程序。驱动程序识别出IRP请求后指挥硬件执行相应操作。 2 WDM驱动模型 WDM模型为存在于Windows 98和Windows 2000操作系统中的设备驱动程序提供了一个参考框架。尽管对于最终用户来说这两个操作系统非常相似,但它们的内部工作却有很大不同。 Windows 2000概述 图1是以我的视点所看到的Windows 2000操作系统,该图着重了驱动程序开发者所关心的特征。软件要么执行在用户模式中,要么执行在内核模式中。当用户模式程序需要读取设备数据时,它就调用Win32 API函数,如ReadFile。Win32子系统模块(如KERNEL32.DLL)通过调用平台相关的系统服务接口实现该API,而平台相关的系统服务将调用内核模式支持例程。在ReadFile调用中,调用首先到达系统DLL(NTDLL.DLL)中的一个入口点,NtReadFile 函数。然后这个用户模式的NtReadFile函数接着调用系统服务接口,最后由系统服务接口调用内核模式中的服务例程,该例程同样名为NtReadFile。

ANDROID Platform GT818 驱动移植说明书

Android平台GT818驱动移植说明书 【程序总揽】 本程序针对Android2.1系统,移植的硬件平台为华天正科技开发的Real6410(基于S3C6410)。本驱动支持多指,能够在系统支持的情况下在主控进入关屏状态时自动调整GT818工作状态,达到省电的目的。 1.1系统资源使用 1.2系统运行流程 为了便于移植,程序中采用了中断和定时查询两种方式,并建议使用中断方式。以中断方式为例,系统的主运行流程如下所示: 1.创建Guitar对应的i2c_client对象,其中完成了该适配器的相关信息设置; 2.加载触摸屏驱动,注意该驱动必须在I2C总线驱动已经加载的情况下才能进行,否则I2C通信将 出错。程序中将其加载优先级设为最低; 3.创建驱动结构体,探测Guitar设备,并将其挂载到I2C总线驱动上;测试I2C通信,注册input 设备,申请IO口和中断资源,完成Guitar初始化工作(如有需要,烧录升级在此进行); 4.开启触摸屏中断,等待数据接收; 5.收到触摸屏数据中断,关中断; 6.通过I2C传输数据,分析手指信息,; 7.更新按键信息,上报手指坐标、按键等信息,开中断; 8.重复4-7之间的循环。

【移植指南】 4.准备工作 本驱动采用GPL许可证,代码没有采用模块方式,所以使用本驱动前需要重新编译内核。在编译内核前,

我们需要做好以下准备工作: 1、在硬盘上或使用虚拟机(如VmWare)安装Linux系统,推荐使用Ubuntu9.10; 2、安装gcc及arm-linux-gcc和其他编译工具,将CC和LD指定为arm-linux-gcc; 3、获取平台对应的Android源码,解压到自己的工作目录。 4、了解移植平台的IO口、中断、I2C总线的使用方式。 5.内核编译配置 在编译代码前我们需要进行内核编译配置,可以使用下面命令中的一个: #make xconfig (基于QT的图形配置界面,非常直观,推荐使用) #make menuconfig (基于文本菜单的配置界面) 下面我们以make xconfig为例,将我们的驱动增加到内核中去。假定我们源代码目录为: ~/android/kernel/ 将编写的源代码复制到Linux内核源代码的相应目录: ~/android/kernel/driver/input/touchscreen/goodix_touch.c ~/android/kernel/include/linux/goodix_touch.h ~/android/kernel/include/linux/goodix_update.h //如果不做烧录则可以不加 1.在目录touchscreen的Kconfig文件中增加新源代码对应项目的编译配置选项: #----------------------------------------------------------------- config TOUCHSCREEN_GOODIX_GT818 # 配置项名称 tristate "S3C6410 TouchScreen Driver" #选择项,选择Y标识要将其编译进内核 default y #默认编译选项 depends on I2C #依赖项,本驱动必须工作在I2C总线驱动的基础上 help #帮助信息 It is a android driver to support Gooidx's touchscreen whose name is guitar on s3c6410 platform. The touchscreen can support multi-touch not more than two fingers. Say Y here to enable the driver for the touchscreen on the S3C SMDK board. If unsure, say N.To compile this driver as a module, choose M here: the module will be called goodix_touch.ko. #----------------------------------------------------------------- 注意: 当将编译选项设置为M时,编译生成的驱动需要我们手动挂载。如需要系统启动时自动挂载,需要将模块goodix_touch.ko拷贝到系统模块加载目录,并修改对应的启动过程的rc脚本。 2.在目录touchscreen的makefile文件中增加对新源代码的编译条目; #这里的二进制文件名必须与源文件名移植,如goodix_touch

虚拟块设备驱动程序设计与分析

如果只是为了应付考试,这个文档就太啰嗦了,不用看,不过还是可以帮助记忆,考试只会考其中加粗字体的几个函数中的一个,至于是哪个我不能断定,因此要记的还是比较多的,要是能理解就更好了,结合课本和下面的解释应该能大体上弄明白这个虚拟块设备驱动的 实现过程,毕竟设备驱动是内核的一部分,光看下面的解释也是还是很头晕的,不过坚持看下去还是有收获的,我也差不多花了半天时间,不过,要是打算……的话就可以直接跳过了。 #define MAJOR_NR 70 //我们创造的虚拟块设备的主设备号 #define DEVICE_NAME “bdemo”//我们创造的虚拟块设备的名字,当设备加载成功后可用lsmod命令查看到该设备模块名 #define blkdemo_devs 2 //虚拟块设备的个数 #define blkdemo_rahead 2 //读取块设备时预读的扇区个数 #define blkdemo_size 4 //每个虚拟块设备的大小,单位为KB #define blkdemo_blksize 1024 //设备每个数据块的大小,即block,单位为字节 #define blkdemo_hardsect 512 //设备每个扇区的大小,单位为字节 struct blkdemo_device { // 这里定义了我们将要创造的虚拟块设备的数据结构 int size; // 用来记录真实块设备的容量,即下面data指针所指向数据存储区的大小 int use_cnt; // 用来记录正在使用该块设备的程序的个数 int hardsect; // 用来保存该块设备每个扇区的大小,单位为字节,即设备的使用计数 u8 *data; // 该指针所指向的内存区域就是该块设备真正用来存储数据的区域,在该设备还未被加载函数初始化时,该指针为// 空,即系统还没有为该设备分配内存区域。 }; static int blkdemo_sizes[blkdemo_devs]; //用来保存我们创建的所有虚拟块设备的大小,单位为KB static int blkdemo_blksizes[blkdemo_devs]; //用来保存我们创建的所有虚拟块设备中每个数据块的大小,单位为字节static int blkdemo_hardsects[blkdemo_devs];//用来保存我们创建的所有虚拟块设备中每个扇区的大小,单位为字节 //上面的这三个数组将会在我们加载这些设备时被注册到内核的数据结构中(即让内核中与之相关的一些指针指向它们,让内核能够读取我们所创建的设备的一些重要信息 //对于一个新的设备,内核肯定不知道他为何物,要想让内核识别我们自己创造的设备,则必须将该设备的一些信息、使用这个设备的方//法等告诉内核,由于内核早已编译成型,至于如何去告诉内核就早已模式化。内核中有几个指针数组(书本page81)专门用来完成上面的部分任务: // blk_size[]; // blksize_size[]; // hardsect_size[]; // read_ahead[]; //这几个数组都为每一个主设备号留有一个位置,对于2.4的内核,主设备号和次设备号均用8位二进制来表示(即短整型的高八位和//低八位),因此这几个数组都包含有256个元素,每个元素都是与主设备号对应的一个指针,如果主设备号所对应的设备不存在,则该//指针置为空(NULL),其实其中很多指针都为空,因为一般电脑上都没有那么多不同类型的块设备,当然,对于我们所创造的这个块设//备而言,它与系统中所存在的其他块设备的类型都不同,要为其确定一个主设备号,这个没什么硬性的规定,只要找一个没被使用的主//设备号就可以了,这个程序中使用的是70(前面的MOJOR_NR宏)。上面我们定义了保存有虚拟块设备信息的数组,现在只要将他们的//首地址赋给这几个数组中下标70(主设备号)所对应的指针元素即可。这一过程是在后面的加载函数中完成的。 static int blksize = blkdemo_blksize; struct blkdemo_device blkdemo_dev[blkdemo_devs];//这里才真正创建了我们虚拟块设备对应的结构体变量(一个全局数组),//每个元素为对应一个虚拟块设备 虚拟块设备的打开函数(open()): int blkdemo_open(struct inode *inode, strcut file *filp) { //设备文件对应的节点(inode)结构中包含有对应的设备号 int num; num = DEVICE_NR(inode->i_rdev);//用DEVICE_NR宏可求出该节点所对应设备的次设备号,所以num即为次设备号if (!blkdemo_dev[num].use_cnt) { //如果该设备的使用计数为0,则说该设备没有被任何程序使用,当虚拟块设备没有被//任何程序使用时,内核先前为该设备所分配的存储区很可能已经被释放掉了,甚至对于可移动设备而言,有可能该设备都被拔掉了(当//然,我们的虚拟块设备是不可能的),因此,在打开该设备时要进行严格的检查,不然会导致设备打开出错而造成系统崩溃。 check_disk_change(inode->i_rdev);//首先检查该块设备是否发生了变化,比如已经被移除了(该设备不可能,所以//此处没有用if来判断,只是形式的调用了一下该函数。 if (!blkdemo_dev[num].data)//然后判断该设备的数据存储区域是否已经被释放掉了 return –ENOMEM; //如果是,则返回,告知系统该设备无法打开,-ENOMEM是一个内核中定义的宏,它代表的意思是//“error,no memory”。 }//如果上述情况均未发生,一切正常,则打开设备,对于这个虚拟的块设备,其实没有什么好打开的,不过还是意思一下:blkdemo_dev[num].use_cnt++; //将设备的使用计数加1,表示又多了个程序使用该设备。 MOD_INC_USE_COUNT; //并且将内核所管理的模块使用计数也加1,好让内核也知道多了一个程序使用该虚拟设备模块。模块使//用计数是内核管理模块时要用的,只有当一个设备的模块使用计数为0时才能卸载该模块,这个值也可以通过lsmod命令查看到return(0);//返回0,表示设备已成功打开 } 虚拟块设备的释放函数(release()): int blkdemo_release(struct inode *inode, struct file *filp) {//释放并不代表将此设备从内核中移除了,他是对调用它的程序而言的,只表示这个程序不再使用该设备了int num;

任意安卓移植ROM教程,超详细ROM技术学习

任意安卓移植ROM教程,超详细ROM技术学习 相信有过刷机经历的都知道安卓系统的构造,我们讲述一下安卓的几大组成:从内核基于linux开始,整个系统就运行在一个虚拟机上,这是安卓的一大特征!! 那么我们移植的时候要修改哪一部分?这就是我们这个帖子的重点了。在刷机时,我们大多使用zip格式的升级包进行刷机,那zip格式的升级包是怎么样的一个组成呢?一个zip升级包的完整构造,其中我们要移植所需要修改的就是META-INF里的刷机脚本。 对于这个构造,有必要完整的解释一次。 META-INF 这里面主要是签名文名和刷机时执行的脚本(updater-script),移植时,我们主要要更改的就是刷机的脚本。system 这里面就是android的系统部分app 这里存放的是系统的app,每个app都有两个文件,一个*.apk,一个*.odex,我们在移植时,要将这个文件合并到对应的*.apk里面去,apk文件其实就是一个zip文件,可以用WinRAR或7zip打开的,当然,合并odex文件不是把它改名直接放到apk里去这么简单的,后面具体介绍一下。还有,这个文件夹里面的程序,刷完以后是不能通过程序管理来卸载的。bin 这里面存放的是native程序,不好意思,一下子忘掉中文怎么说了。简单来说,apk是JAVA 程序,而这个是C/C++的程序。etc 这里面存放的是系统默认的配置文件,GPS的配置也在这里J。fonts 这个是字体文件夹,一般很少改动,除非要做美化framework 这里存放的是android框架,移植MIUI,很多改动在这个文件夹里,美化ROM的话,主要改framework-res.apk就可以了。当然,MIUI本身就有主题机制了,不用这么麻烦去改。这个文件夹里也会有对应的odex文件。lib 一些通过的类库,一般是由app/bin里面的程序调用的。media 媒体文件,要添加系统默认的铃声就在这里了。如果是别的ROM的话,壁纸也会放在这里面。

Linux设备驱动程序的概念、作用以及模块

Linux设备驱动程序的概念、作用以及模块 我们首先对linux系统整个框架要有个了解。Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,Linux的虚拟地址空间也为0~4G。 Linux 内核将这4G字节的空间分为两部分,分别是用户空间(0~3G)和内核空间(3G~4G)。其中,用户空间存放的是应用程序,而内核空间存放的是内核,设备驱动和硬件。 为什么需要存在设备驱动呢?我们知道,内核是操作系统基本的部分,而操作系统是不能够直接控制硬件的,这样我们就需要设备驱动作为操作系统和硬件设备间的粘合剂,相当于一个中间人吧,负责上下两边的沟通。驱动负责将操作系统的请求传输,转化为特定物理设备控制器能够理解的命令。 这样我们就知道,驱动需要完成两大功能: 1、为linux内核提供调用接口。 2、控制硬件。因为寄存器是控制硬件的操作,所以驱动程序控制硬件,也就是要通过读写硬件寄存器达到控制硬件的目的。 内核是为应用程序服务的,其本质其实是函数的集合,内核要实现的功能我们可以分为两部门:基本功能和扩展功能。其中,基本功能包括进程管理,线程管理等等,而扩展功能,可以根据用户的需求自行添加。 下面我们就来探讨一下怎样向内核添加一项功能呢? 1、我们首先想到,肯定需要写一个功能函数,假如我们命名为fun.c,那么函数写好后,必须要和linux源码一起编译,生成zImage内核镜像文件。 2、重新编译内核。 这样就得到了新的内核,这种添加的方式我们称为静态添加。大家发现,每次修改一次fun.c,都要重新编译一次内核,灰常的麻烦,所以引进了内核模块机制,只需要加载或卸载模块,就可以动态的增加或者删除内核的功能,不用每次都重新编译,是不是很方便?那么接下来我们会想到,这个模块怎么就能和内核连接在一起呢?其实很简单,fun.c文件除了要实现功能呢,还需要包含和内核的接口,内核也提供了模块的接口,只要这两个接口一致,模块就可以融入内核,成为内核的一部分。Linux驱动程序都是以模块的形式存在的,所以我们称之为驱动模块。 所以我们总结出添加模块的步骤是: 1、写功能函数fun.c。 怎么样编写模块的源码文件,我们以一个Hello模块实例分析。 #include #include //①模块的头文件,在对应内核下 的include目录中{ … //②功能函数hello.c(同普通} 的.c文件) Static int __int hellomudule_init(void) //③模块初始化函数 { Printk(“Hello world!\n”); Return 0; }

相关文档
最新文档