Microsoft Word - 第6章 Android驱动编程.docx

Size: px
Start display at page:

Download "Microsoft Word - 第6章 Android驱动编程.docx"

Transcription

1 Android 系统移植和驱动开发 作者 : 华清远见 第 6 章 Android 驱动编程 本章目标 本章将进入到 Android 的内核空间, 初步介绍嵌入式 Android 设备驱动的开发 驱动的开发流程相对于应用程序的开发是全新的, 与读者以前的编程习惯完全不同, 希望读者能尽快熟悉环境 本章主要内容 : 设备驱动概述 字符设备驱动编程 GPIO 驱动程序实例 4 4 扫描键盘驱动

2 6.1 Android 内核内核模块编程 1. 设备驱动和内核模块 Android 内核中采用可加载的模块化设计 (Loadable Kernel Modules,LKMs), 一般情况下编译的 Android 内核是支持可插入式模块的, 也就是将最基本的核心代码编译在内核中, 其他的代码可以编译到内核中或者编译为内核的模块文件 ( 在需要时动态加载 ) Android 内核设备驱动属于内核的一部分,Android 内核的一个模块可以以如下两种方式被编译和加载 : 直接编译进 Android 内核内核, 随同 Android 内核启动时加载 编译成一个可加载和删除的模块, 使用 insmod 加载 (modprobe 和 insmod 命令类似, 但依赖于相关的配置文件 ) rmmod 删除 这种方式控制了内核的大小, 而模块一旦被插入内核, 它就与内核其他部分一样 常见的驱动程序是作为内核模块动态加载的, 如声卡驱动和网卡驱动等, 而 Android 内核最基础的驱动, 如 CPU PCI 总线 TCP/IP APM( 高级电源管理 ) VFS 等驱动程序则直接编译在内核文件中 有时也把内核模块称为驱动程序, 只不过驱动的内容不一定是硬件罢了, 如 Ext3 文件系统的驱动 因此, 加载驱动就是加载内核模块 2. 模块相关命令 lsmod 列出了当前系统中加载的模块, 其中左边第一列是模块名, 第二列是该模块大小, 第三列则是使用该模块的对象数目, 代码如下 : $ lsmod Module Size Used by Autofs 1268 (autoclean) (unused) eepro iptable_nat (autoclean) (unused) ip_conntrack (autoclean) [iptable_nat] iptable_mangle 2272 (autoclean) (unused) iptable_filter 2272 (autoclean) (unused) ip_tables [iptable_nat iptable_mangle iptable_filter] usb-ohci (unused) usbcore [usb-ohci] ext jbd [ext3] aic7xxx sd_mod scsi_mod [aic7xxx sd_mod] rmmod 用于将当前模块卸载 insmod 和 modprobe 用于加载当前模块, 但 insmod 不会自动解除依存关系, 即如果要加载的模块引用了当前内核符号表中不存在的符号, 则无法加载, 也不会去查在其他尚未加载的模块中是否定义了该符号 ;modprobe 可以根据模块间依存关系, 以及 /etc/modules.conf 文件中的内容自动加载其他有依赖关系的模块 /proc 文件系统是一个伪文件系统, 它是一种内核和内核模块用来向进程发送信息的机制 这个伪文件系统让用户可以和内核内部数据结构进行交互, 获取有关系统和进程的有用信息, 在运行时通过改变内核参数来改变设置 与其他文件系统不同,/proc 存在于内存之中而不是在硬盘上 读者可以通过 ls 命令查看 /proc 文件系统的内容 表 6.1 列出了 /proc 文件系统的主要目录内容 表 6.1 /proc 文件系统的主要目录内容 目录名称目录内容目录名称目录内容 apm 高级电源管理信息 locks 内核锁 cmdline 内核命令行 meminfo 内存信息 2

3 cpuinfo CPU 相关信息 misc 杂项 devices 设备信息 ( 块设备 / 字符设备 ) modules 加载模块列表 dma 使用的 DMA 通道信息 mounts 加载的文件系统 filesystems 支持的文件系统信息 partitions 系统识别的分区表 interrupts 中断的使用信息 rtc 实时时钟 ioports I/O 端口的使用信息 stat 全面统计状态表 kcore 内核映像 swaps 对换空间的利用情况 kmsg 内核消息 version 内核版本 ksyms 内核符号表 uptime 系统正常运行时间 loadavg 负载均衡 除此之外, 还有一些是以数字命名的目录, 它们是进程目录 系统中当前运行的每一个进程都有对应 的一个目录在 /proc 下, 以进程的 PID 号为目录名, 它们是读取进程信息的接口 进程目录的结构如表 6.2 所示 表 6.2 /proc 中进程目录结构 目录名称 目录内容 目录名称 目录内容 cmdline 命令行参数 cwd 当前工作目录的链接 environ 环境变量值 exe 指向该进程的执行命令文件 fd 一个包含所有文件描述符的目录 maps 内存映像 mem 进程的内存被利用情况 statm 进程内存状态信息 stat 进程状态 root 链接此进程的 root 目录 status 进程当前状态, 以可读的方式显示出来 用户可以使用 cat 命令来查看其中的内容 可以看到,/proc 文件系统体现了内核及进程运行的内容, 在加载模块成功后, 读者可以通过查看 /proc/device 文件获得相关设备的主设备号 每个内核模块程序可以在任何时候到 /proc 文件系统中添加或删除自己的入口点 ( 文件 ), 通过该文件导出自己的信息 但后来在新的内核版本中, 内核开发者不提倡在 /proc 下添加文件, 而建议新的代码通过 sysfs 来向外导出信息 3.Android 内核内核模块编程 1) 内核模块的程序结构一个 Android 内核内核模块主要由以下几个部分组成 模块加载函数 ( 必需 ): 当通过 insmod 或 modprobe 命令加载内核模块时, 模块的加载函数会自动被内核执行, 完成本模块的相关初始化工作 模块卸载函数 ( 必需 ): 当通过 rmmod 命令卸载某模块时, 模块的卸载函数会自动被内核执行, 完成与模块加载函数相反的功能 模块许可证声明 ( 必需 ): 模块许可证 (LICENSE) 声明描述内核模块的许可权限, 如果不声明 LICENSE, 模块被加载时, 将收到内核被污染 (Kernel Tainted) 的警告 在 Android 2.6 内核中, 可接受的 LICENSE 包括 GPL GPL v2 GPL and additional rights Dual BSD/GPL Dual MPL/GPL 和 Proprietary 大多数情况下, 内核模块应遵循 GPL 兼容许可权 Android 2.6 内核模块最常见的是以 MODULE_LICENSE( "Dual BSD/GPL" ) 语句声明模块采用 BSD/GPL 双许可 3

4 专业始于专注卓识源于远见 模块参数 ( 可选 ): 模块参数是模块被加载时可以被传递给它的值, 它本身对应模块内部的全局变量 模块导出符号 ( 可选 ): 内核模块可以导出符号 (symbol, 对应于函数或变量 ), 这样其他模块可以使用本模块中的变量或函数 模块作者等信息声明 ( 可选 ) 2) 模块加载函数 Android 内核模块加载函数一般以 init 标识声明, 典型的模块加载函数的形式如下 : static int init initialization_function(void) /* 初始化代码 */ module_init(initialization_function); 模块加载函数必须以 module_init( 函数名 ) 的形式被指定 它返回整型值, 若初始化成功, 应返回 而在初始化失败时, 应该返回错误编码 在 Android 内核中, 错误编码是一个负值, 在 <Android 内核 /errno.h> 中定义, 包含 -ENODEV -ENOMEM 之类的符号值 返回相应的错误编码是个非常好的习惯, 因为只有这样, 用户程序才可以利用 perror 等方法把它们转换成有意义的错误信息字符串 在 Android 2.6 内核中, 可以使用 request_module(const char *fmt, ) 函数加载内核模块, 驱动开发人员可以通过调用 或 request_module(module_name); request_module("char-major-%d-%d", MAJOR(dev), MINOR(dev)); 来加载其他内核模块 在 Android 内核内核中, 所有标识为 init 的函数在连接时都放在.init.text 这个区段内, 此外, 所有的 init 函数在区段.initcall.init 中还保存了一些函数指针, 在初始化时内核会通过这些函数指针调用这些 init 函数, 并在初始化完成后释放 init 区段 ( 包括.init.text,.initcall.init 等 ) 3) 模块卸载函数 Android 内核模块卸载函数一般以 exit 标识声明, 典型的模块卸载函数的形式如下 : static void exit cleanup_function(void) /* 释放代码 */ module_exit(cleanup_function); 模块卸载函数在模块卸载时执行, 不返回任何值, 必须以 module_exit( 函数名 ) 的形式来指定 通常, 模块卸载函数要完成与模块加载函数相反的功能, 介绍如下 若模块加载函数注册了 XXX, 则模块卸载函数应该注销 XXX 若模块加载函数动态申请了内存, 则模块卸载函数应释放该内存 若模块加载函数申请了硬件资源 ( 如中断 DMA 通道 I/O 端口和 I/O 内存等 ) 的占用, 则模块卸载函数应释放这些硬件资源 若模块加载函数开启了硬件, 则卸载函数中一般要关闭硬件 与 init 一样, exit 也可以使对应函数在运行完成后自动回收内存 实际上, init 和 exit 都是宏, 其定义分别如下 : 和 #define init attribute (( section (".init.text"))) #ifdef MODULE #define exit attribute (( section (".exit.text"))) #else #define exit attribute_used attribute (( section (".exit.text"))) 4

5 #endif 数据也可以被定义为 initdata 和 exitdata, 这两个宏分别如下 : #define initdata attribute (( section (".init.data"))) 和 #define exitdata attribute (( section (".exit.data"))) 4) 模块参数我们可以用 module_param( 参数名, 参数类型, 参数读 / 写权限 ) 为模块定义一个参数, 下列代码定义了一个整型参数和一个字符指针参数 : static char *str_param = "Android 内核 Module Program"; static int num_param = 4; module_param(num_param, int, S_IRUGO); module_param(str_param, charp, S_IRUGO); 在装载内核模块时, 用户可以向模块传递参数, 形式为 insmode( 或 modprobe) 模块名参数名 = 参数值, 如果不传递, 参数将使用模块内定义的默认值 参数类型可以是 byte short ushort int uint long ulong charp( 字符指针 ) bool 或 invbool( 布尔的反 ), 在模块被编译时会将 module_param 中声明的类型与变量定义的类型进行比较, 判断是否一致 模块被加载后, 在 /sys/module/ 目录下将出现以此模块名命名的目录 当 参数读 / 写权限 为 时, 表示此参数不存在 sysfs 文件系统下对应的文件节点, 如果此模块存在 参数读 / 写权限 不为 的命令行参数, 则在此模块的目录下还将出现 parameters 目录, 包含一系列以参数名命名的文件节点, 这些文件的权限值就是传入 module_param() 的 参数读 / 写权限, 而文件的内容为参数的值 通常使用 <Android 内核 /stat.h> 中定义的值来表示权限值, 例如, 使用 S_IRUGO 作为参数可以被所有人读取, 但是不能改变 ; S_IRUGO S_IWUSR 允许 root 来改变参数 除此之外, 模块也可以拥有参数数组, 形式为 module_param_array( 数组名, 数组类型, 数组长, 参数读 / 写权限 ) 从 2.6. 到 版本, 需将数组长变量名赋给 数组长, 从 版本开始, 需将数组长变量的指针赋给 数组长, 当不需要保存实际输入的数组元素个数时, 可以设置 数组长 为 NULL 运行 insmod 或 modprobe 命令时, 应使用逗号分隔输入的数组元素 5) 导出符号 Android 2.6 的 /proc/kallsyms 文件对应着内核符号表, 它记录了符号及符号所在的内存地址 模块可以使用如下宏导出符号到内核符号表中 : EXPORT_SYMBOL( 符号名 ); EXPORT_SYMBOL_GPL( 符号名 ); 导出的符号将可以被其他模块使用, 使用前声明一下即可 EXPORT_SYMBOL_GPL() 只适用于包含 GPL 许可权的模块 6) 模块声明与描述在 Android 内核内核模块中, 可以用 MODULE_AUTHOR MODULE_DESCRIPTION MODULE_ VERSION MODULE_DEVICE_TABLE MODULE_ALIAS 分别声明模块的作者 描述 版本 设备表和别名, 例如 : MODULE_AUTHOR(author); MODULE_DESCRIPTION(description); MODULE_VERSION(version_string); MODULE_DEVICE_TABLE(table_info); MODULE_ALIAS(alternate_name); 对于 USB PCI 等设备驱动, 通常会创建一个 MODULE_DEVICE_TABLE 7) 模块的使用计数 Android 2.4 内核中, 模块自身通过 MOD_INC_USE_COUNT MOD_DEC_USE_COUNT 宏来管理自己被使用的计数 5

6 Android 2.6 内核提供了模块计数管理接口 try_module_get(&module) 和 module_put (&module), 从而取代 Android 2.4 内核中的模块使用计数管理宏 模块的使用计数一般不必由模块自身管理, 而且模块计数管理还考虑了 SMP 与 PREEMPT 机制的影响 int try_module_get(struct module *module); 该函数用于增加模块使用计数 ; 若返回为, 则表示调用失败, 希望使用的模块没有被加载或正在被卸载中 void module_put(struct module *module); 该函数用于减少模块使用计数 try_module_get () 与 module_put() 的引入与使用与 Android 2.6 内核下的设备模型密切相关 Android 2.6 内核为不同类型的设备定义了 struct module *owner 域, 用来指向管理此设备的模块 当开始使用某个设备时, 内核使用 try_module_get(dev->owner) 去增加管理此设备的 owner 模块的使用计数 ; 当不再使用此设备时, 内核使用 module_put(dev->owner) 减少对管理此设备的 owner 模块的使用计数 这样, 当设备在使用时, 管理此设备的模块将不能被卸载 只有当设备不再被使用时, 模块才允许被卸载 在 Android 2.6 内核下, 对于设备驱动工程师而言, 很少需要亲自调用 try_module_get() 与 module_put(), 因为此时开发人员所写的驱动通常为支持某具体设备的 owner 模块, 对此设备 owner 模块的计数管理由内核里更底层的代码 ( 如总线驱动或此类设备共用的核心模块 ) 来实现, 从而简化了设备驱动的开发 8) 模块的编译我们可以为 HelloWorld 模块程序编写一个简单的 Makefile, 如下 : obj-m := hello.o 并使用如下命令编译 HelloWorld 模块 : $ make -C /usr/src/android 内核 / M=/driver_study/ modules 如果当前处于模块所在的目录, 则以下命令与上述命令同等 : $ make C /usr/src/android 内核 M=$(pwd) modules 其中,-C 后指定的是 Android 内核源代码的目录, 而 M= 后指定的是 hello.c 和 Makefile 所在的目录, 编译结果如下 : $ make -C /usr/src/android 内核 / M=/driver_study/ modules make: Entering directory '/usr/src/android 内核 ' CC [M] /driver_study/hello.o /driver_study/hello.c:18:35: warning: no newline at end of file Building modules, stage 2. MODPOST CC /driver_study/hello.mod.o LD [M] /driver_study/hello.ko make: Leaving directory '/usr/src/android 内核 ' 从中可以看出, 编译过程中经历了这样的步骤 : 先进入 Android 内核所在的目录, 并编译出 hello.o 文件, 运行 MODPOST 会生成临时的 hello.mod.c 文件, 然后根据此文件编译出 hello.mod.o, 之后链接 hello.o 和 hello.mod.o 文件得到模块目标文件 hello.ko, 最后离开 Android 内核内核所在的目录 中间生成的 hello.mod.c 文件的源代码如下 : 1 #include <Android 内核 /module.h> 2 #include <Android 内核 /vermagic.h> 3 #include <Android 内核 /compiler.h> 4 5 MODULE_INFO(vermagic, VERMAGIC_STRING); 6 7 struct module this_module 8 attribute ((section(".gnu.linkonce.this_module"))) = 9.name = KBUILD_MODNAME, 1.init = init_module, 11 #ifdef CONFIG_MODULE_UNLOAD 12.exit = cleanup_module, 6

7 13 #endif 14 ; static const char module_depends[] 17 attribute_used 18 attribute ((section(".modinfo"))) = 19 "depends="; hello.mod.o 产生了 ELF(Android 内核所采用的可执行 / 可链接的文件格式 ) 的两个节, 即 modinfo 和.gun.linkonce.this_module 如果一个模块包括多个.c 文件 ( 如 file1.c file2.c), 则应该以如下方式编写 Makefile: obj-m := modulename.o module-objs := file1.o file2.o 9) 模块与 GPL 对于自己编写的驱动等内核代码, 如果不编译为模块则无法绕开 GPL, 编译为模块后企业在产品中使用模块, 则公司对外不再需要提供对应的源代码, 为了使公司产品所使用的 Android 内核操作系统支持模块, 需要完成如下工作 在内核编译时应该选择 Enable loadable module support, 嵌入式产品一般不需要动态卸载模块, 所以 可以卸载模块 不用选, 当然选了也没关系, 如图 6.1 所示 图 6.1 内核中支持模块的编译选项 如果有项目被选择 M, 则编译时除了制作镜像 make bzimage 以外, 也要编译模块 make modules 将编译的内核模块.ko 文件放置在目标文件系统的相关目录中 产品的文件系统中应该包含了支持新内核的 insmod lsmod rmmod 等工具, 由于嵌入式产品中一般不需要建立模块间依赖关系, 所以 modprobe 可以不要, 一般也不需要卸载模块, 所以 rmmod 也可以不要 在使用过程中用户可使用 insmod 命令手动加载模块, 如 insmod xxx.ko mount /proc mount /var 但是一般而言, 产品在启动过程中应该加载模块, 在嵌入式 Android 内核的启动过程中, 加载企业自己的模块的最简单方法是修改启动过程的 rc 脚本, 增加 insmod /.../xxx.ko 命令 例如, 某设备正在使用的 Android 内核系统中包含如下 rc 脚本 : mount /dev/pts mkdir /var/log mkdir /var/run mkdir /var/ftp mkdir -p /var/spool/cron mkdir /var/config 7

8 ... insmod /usr/lib/company_driver.ko 2> /dev/null /usr/bin/userprocess /var/config/rc 4. 内核模块实例程序 下面列出一个简单的内核模块程序, 它的功能是统计一个字符串中的各种字符 ( 如英文字母 数字 其他符号 ) 的数目 模块功能的演示如下 : $ insmod module_test.ko symbol_type=1 string="a1b+c=d4e5[6g7h,8i9k/l." $ dmesg tail n 1 Total symbols module init /* 在模块加载时打印 */ Digits: 7 /* 字符串中有 7 个数字 */ 第一个参数 (symbol_type) 表示统计类型 ( 为英文字母,1 为数字,2 为其他字符,3 以上为任何字符 ), 第二个参数 (string) 表示需要统计的字符串 实现该功能的模块代码如下 : #include <Android 内核 /init.h> #include <Android 内核 /module.h> #include <asm/string.h> #define TOTAL_LETTERS #define TOTAL_DIGITS 1 #define TOTAL_SYMBOLS 2 #define TOTAL_ALL TOTAL_LETTERS TOTAL_DIGITS TOTAL_SYMBOLS #define STR_MAX_LEN 256 static int symbol_type = TOTAL_ALL; static char *string = NULL; unsigned int total_symbols(char* string, unsigned int total_type) /* 该函数根据统计类型 (total_type) 计算相应字符的个数并返回 */ /* 这部分代码也可以从网上下载 */ EXPORT_SYMBOL(total_symbols); /* 导出的符号用 cat /proc/kallsyms grep "total_symbols" 命令检查 */ static int total_symbols_init(void) char type_str[str_max_len]; unsigned int number_of_symbols = ; switch(symbol_type) case TOTAL_LETTERS: /* 字母 统计 */ strcpy(type_str, "Letters"); break; case TOTAL_DIGITS: /* 数字 统计 */ strcpy(type_str, "Digits"); break; case TOTAL_SYMBOLS: /* 其他符号 统计 */ strcpy(type_str, "Symbols"); break; default: /* 默认为总体统计 */ case TOTAL_ALL: strcpy(type_str, "Characters"); number_of_symbols = total_symbols(string, symbol_type); printk("<1>total symbols module init\n"); 8

9 printk("<1>%s: %d\n", type_str, number_of_symbols); return ; static void total_symbols_exit(void) printk("<1>total symbols module exit\n"); module_init(total_symbols_init); /* 初始化设备驱动程序的入口 */ module_exit(total_symbols_exit); /* 卸载设备驱动程序的入口 */ module_param(symbol_type, uint, S_IRUGO); module_param(string, charp, S_IRUGO); MODULE_AUTHOR("David"); MODULE_DESCRIPTION("A simple module program"); MODULE_VERSION("V1."); 6.2 字符设备驱动编程 字符设备驱动编写流程 在 6.1 节中已经提到, 设备驱动程序可以使用模块的方式动态加载到内核中去 加载模块的方式与以往的应用程序开发有很大的不同 以往在开发应用程序时都有一个 main() 函数作为程序的入口点, 而在驱动开发时却没有 main() 函数, 模块在调用 insmod 命令时被加载, 此时的入口点是 module_init() 函数, 通常在该函数中完成设备的注册 同样, 模块在调用 rmmod 命令时被卸载, 此时的入口点是 module_exit() 函数, 在该函数中完成设备的卸载 在设备完成注册加载之后, 应用程序即对该设备进行一定的操作, 如 open() read() write() 等, 而驱动程序就是用于实现这些操作, 在应用程序调用相应入口函数时执行相关的操作 上述函数之间的关系如图 6.2 所示 重要数据结构 图 6.2 设备驱动程序流程图 在 Android 内核驱动程序中, 涉及 3 个重要的内核数据结构, 分别是 file_operation file 和 inode 在 Android 内核中 inode 结构用于表示文件, 而 file 结构则表示打开的文件描述符, 因为对于单个文件而言可能会有许多表示打开的文件描述符, 因此就可能会对应有多个 file 结构, 但它们都指向单个 inode 结构 此外, 每个 file 结构都与一组函数相关联, 这组函数是用 file_operations 结构来指示的 用户应用程序调用设备的一些功能是在设备驱动程序中定义的, 也就是设备驱动程序的入口点, 它是一个在 <Android 内核 /fs.h> 中定义的 struct file_operations 结构,file_operations 是 Android 内核驱动程序中最为重要的一个结构, 它定义了一组常见文件 I/O 函数, 这些函数在不同的驱动程序中会有不同的具体实现, 其结构如下 : struct file_operations loff_t (*llseek) (struct file *, loff_t, int); 9

10 ssize_t (*read) (struct file *filp, char *buff, size_t count, loff_t *offp); ssize_t (*write) (struct file *filp, const char *buff, size_t count, loff_t *offp); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); int (*flush) (struct file *); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *); int (*fasync) (int, struct file *, int); int (*check_media_change) (kdev_t dev); int (*revalidate) (kdev_t dev); int (*lock) (struct file *, int, struct file_lock *); ; 这里定义的很多函数是否与第 5 章中文件 I/O 的系统调用类似? 其实当时的系统调用函数通过内核, 最终调用对应的 file_operations 结构的接口函数 ( 例如,open() 文件操作是通过调用对应文件的 file_operations 结构的 open 函数接口而被实现 ) 当然, 每个设备的驱动程序不一定要实现其中所有的函数操作, 若不需要定义实现, 将其设为 NULL 即可 struct inode 结构提供了关于设备文件 /dev/driver( 假设此设备名为 driver) 的信息,file 结构提供关于被打开的文件信息, 主要供与文件系统对应的设备驱动程序使用 file 结构较为重要, 这里列出了它的定义 : struct file mode_t f_mode;/* 标识文件是否可读或可写,FMODE_READ 或 FMODE_WRITE*/ dev_t f_rdev; /* 用于 /dev/tty */ off_t f_pos; /* 当前文件位移 */ unsigned short f_flags; /* 文件标志, 如 O_RDONLY O_NONBLOCK 和 O_SYNC */ unsigned short f_count; /* 打开的文件数目 */ unsigned short f_reada; struct inode *f_inode; /* 指向 inode 的结构指针 */ struct file_operations *f_op;/* 文件索引指针 */ ; 设备驱动程序主要组成 1. 早期版本的字符设备注册早期版本的设备注册使用函数 register_chrdev(), 调用该函数后就可以向系统申请主设备号, 如果 register_chrdev() 操作成功, 设备名就会出现在 /proc/devices 文件中 在关闭设备时, 通常需要解除原先的设备注册, 此时可使用函数 unregister_chrdev(), 然后该设备就会从 /proc/devices 中消失 其中主设备号和次设备号不能大于 255 当前不少的字符设备驱动代码仍然使用这些早期版本的函数接口, 但在未来内核的代码中, 将不会出现这种编程接口机制 因此, 应尽量使用后面讲述的编程机制 register_chrdev() 函数语法要点如表 6.3 所示 表 6.3 register_chrdev() 函数语法要点 所需头文件 函数原型 函数传入值 #include <Android 内核 /fs.h> int register_chrdev(unsigned int major, const char *name,struct file_operations *fops) major: 设备驱动程序向系统申请的主设备号, 如果为, 则系统为此驱动程序动态地分配一个主设备号 name: 设备名 fops: 对各个调用的入口点 1

11 函数返回值 成功 : 如果是动态分配主设备号, 则返回所分配的主设备号 且设备名会出现在 /proc/devices 文件中 出错 : 1 unregister_chrdev() 函数语法要点如表 6.4 所示 表 6.4 unregister_chrdev() 函数语法要点 所需头文件函数原型函数传入值函数返回值 #include <Android 内核 /fs.h> int unregister_chrdev(unsigned int major, const char *name) major: 设备的主设备号, 必须和注册时的主设备号相同 name: 设备名成功 :, 且设备名从 /proc/devices 文件中消失出错 : 1 2. 设备号相关函数 设备号是一个数字, 它是设备的标志 设备号有主设备号和次设备号, 其中主设备号表示设备类型, 对应于确定的驱动程序, 具备相同主设备号的设备之间共用同一个驱动程序, 而用次设备号来标识具体物理设备 因此, 在创建字符设备之前, 必须先获得设备的编号 ( 可能需要分配多个设备号 ) 在 Android 2.6 中, 用 dev_t 类型来描述设备号 (dev_t 是 32 位数值类型, 其中高 12 位表示主设备号, 低 2 位表示次设备号 ) 用两个宏 MAJOR 和 MINOR 分别获得 dev_t 设备号的主设备号和次设备号, 而且用 MKDEV 宏来实现逆过程, 即组合主设备号和次设备号而获得 dev_t 类型设备号 #include <Android 内核 /kdev.h> MAJOR(dev_t dev); /* 获得主设备号 */ MINOR(dev_t dev); /* 获得次设备号 */ MKDEV(int major, int minor); 分配设备号有静态和动态两种方法 静态分配 (register_chrdev_region() 函数 ) 是指在事先知道设备主设备号的情况下, 通过参数函数指定第一个设备号 ( 它的次设备号通常为 ) 而向系统申请分配一定数目的设备号 动态分配 (alloc_chrdev_region()) 是指通过参数仅设置第一个次设备号 ( 通常为, 事先不会知道主设备号 ) 和要分配的设备数目而系统动态分配所需的设备号 通过 unregister_chrdev_region() 函数释放已分配的 ( 无论是静态的还是动态的 ) 设备号 它们的函数格式如表 6.5 所示 表 6.5 设备号分配与释放函数语法要点 所需头文件 #include <Android 内核 /fs.h> int register_chrdev_region (dev_t first, unsigned int count, char *name) 函数原型 int alloc_chrdev_region (dev_t *dev, unsigned int firstminor, unsigned int count, char *name) void unregister_chrdev_region (dev_t first, unsigned int count) first: 要分配的设备号的初始值 函数传入值 count: 要分配 ( 释放 ) 的设备号数目 name: 要申请设备号的设备名称 ( 在 /proc/devices 和 sysfs 中显示 ) dev: 动态分配的第一个设备号 函数返回值 成功 :( 只限于两种注册函数 ) 出错 : 1( 只限于两种注册函数 ) 11

12 3. 最新版本的字符设备注册在获得了系统分配的设备号之后, 通过注册设备才能实现设备号和驱动程序之间的关联 这里讨论 2.6 内核中的字符设备的注册和注销过程 在 Android 内核中使用 struct cdev 结构来描述字符设备, 在驱动程序中必须将已分配到的设备号及设备操作接口 ( 即为 struct file_operations 结构 ) 赋予 cdev 结构变量 首先使用 cdev_alloc() 函数向系统申请分配 cdev 结构, 再用 cdev_init() 函数初始化已分配到的结构并与 file_operations 结构关联起来 最后调用 cdev_add() 函数将设备号与 struct cdev 结构进行关联并向内核正式报告新设备的注册, 这样新设备可以用了 如果要从系统中删除一个设备, 则要调用 cdev_del() 函数 具体函数格式如表 6.6 所示 表 6.6 最新版本的字符设备注册 所需头文件函数原型函数传入值函数返回值 #include <Android 内核 /cdev.h> sturct cdev *cdev_alloc(void) void cdev_init(struct cdev *cdev, struct file_operations *fops) int cdev_add (struct cdev *cdev, dev_t num, unsigned int count) void cdev_del(struct cdev *dev) cdev: 需要初始化 / 注册 / 删除的 struct cdev 结构 fops: 该字符设备的 file_operations 结构 num: 系统给该设备分配的第一个设备号 count: 该设备对应的设备号数量成功 : cdev_alloc: 返回分配到的 struct cdev 结构指针 cdev_add: 返回 出错 : cdev_alloc: 返回 NULL cdev_add: 返回 内核仍然保留早期版本的 register_chrdev() 等字符设备相关函数, 其实从内核代码中可以发现, 在 register_chrdev() 函数的实现中用到 cdev_alloc() 和 cdev_add() 函数, 而在 unregister_chrdev() 函数的实现中用到 cdev_del() 函数 因此很多代码仍然使用早期版本接口, 但这种机制将来会从内核中消失 前面已经提到字符设备的实际操作在 file_operations 结构的一组函数中定义, 并在驱动程序中需要与字符设备结构关联起来 下面讨论 file_operations 结构中最主要的成员函数和它们的用法 4. 打开设备打开设备的函数接口是 open, 根据设备的不同,open 函数接口完成的功能也有所不同, 其原型如下 : int (*open) (struct inode *, struct file *); 通常在 open 函数接口中要完成如下工作 : 如果未初始化, 则进行初始化 识别次设备号, 如果必要, 更新 f_op 指针 分配并填写被置于 filp->private_data 的数据结构 检查设备特定的错误 ( 如设备未就绪或类似的硬件问题 ) 打开计数是 open 函数接口中常见的功能, 它是用于计算自从设备驱动加载以来设备被打开过的次数 由于设备在使用时通常会多次被打开, 也可以由不同的进程所使用, 所以若有一个进程想要删除该设备, 则必须保证其他设备没有使用该设备 因此, 使用计数器就可以很好地完成这项功能 5. 释放设备释放设备的函数接口是 release() 要注意释放设备和关闭设备是完全不同的 当一个进程释放设备时, 其他进程还能继续使用该设备, 只是该进程暂时停止对该设备的使用, 并没有真正关闭该设备 ; 而当一个进程关闭设备时, 其他进程必须重新打开此设备才能使用它 12

13 释放设备时要完成的工作如下 : 释放打开设备时系统所分配的内存空间 ( 包括 filp->private_data 指向的内存空间 ) 在最后一次关闭设备 ( 使用 close() 系统调用 ) 时, 才会真正释放设备 ( 执行 release() 函数 ) 即在打开计数等于 时的 close() 系统调用才会真正进行设备的释放操作 6. 读 / 写设备读 / 写设备的主要任务就是把内核空间的数据复制到用户空间, 或者从用户空间复制到内核空间, 也就是将内核空间缓冲区中的数据复制到用户空间的缓冲区中或者相反 这里首先解释一个 read() 和 write() 函数的入口函数, 如表 6.7 所示 表 6.7 read write 函数接口语法要点 所需头文件 函数原型 #include <Android 内核 /fs.h> ssize_t (*read) (struct file *filp, char *buff, size_t count, loff_t *offp) ssize_t (*write) (struct file *filp, const char *buff, size_t count, loff_t *offp) filp: 文件指针 函数传入值 buff: 指向用户缓冲区 count: 传入的数据长度 offp: 用户在文件中的位置 函数返回值 成功 : 写入的数据长度 虽然这个过程看起来很简单, 但是内核空间地址和应用空间地址是有很大区别的, 其中一个区别是用户空间的内存是可以被换出的, 因此可能会出现页面失效等情况 所以不能使用诸如 memcpy() 之类的函数来完成这样的操作 在这里要使用 copy_to_user() 或 copy_from_user() 等函数, 它们是用来实现用户空间和内核空间的数据交换的 copy_to_user() 和 copy_from_user() 的格式如表 6.8 所示 表 6.8 copy_to_user() 和 copy_from_user() 函数语法要点 所需头文件 函数原型 #include <asm/uaccess.h> unsigned long copy_to_user(void *to, const void *from, unsigned long count) unsigned long copy_from_user(void *to, const void *from, unsigned long count) to: 数据目的缓冲区 函数传入值 from: 数据源缓冲区 count: 数据长度 函数返回值 成功 : 写入的数据长度失败 :-EFAULT 要注意, 这两个函数不仅实现了用户空间和内核空间的数据转换, 而且还会检查用户空间指针的有效性 如果指针无效, 那么就不进行复制 7.ioctl 大部分设备除了读 / 写操作, 还需要硬件配置和控制 ( 例如, 设置串口设备的波特率 ) 等很多其他操作 在字符设备驱动中 ioctl 函数接口给用户提供对设备的非读 / 写操作机制 ioctl 函数接口的具体格式如表 6.9 所示 表 6.9 ioctl 函数接口语法要点 所需头文件 函数原型 函数传入值 #include <Android 内核 /fs.h> int(*ioctl)(struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg) inode: 文件的内核内部结构指针 13

14 filp: 被打开的文件描述符 cmd: 命令类型 arg: 命令相关参数 8. 获取内存在应用程序中获取内存通常使用函数 malloc(), 但在设备驱动程序中动态开辟内存可以以字节或页面为单位 其中, 以字节为单位分配内存的函数有 kmalloc(), 需要注意的是,kmalloc() 函数返回的是物理地址, 而 malloc() 等返回的是线性虚拟地址, 因此在驱动程序中不能使用 malloc() 函数 与 malloc() 不同, kmalloc() 申请空间有大小限制 长度是 2 的整次方, 并且不会对所获取的内存空间清零 如果驱动程序需要分配比较大的空间, 使用基于页的内存分配函数会更好些 以页为单位分配内存的函数如下 : get_zeroed_page() 函数分配一个页大小的空间并清零该空间 get_free_page() 函数分配一个页大小的空间, 但不清零空间 get_free_pages() 函数分配多个物理上连续的页空间, 但不清零空间 get_dma_pages() 函数在 DMA 的内存区段中分配多个物理上连续的页空间 与之相对应的释放内存的函数有 kfree() 或 free_page 函数族 表 6.1 给出了 kmalloc() 函数的语法要点 表 6.1 kmalloc() 函数语法要点 所需头文 件 函数原型 void *kmalloc(unsigned int len,int flags) #include <Android 内核 /malloc.h> len: 希望申请的字节数 GFP_KERNEL: 内核内存的通常分配方法, 可能引起睡眠 GFP_BUFFER: 用于管理缓冲区高速缓存 函数传入值 flags GFP_ATOMIC: 为中断处理程序或其他运行于进程上下文之外的代码分配内存, 且不会引起睡眠 GFP_USER: 用户分配内存, 可能引起睡眠 GFP_HIGHUSER: 优先高端内存分配 GFP_DMA:DMA 数据传输请求内存 GFP_HIGHMEN: 请求高端内存 函数返回值 成功 : 写入的数据长度失败 :-EFAULT 表 6.11 给出了 kfree() 函数的语法要点 表 6.11 kfree() 函数语法要点 所需头文件 #include <Android 内核 /malloc.h> 函数原型 函数传入值 函数返回值 void kfree(void * obj) obj: 要释放的内存指针成功 : 写入的数据长度失败 :-EFAULT 表 6.12 给出了以页为单位的分配函数 get_free_ page 类函数的语法要点 表 6.12 get_free_ page 类函数语法要点 14

15 所需头文件函数原型函数传入值函数返回值 #include <Android 内核 /malloc.h> unsigned long get_zeroed_page(int flags) unsigned long get_free_page(int flags) unsigned long get_free_page(int flags,unsigned long order) unsigned long get_dma_pages(int flags,unsigned long order) flags: 同 kmalloc() order: 要请求的页面数, 以 2 为底的对数成功 : 返回指向新分配的页面的指针失败 :-EFAULT 表 6.13 给出了基于页的内存释放函数 free_ page 族函数的语法要点 表 6.13 free_page 类函数语法要点 所需头文件函数原型函数传入值函数返回值 #include <Android 内核 /malloc.h> unsigned long free_page(unsigned long addr) unsigned long free_pages(unsigned long addr, unsigned long order) addr: 要释放的内存起始地址 order: 要请求的页面数, 以 2 为底的对数 成功 : 写入的数据长度失败 :-EFAULT 9. 打印信息就如同在编写用户空间的应用程序, 打印信息有时是很好的调试手段, 也是在代码中很常用的组成部分 但是与用户空间不同, 在内核空间要用函数 printk(); 而不能用平常的函数 printf() printk() 和 printf() 很类似, 都可以按照一定的格式打印消息, 不同的是,printk() 还可以定义打印消息的优先级 表 6.14 给出了 printk() 函数的语法要点 表 6.14 printk 类函数语法要点 所需头文件 函数原型 int printk(const char * fmt, ) #include <Android 内核 /kernel> 函数传入值 fmt: 日志级别 KERN_EMERG: 紧急时间消息 KERN_ALERT: 需要立即采取动作的情况 KERN_CRIT: 临界状态, 通常涉及严重的硬件或软件操作失败 KERN_ERR: 错误报告 KERN_WARNING: 对可能出现的问题提出警告 KERN_NOTICE: 有必要进行提示的正常情况 KERN_INFO: 提示性信息 KERN_DEBUG: 调试信息 : 与 printf() 相同 函数返回值 成功 : 失败 : 1 这些不同优先级的信息输出到系统日志文件 ( 例如 : /var/log/messages ), 有时也可以输出到虚拟控制台上 其中, 对输出给控制台的信息有一个特定的优先级 console_loglevel 只有打印信息的优先级小于这个整数值, 信息才能被输出到虚拟控制台上, 否则, 信息仅被写入到系统日志文件中 若不加任何优先级选项, 则消息默认输出到系统日志文件中 15

16 6.3 LCD 控制器 LCD 控制器介绍 1. 液晶屏的分类液晶显示屏按显示原理分为 STN 和 TFT 两种 STN(Super Twisted Nematic, 超扭曲向列 ) 液晶屏 :STN 液晶显示器与液晶材料 光线的干涉现象有关, 因此显示的色调以淡绿色与橘色为主 STN 液晶显示器中, 使用 X Y 轴交叉的单纯电极驱动方式, 即 X Y 轴由垂直与水平方向的驱动电极构成, 水平方向驱动电压控制显示部分为亮或暗, 垂直方向的电极则负责驱动液晶分子的显示 STN 液晶显示屏加上彩色滤光片, 并将单色显示矩阵中的每一像素分成 3 个子像素, 分别通过彩色滤光片显示红 绿 蓝三原色, 也可以显示出色彩 单色液晶屏及灰度液晶屏都是 STN 液晶屏 TFT(Thin Film Transistor, 薄膜晶体管 ) 彩色液晶屏 : 随着液晶显示技术的不断发展和进步,TFT 液晶显示屏被广泛用于制作成计算机中的液晶显示设备 TFT 液晶显示屏既可在笔记本电脑上应用 ( 现在大多数笔记本电脑都使用 TFT 显示屏 ), 也可用于主流台式显示器 2. 液晶屏的显示液晶屏的显示要求设计专门的驱动与显示控制电路 驱动电路包括提供液晶屏的驱动电源和液晶分子偏置电压, 以及液晶显示屏的驱动逻辑 ; 显示控制部分可由专门的硬件电路组成, 也可以采用集成电路 (IC) 模块, 如 EPSON Silicon Motion 的显卡驱动器等 ; 还可以使用处理器外围 LCD 控制模块 S5PC1 LCD 控制器介绍 S5PC1 处理器集成了 LCD 控制器, 主要用于传输显示数据和产生控制信号 它并支持屏幕水平和垂直滚动显示 数据的传送采用 DMA( 直接内存访问 ) 方式, 以达到最小的延迟 它可以支持多种液晶屏, 如 STN LCD 显示器 TFT LCD 显示控制器 STN LCD 显示器性能如下 支持 3 种类型的扫描方式 :4 位单扫描 4 位双扫描和 8 位单扫描 支持 256 色和 496 色彩色 STN LCD 典型的实际屏幕大小是 : 等 最大虚拟屏幕占内存大小为 4MB 256 色模式下最大虚拟屏幕大小 : 等 TFT LCD 显示控制器性能如下 : 支持 或 8bpp 彩色调色显示 支持 16bpp 和 24bpp 非调色真彩显示 在 24bpp 模式下, 最多支持 16M 种颜色 支持多种屏幕大小 典型的实际屏幕大小是 : 等 最大虚拟屏幕占内存大小为 4MB 64K 色模式下最大虚拟屏幕大小 : 等 1.S5PC1 功能简述 S5PC1 的集成 LCD 控制器功能很强大, 其中包含一个本地总线传输图像数据的逻辑模块, 以及内置的图像处理单元 这些模块都可通过总线连接至外接的 LCD 接口,LCD 接口包含 3 种类型, 有 RGB 接口 间接的 -i8 接口 ITU-R BT.61/656 接口 显示控制器支持最多 5 个叠加图像窗口, 每个窗口都支持多种图像格式, 以及 256 灰度级绑定 颜色锁定 x-y 坐标控制 软件卷动 可变的窗体尺寸, 等等 16

17 显示控制器支持多种颜色格式, 例如,RGB(1bpp-24bpp) YcbCr4:4:4( 限于本地总线 ) 显示控制器可编程支持不同需求的图像像素 数据线宽度 时序 刷新率 2.LCD 外部接口信号 S5PC1 的 LCD 控制器包括两个时序部分, 一个针对 RGB 接口 ITU-R61/656 的时序 ; 另一个针对间接 i8 接口的时序 本书重点介绍关于 RGB 接口的控制器部分 RGB VIME 产生的控制信号有 VSYNC( 垂直同步信号 ) HSYNC( 水平同步信号 ) VDEN( 数据有效信号 ) VCLK(LCD 时钟 ), 这些信号都可由寄存器配置, 还有 VD[23:] 的数据输出口 如图 6.3 所示为 LCD-RGB 接口时序 图 6.3 LCD RGB 接口时序图 S5PC1 LCD 控制器操作基于前面介绍的 RGB 接口时序图, 下面介绍 LCD 的控制流程 给出如下 3 个公式 : HOZVAL =(Horizontal display size -1) LINEVAL=(Vertical display size -1) VCLK(Hz)= HCLK/(CLKVAL+1) where CLKVAL >= 1 这些公式在配置寄存器的时候都需要使用到 下面简单解释一下 RGB 接口时序图的意义, 在一帧画面的呈现中, 涉及如下步骤 : 首先 LCD 控制器发出一次 VSYNC 信号, 这时会伴随发出 HSYNC 信号, 可以想象一下,LCD 屏的显示方式, 先选中第一行 (VSYNC 信号 ), 然后从第一列开始顺序选中 (HSYNC 信号 ), 在每次的 HSYNC 中, 会发生数据传输, 这时是由 VCLK 来决定的 在每一帧时钟信号中, 还会有一些与屏显示无关的时钟出现, 这就给确定行频和场频带来了一定的难度 如在 HSYNC 信号中先后会有水平同步信号前肩 (HFPD) 和水平同步信号后肩 (HBPD) 出现, 在 VSYNC 信号中先后会有垂直同步信号前肩 (VFPD) 和垂直同步信号后肩 (VBPD) 出现, 在这些信号时序内, 不会有有效像素信号出现, 另外,HSYNC 和 VSYNC 信号有效时, 其电平要保持一定的时间, 它们分别称为水平同步信号脉宽 HSPW 和垂直同步信号脉宽 (VSPW), 这段时间也不能有像素信号 因此, 计算行频和场频时, 一定要包括这些信号 HBPD HFPD 和 HSPW 的单位是一个 VCLK 的时间, 而 VSPW VFPD 和 VBPD 的单位是扫描一行所用的时间 在 S5PC1 中, 还需要重点考虑 Alpha 绑定机制, 因为它是 5 个窗口叠加共同呈像的原理, 因此需要配置一下 Alpha 绑定方程, 如图 6.4 所示 17

18 图 6.4 Alpha 绑定过程从图中可以看到, 每次叠加由两个窗口进行, 窗口的顺序依次是 : (1)X = 窗口 与窗口 1 (2)X1 = X 与窗口 2 (3)X2 = X1 与窗口 3 (4)X4 = X2 与窗口 4 最后的 X4 为 LCD 所呈现的图像, 如图 6.5 所示 图 6.5 绑定方程其中,B' 是一个色值函数, 它由 A 的色值分量与 B 的色值分量线性叠加而成 此处,A 的色值来自 win(n+1),b 的色值来自 win(n),a b 则是线性因子 我们只需要考虑 a b 的值, 就可以得到想要的结果 同理,alphaB' 是一个 B' 色值的伴随灰度值函数, 即一组 alpha 通道 它的构成与前一个方程是同构的 p q 也是线性因子, 这样 4 个因子决定了两个窗口的最终叠加色值, 以及伴随 alpha 的值 ( 注意,a b p q 是只能可选值, 从图 6.5 中可以看出这一点 ) 在 LCD 控制器中, 只需要配置 WINn blending equation control register, 并将具体的因子配好后, 就可以实现了, 注意 5 个窗口需要同时配置方程 接下来重点考察 alphab 灰度值, 它是一个 8bit 的值,~255 分别代表了不同的灰度级 从方程中可以看出, 如果一个 alpha 值与一个色值相乘后, 就会得到一个该色值的分量, 这样两个窗口的叠加就靠不同的灰度来确定 换句话说, 如果要使 win1~win4 窗体整体透明, 就必须使 win1~win4 的灰度级最高, 则使得 alpha value 为, 并且色值方程配置 pn=,qn=,an=alphaa,bn=(1-alphaa), 其中 n=1,2,3,4 即可实现 window 显示, 而其他窗口透明 LCD 控制器寄存器由于在 S5PC1 中 LCD 控制器的寄存器众多, 这里只简单介绍一下我们要用到, 并且很重要的寄存器, 如果想了解更多的信息, 请参看 S5PC1 手册 各寄存器及其参数含义如表 6.15 至表 6.24 所示 表 6.15 VIDCON,R/W,ADDRESS=xEE 18

19 Field Bit Description Reset Value Reserved [31] Reserved (should be ) INTERLACE_ F [29] 逐行扫描方式或者间隔扫描方式 = 逐行扫描 1 = 间隔扫描方式 (only ITU61/656 Interface) 输出格式 : VIDOUT [27:26 ] : RGB I/F 1 = ITU61/656 1 = Indirect I8 I/F for LDI 11 = Indirect I8 I/F for LDI1 选择显示模式 (Where, VIDOUT[1:] == 2 b). PNRMODE [18:17 ] = RGB 格式 (RGB) 1 = RGB 格式 (BGR) 1 = Serial Format (R->G->B) 11 = Serial Format (B->G->R) 选择 CLKVAL_F 刷新时序的模式 CLKVALUP [16] CLKVAL_F [13:6] VCLKFREE [5] CLKDIR [4] CLKSEL_F [2] ENVID [1] ENVID_F [] = 总在刷新 1 = 当一帧开始时决定 VCLK 的速率以及 CLKVAL[7:] VCLK = HCLK / (CLKVAL+1) 且 CLKVAL >= 1 Note. 1. VCLK 最大值是 66MHz. 2. CLKSEL_F 寄存器选择的时钟源 VCLK 控制方式 = 普通模式 (ENVID) 1 = 自由模式选择时钟源的通道 = 直接获取时钟 (VCLK = Clock source) 1 = 除以分频值选择时钟源 = HCLK 1 = SCLK_LCD 数据输出使能位 = 禁止 1 = 使能当前帧结束使能位 = 禁止 1 = 使能如果该位被设置, 则该位直到一帧结束时才被禁止 表 6.16 VIDCON1,R/W,ADDRESS=xEE4 19

20 Field Bit Description Reset Value LINECNT (read only) [26:16] 提供 line counter 的计数值 (read only) 从 到 LINEVAL FSTATUS [15] VSTATUS [14:13] 场状态 (read only). = 非平坦场 1 = 平坦场垂直状态 read only). = VSYNC 1 = 后肩 1 = ACTIVE 11 = 前肩 Reserved [12:8] Reserved IVCLK [7] IHSYNC [6] IVSYNC [5] IVDEN [4] VCLK 极性 = VCLK 下降沿取数据 1 = VCLK 上升沿取数据该位决定了 HSYNC 脉冲极性. = 普通 1 = 反转该位决定了 VSYNC 脉冲极性 = 普通 1 = 反转该位决定了 VDEN 信号极性 = 普通 1 = 反转 Reserved [3:] Reserved x 表 6.17 VIDTCON,R/W,ADDRESS=XEE1 Field Bit Description Reset VBPD [23:16] 垂直后肩所占周期 x VFPD [15:8] 垂直前肩所占周期 x VSPW [7:] 垂直同步脉冲宽度 x 表 6.18 VIDTCON1,R/W,ADDRESS=XEE14 Field Bit Description Reset Value HBPD [23:16] 水平后肩所占周期 x HFPD [15:8] 水平前肩所占周期 x HSPW [7:] 水平同步脉冲宽度 x 表 6.19 VIDTCON2,R/W,ADDRESS=XEE18 Field Bit Description Reset Value LINEVAL [21:11] 该位决定了显示屏的垂直尺寸 HOZVAL [1:] 该位决定了显示屏的水平尺寸 表 6.2 VIDTCON2,R/W,ADDRESS=XEE2 Field Bit Description Reset Value ENLOCAL [22] 数据存取路径 2

21 BUFSTATUS [21] BUFSEL [2] BUFAUTOEN [19] BITSWP [18] BYTSWP [17] HAWSWP [16] WSWP [15] = DMA 方式 1 = 本地方式 (CAMIF ) 缓冲区的编号 ( 这是因为 Windows 中 1 可以有两个缓冲区 )(Read Only) = 缓冲区 1 = 缓冲区 1 选择缓冲区 (/1) = 缓冲区 1 = 缓冲区 1 双缓冲自动控制位 = BUFSEL, 1 = 自动改变由 Trigger Input 控制 位交换控制位 = 禁止交换 1 = 使能交换 字节交换控制位 = 禁止交换 1 = 使能交换 半字交换控制位 = 禁止交换 1 = 使能交换 字交换控制位 = 禁止交换 1 = 使能交换 Reserved [14] Reserved InRGB [13] 输入的源图像的格式 (Only for EnLcal enable) = RGB 1 = YCbCr Reserved [12:11] Reserved (should be ) BURSTLEN [1:9] DMA s Burst 最大长度 = 16 字 1 = 8 字 1 = 4 字 续表 Field Bit Description Reset Value Reserved [8:7] Reserved BLD_PIX [6] BPPMODE_F [5:2] 选择绑定的类型 = 平面绑定 1= 像素绑定 BPP(Bits Per Pixel) 模式 = 1 bpp 1 = 2 bpp 1 = 4 bpp 11 = 8 bpp ( palletized ) 1 = 8 bpp ( 无调色盘, A: 1-R:2-G:3-B:2 ) 11 = 16 bpp ( 无调色盘, R:5-G:6-B:5 ) 11 = 16 bpp ( 无调色盘, A:1-R:5-G:5-B:5 ) 111 = 16 bpp ( 无调色盘, I :1-R:5-G:5-B:5 ) 1 = unpacked 18 bpp ( 无调色盘, R:6-G:6-B:6 ) 11 = unpacked 18 bpp ( 无调色盘, A:1-R:6-G:6-B:5 ) 11 = unpacked 19 bpp ( 无调色盘, A:1-R:6-G:6-B:6 ) 111 = unpacked 24 bpp ( 无调色盘, R:8-G:8-B:8 ) 21

22 11 = unpacked 24 bpp ( 无调色盘,A:1-R:8-G:8-B:7 ) *111 = unpacked 25 bpp ( 无调色盘, A:1-R:8-G:8-B:8 ) *111 = unpacked 13 bpp ( 无调色盘,A:1-R:4-G:4-B:4 ) 1111 = unpacked 15 bpp ( 无调色盘, R:5-G:5-B:5 ) 专业始于专注卓识源于远见 ALPHA_SEL [1] 选择 Alpha 值的方式平面绑定时 : = using ALPHA_R/G/B values 1 = using ALPHA1_R/G/B values 像素绑定时 : = AEN 使能位置 ( 细节请参看 S5PC1 手册 ) ENWIN_F [] = 窗口禁止 1 = 窗口使能 表 6.21 FRAME BUFFER ADDRESS,R/W,ADDRESS=XEEA Field Bit Description Reset Value VBANK_F [31:24] [31:24] 决定系统内存中的 bank 地址 VBASEU_F [23:] [23:] 决定 frame buffer 的起始地址 表 6.22 FRAME BUFFER ADDRESS 1,R/W,ADDRESS=XEED Field Bit Description Reset Value VBASEL_F [23:] [23:] 决定了 frame buffer 的结束地址 x 表 6.23 FRAME BUFFER ADDRESS 2,R/W,ADDRESS=XEE1 Field Bit Description Reset Value OFFSIZE_F [25:13] 虚拟屏幕偏移 (B) PAGEWIDTH_F [12:] 虚拟页宽度 (B) 表 6.24 WINDOW 1 BLENDING EQUATION CONTROL REGISTER,R/W,ADDRESS=XEE244 Field Bit Description Reset Value reserved [31:22] reserved x Q_FUNC [21:18] alphab 值为 : = (zero) 1 = 1 (max) 1 = **alphaa (alpha value of *foreground) 11 = 1 alphaa 1 = alphab 11 = 1 alphab 11x = reserved 1x = reserved 11 = A (foreground color data) 111 = 1 A 11 = B (background color data) 111 = 1 B 111x = reserved x reserved [17:16] Reserved 22

23 P_FUNC [15:12] Alpha 值为 : 同上 专业始于专注卓识源于远见 x reserved [11:1] Reserved B_FUNC [9:6] B 的值为 : 同上 x3 reserved [5:4] Reserved A_FUNC [3:] A 的值为 : 同上 x2 6.4 驱动程序 本部分共有两个文件, 一个是 led_drv.ko, 这是驱动程序 ; 另一个是 main, 它是 main.c 生成的测试程序, 可以通过 ioctl 来控制驱动程序, 测试驱动程序是否达到目标 下面列出了编写驱动时候要用到的原理图, 主要有 S5PC1 芯片手册和 FS_S5PC1A LED 电路图 S5PC1 芯片手册片段如下 : 23

24 FS_S5PC1A LED 电路图如图 6.6 所示 驱动程序初始化和退出 图 6.6 FS_S5PC1A LED 电路图 驱动程序初始化和退出的代码如下 : static int simple_major = 25; /* * Set up the cdev structure for a device. // 默认的设备号码, 如果为 则尝试自动分配 */ static void simple_setup_cdev(struct cdev *dev, int minor, struct file_operations *fops) // 自编的函数, 注册字符设备 int err, devno = MKDEV(simple_major, minor);// 建立设备号 cdev_init(dev, fops); dev->owner = THIS_MODULE; dev->ops = fops; err = cdev_add (dev, devno, 1); /* Fail gracefully if need be */ if (err) /* // 初始化设备结构体 struct cdev *dev // 关联 fops // 注册一个字符设备 // 注册失败处理 printk (KERN_NOTICE "Error %d adding simple%d", err, minor); * Our various sub-devices. */ /* Device uses remap_pfn_range */ static struct file_operations simple_remap_ops = // 定义设备的 fops.owner = THIS_MODULE,.open = simple_open,.release = simple_release,.read = simple_read,.write = simple_write,.ioctl ; = simple_ioctl, /* * We export two simple devices. There's no need for us to maintain any * special housekeeping info, so we just deal with raw cdevs. 24

25 */ static struct cdev SimpleDevs; /* * Module housekeeping. */ static struct class *my_class; static int simple_init(void) int result; dev_t dev = MKDEV(simple_major, ); // 将设备号转化为 dev_t 的结构 /* Figure out our device number. */ if (simple_major) result = register_chrdev_region(dev, 1, "simple");// 尝试申请主设备号 else // 请求自动分配主设备号, 起始值是, 总共分配 1 个, 设备名 simple result = alloc_chrdev_region(&dev,, 1, "simple"); simple_major = MAJOR(dev);// 将分配成功的设备号保存在 simple_major 变量中 if (result < ) // 分配主设备号失败 printk(kern_warning "simple: unable to get major %d\n", simple_major); return result; if (simple_major == ) simple_major = result; /* Now set up two cdevs. */ // 调用自编的函数注册字符设备, 有 Bug, 没有返回注册是否成功 simple_setup_cdev(&simpledevs,, &simple_remap_ops); //Bug: 打印前应该检查注册是否成功 printk("simple device installed, with major %d\n", simple_major); // 建立一个叫 simple 的内核 class, 目的是下一步创建设备节点文件 my_class= class_create(this_module, "simple"); device_create(my_class, NULL, MKDEV(simple_major, ), NULL, "led");// 创建设备节点文件 return ; static void simple_cleanup(void) cdev_del(&simpledevs); // 删除字符设备 unregister_chrdev_region(mkdev(simple_major, ), 1);// 注销主设备号 device_destroy(my_class,mkdev(simple_major,));// 删除设备节点 printk("simple device uninstalled\n"); module_init(simple_init); module_exit(simple_cleanup); 驱动程序 Open and release 函数 驱动程序 Open and release 函数代码如下 : // 寄存器地址, 见 CPU 手册 7 页 #define pgpg3con xe31c #define pgpg3dat xe31c4 // 寄存器操作指针 static void *vgpg3con, *vgpg3dat; #define GPG3CON (*(volatile unsigned int *) vgpg3con) #define GPG3DAT (*(volatile unsigned int *) vgpg3dat) 25

26 static int simple_major = 25; module_param(simple_major, int, ); MODULE_AUTHOR("farsight"); MODULE_LICENSE("Dual BSD/GPL"); // 默认的主设备号 // 向内核申明一个参数, 可以在 insmod 时传递给驱动程序 /* * Open the device; in fact, there's nothing to do here. */ int simple_open (struct inode *inode, struct file *filp) vgpg3con=ioremap(pgpg3con,x1);//io remap 地址 pgpg3con 到变量 vgpg3dat=vgpg3con+x4; // 计算 vgpg3dat 寄存器的地址 GPG3CON=x1111; // 使用宏设定寄存器初始值 GPG3DAT=xff; return ; // 使用宏设定寄存器初始值 ssize_t simple_read(struct file *file, char user *buff, size_t count, loff_t *offp) return ; ssize_t simple_write(struct file *file, const char user *buff, size_t count, loff_t *offp) return ; static int simple_release(struct inode *node, struct file *file) return ; 驱动程序 ioctl 函数 驱动程序 ioctl 函数代码如下 : //ioctl 命令值,LED ON,LED OFF #define LED_ON x48 #define LED_OFF x481 void led_off( void ) GPG3DAT=GPG3DAT (1<<2); // 通过宏设定寄存器的值, 置 1 //printk( stop led\n ); void led_on( void ) GPG3DAT=GPG3DAT&(~(1<<2)); // 通过宏设定寄存器的值, 置 //printk( start led\n ); static int simple_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) switch ( cmd ) case LED_ON: led_on(); break; // 判断命令 // 执行命令 26

27 case LED_OFF: default: return ; led_off(); break; break; 驱动测试程序 main.c 驱动测试程序 main.c 代码如下 : /* * main.c : test demo driver */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #define LED_ON x48 #define LED_OFF x481 int main() int i = ; int dev_fd; dev_fd = open("/dev/simple",o_rdwr O_NONBLOCK);// 打开设备文件 if ( dev_fd == -1 ) printf("cann't open file /dev/simple\n"); exit(1); while(1) ioctl(dev_fd,led_on,); // printf("on\n"); sleep(1); ioctl(dev_fd,led_off,); // printf("off\n"); sleep(1); return ; // 发送 ioctl 命令 LED_ON // 发送 ioctl 命令 LED_OFF 6.5 小结 本章主要介绍了嵌入式 Android 内核设备驱动程序开发的基础 首先介绍了设备驱动程序的基础知识 驱动程序与整个软硬件系统之间的关系, 以及 Android 内核内核模块的基本编程 接下来重点讲解了字符设备驱动程序的编写, 这里详细介绍了字符设备驱动程序的编写流程 重要的数据结构 设备驱动程序的主要函数接口 然后又以 GPIO 驱动为例介绍了一个简单的字符驱动程序的编写步骤 最后, 介绍了中断编程, 并以编写完整的按键驱动程序为例进行讲解 27

28 6.6 思考题 1. 根据书中的提示, 将本章所述的按键驱动程序进行进一步的改进, 并在目标板上进行测试 2. 实现各种外设 ( 包括 ADC SPI I 2 C 等 ) 的字符设备驱动程序 联系方式 集团官网 : 嵌入式学院 : 移动互联网学院 : 企业学院 : 物联网学院 : 研发中心 :dev.hqyj.com 集团总部地址 : 北京市海淀区西三旗悦秀路北京明园大学校内华清远见教育集团 北京地址 : 北京市海淀区西三旗悦秀路北京明园大学校区, 电话 : /5 上海地址 : 上海市徐汇区漕溪路 25 号银海大厦 11 层 B 区, 电话 : 深圳地址 : 深圳市龙华新区人民北路美丽 AAA 大厦 15 层, 电话 : 成都地址 : 成都市武侯区科华北路 99 号科华大厦 6 层, 电话 : 南京地址 : 南京市白下区汉中路 185 号鸿运大厦 1 层, 电话 : 武汉地址 : 武汉市工程大学卓刀泉校区科技孵化器大楼 8 层, 电话 : 西安地址 : 西安市高新区高新一路 12 号创业大厦 D3 楼 5 层, 电话 : 广州地址 : 广州市天河区中山大道 268 号天河广场 3 层, 电话 :

华恒家庭网关方案

华恒家庭网关方案 LINUX V1.5 1 2 1 2 LINUX WINDOWS PC VC LINUX WINDOWS LINUX 90% GUI LINUX C 3 REDHAT 9 LINUX PC TFTP/NFS http://www.hhcn.com/chinese/embedlinux-res.html minicom NFS mount C HHARM9-EDU 1 LINUX HHARM9-EDU

More information

static struct file_operations gpio_ctl_fops={ ioctl: gpio_ctl_ioctl, open : gpio_open, release: gpio_release, ; #defineled1_on() (GPBDAT &= ~0x1) #def

static struct file_operations gpio_ctl_fops={ ioctl: gpio_ctl_ioctl, open : gpio_open, release: gpio_release, ; #defineled1_on() (GPBDAT &= ~0x1) #def Kaise s 2410 Board setting [1]. Device Driver Device Driver Linux s Kernel ARM s kernel s3c2410_kernel2.4.18_r1.1_change.tar.bz2 /usr/src (1) #cd /usr/src (2) #tar xfj s3c2410_kernel2.4.18_r1.1_change.tar.bz2

More information

<4D F736F F D20B5DA36D5C22020D7D6B7FBC9E8B1B8C7FDB6AF>

<4D F736F F D20B5DA36D5C22020D7D6B7FBC9E8B1B8C7FDB6AF> LINUX 设备驱动开发详解 作者 : 华清远见 第 6 章 字符设备驱动 Linux Linux 6.1 Linux cdev file_operations Linux 6.2 globalmem 6 9 6.3 6.1 globalmem seek() I/O globalmem 6.4 6.3 globalmem Linux 字符设备驱动结构 6.1.1 cdev 结构体 在 Linux 2.6

More information

CC213

CC213 : (Ken-Yi Lee), E-mail: feis.tw@gmail.com 49 [P.51] C/C++ [P.52] [P.53] [P.55] (int) [P.57] (float/double) [P.58] printf scanf [P.59] [P.61] ( / ) [P.62] (char) [P.65] : +-*/% [P.67] : = [P.68] : ,

More information

chap07.key

chap07.key #include void two(); void three(); int main() printf("i'm in main.\n"); two(); return 0; void two() printf("i'm in two.\n"); three(); void three() printf("i'm in three.\n"); void, int 标识符逗号分隔,

More information

DVK530/531扩展板

DVK530/531扩展板 DVK720 扩展板 驱动移植手册 2014.04.03 V1.0 版权声明 本手册所有权由深圳市微雪电子有限公司独家持有 未经本公司的书 面许可, 不得以任何方式或形式进行修改 分发或复制本文档的任何 部分, 否则一切后果由违者自负 版本更新记录 版本日期说明 V1.0 2014.04.03 初始发布 深圳市微雪电子有限公司 www.waveshare.net I 目录 版权声明... I 版本更新记录...

More information

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例 帝国 CMS 下在 PHP 文件中调用数据库类执行 SQL 语句实例 这篇文章主要介绍了帝国 CMS 下在 PHP 文件中调用数据库类执行 SQL 语句实例, 本文还详细介绍了帝国 CMS 数据库类中的一些常用方法, 需要的朋友可以参考下 例 1: 连接 MYSQL 数据库例子 (a.php)

More information

Guava学习之Resources

Guava学习之Resources Resources 提供提供操作 classpath 路径下所有资源的方法 除非另有说明, 否则类中所有方法的参数都不能为 null 虽然有些方法的参数是 URL 类型的, 但是这些方法实现通常不是以 HTTP 完成的 ; 同时这些资源也非 classpath 路径下的 下面两个函数都是根据资源的名称得到其绝对路径, 从函数里面可以看出,Resources 类中的 getresource 函数都是基于

More information

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++;

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++; Memory & Pointer trio@seu.edu.cn 2.1 2.1.1 1 int *p int a 0x00C7 0x00C7 0x00C7 2.1.2 2 int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++; 2.1.3 1. 2. 3. 3 int A,

More information

Bus Hound 5

Bus Hound 5 Bus Hound 5.0 ( 1.0) 21IC 2007 7 BusHound perisoft PC hound Bus Hound 6.0 5.0 5.0 Bus Hound, IDE SCSI USB 1394 DVD Windows9X,WindowsMe,NT4.0,2000,2003,XP XP IRP Html ZIP SCSI sense USB Bus Hound 1 Bus

More information

JLX

JLX PRODUCT:LCD MODULE. Model No.: JLX177-006 Product Type: 1.77 inch QVGA TFT Modoule. 产品规格书 晶联讯研发研发部 : Written By Checked By Approved By 客户名称 : 结构电子核准 地址 : 深圳市宝安区西乡宝安大道东华工业区 A3 栋 6 楼电话 :0755-29784961 Http://www.jlxlcd.cn

More information

新・明解C言語入門編『索引』

新・明解C言語入門編『索引』 !... 75!=... 48 "... 234 " "... 9, 84, 240 #define... 118, 213 #include... 148 %... 23 %... 23, 24 %%... 23 %d... 4 %f... 29 %ld... 177 %lf... 31 %lu... 177 %o... 196 %p... 262 %s... 242, 244 %u... 177

More information

<4D F736F F D20C7B6C8EBCABDCFB5CDB3BFAAB7A2CAB5D1E9CBC42E646F63>

<4D F736F F D20C7B6C8EBCABDCFB5CDB3BFAAB7A2CAB5D1E9CBC42E646F63> 嵌入式系统实验四 Linux 下设备驱动程序的开发 3.1 设备驱动程序的开发流程 进行嵌入式 Linux 系统的开发, 很大的工作量是为各种设备编写驱动程序 在 ARM 平台上开发嵌入式 Linux 的设备驱动程序与在其他平台上开发是一样的 总的来说, 实现一个嵌入式 Linux 设备驱动的大致流程如下 : (1) 查看原理图, 理解设备的工作原理 (2) 定义主设备号 (3) 在驱动程序中实现驱动的初始化

More information

第11章、嵌入式Linux设备驱动开发

第11章、嵌入式Linux设备驱动开发 黑色经典 系列之 嵌入式 Linux 应用程序开发详解 第 11 章嵌入式 Linux 设备驱动开发 本章目标 本书从第 6 章到第 10 章详细讲解了嵌入式 Linux 应用程序的开 发, 这些都是处于用户空间的内容 本章将进入到 Linux 的内核空间, 初步介绍嵌入式 Linux 设备驱动的开发 驱动的开发流程相对于应用 程序的开发是全新的, 与读者以前的编程习惯完全不同, 希望读者能 尽快地熟悉现在环境

More information

嵌入式Linux知识培训

嵌入式Linux知识培训 嵌入式 Linux 知识培训 主要包括以下四部分内容 : 一 嵌入式 Linux 开发的基本知识 二 Linux 下使用 C 语言进行系统开发 三 面向嵌入式 Linux 的 GUI 系统的体系结构及二次开发 四 基于 Linux OS Smart Phone 的体系结构及开发内容 李玉东 第一部分 基础知识 嵌入式 Linux 软件系统的构成 1.BootLoader 2. Kernel 3.FileSystem

More information

六域链联盟 SDChain-Matrix 节点搭建指南 2018/07/26 Version : 1.0.0

六域链联盟 SDChain-Matrix 节点搭建指南 2018/07/26 Version : 1.0.0 SDChain-Matrix 节点搭建指南 目录 1 环境要求... 3 2 软件下载... 4 3 安装部署... 4 3.1 部署可执行程序目录... 4 3.2 部署配置文件目录... 4 3.3 部署数据库文件目录... 4 3.4 部署日志文件目录... 4 3.5 部署依赖库文件目录... 4 4 配置参数... 5 5 启动运行... 7 5.1 普通模式启动... 7 5.2 加载启动模式...

More information

<4D F736F F F696E74202D20B5DAB6FEBDB2A3BAC7B6C8EBCABD4C696E75782D416E64726F6964C7FDB6AFBFAAB7A2BDD2C3D8D6AED2BABEA7C6C1C7FDB6AFBFAAB7A22DB9F9C0CFCAA62E BBCE6C8DDC4A3CABD5D>

<4D F736F F F696E74202D20B5DAB6FEBDB2A3BAC7B6C8EBCABD4C696E75782D416E64726F6964C7FDB6AFBFAAB7A2BDD2C3D8D6AED2BABEA7C6C1C7FDB6AFBFAAB7A22DB9F9C0CFCAA62E BBCE6C8DDC4A3CABD5D> 在线大讲堂 手机驱动开发揭秘之液晶屏驱动开发 版权 华清远见嵌入式培训中心版权所有 ; 未经华清远见明确许可, 不能为任何目的以任何形式复制或传播此文档的任何部分 ; 本文档包含的信息如有更改, 恕不另行通知 ; 保留所有权利 2 主要内容 1. 液晶屏技术背景 2. 液晶屏接口分析 3. 液晶屏驱动框架分析 液晶屏与触摸屏关系 显示输出 控制输入 液晶屏与触摸屏关系 输入设备 软件 计算机硬件接口

More information

C PICC C++ C++ C C #include<pic.h> C static volatile unsigned char 0x01; static volatile unsigned char 0x02; static volatile unsigned cha

C PICC C++ C++ C C #include<pic.h> C static volatile unsigned char 0x01; static volatile unsigned char 0x02; static volatile unsigned cha CYPOK CYPOK 1 UltraEdit Project-->Install Language Tool: Language Suite----->hi-tech picc Tool Name ---->PICC Compiler Executable ---->c:hi-picinpicc.exe ( Command-line Project-->New Project-->File Name--->myc

More information

1

1 SDT Uclinux SDT.alf.c 44blib.alf 44blib.c jtag ADS.alf.c make menuconfig make dep make clean make lib_only make user_only make romfs make image make uclinux ext2 cash lcd frambuffer 1 armsys-c uclinux

More information

untitled

untitled 1 Outline 數 料 數 數 列 亂數 練 數 數 數 來 數 數 來 數 料 利 料 來 數 A-Z a-z _ () 不 數 0-9 數 不 數 SCHOOL School school 數 讀 school_name schoolname 易 不 C# my name 7_eleven B&Q new C# (1) public protected private params override

More information

Microsoft Word - 实用案例.doc

Microsoft Word - 实用案例.doc 计 算 机 系 统 应 用 2009 年 第 12 期 嵌 入 式 Linux 下 温 湿 度 传 感 器 的 设 计 与 实 现 1 Design and Implementation of Temperature and Humidity Sensor Based on Embedded Linux 陈 博 刘 锦 高 ( 华 东 师 范 大 学 电 子 科 学 技 术 系 上 海 200241)

More information

C/C++语言 - C/C++数据

C/C++语言 - C/C++数据 C/C++ C/C++ Table of contents 1. 2. 3. 4. char 5. 1 C = 5 (F 32). 9 F C 2 1 // fal2cel. c: Convert Fah temperature to Cel temperature 2 # include < stdio.h> 3 int main ( void ) 4 { 5 float fah, cel ;

More information

C语言的应用.PDF

C语言的应用.PDF AVR C 9 1 AVR C IAR C, *.HEX, C,,! C, > 9.1 AVR C MCU,, AVR?! IAR AVR / IAR 32 ALU 1KBytes - 8MBytes (SPM ) 16 MBytes C C *var1, *var2; *var1++ = *--var2; AVR C 9 2 LD R16,-X ST Z+,R16 Auto (local

More information

新版 明解C++入門編

新版 明解C++入門編 511!... 43, 85!=... 42 "... 118 " "... 337 " "... 8, 290 #... 71 #... 413 #define... 128, 236, 413 #endif... 412 #ifndef... 412 #if... 412 #include... 6, 337 #undef... 413 %... 23, 27 %=... 97 &... 243,

More information

untitled

untitled 3 C++ 3.1 3.2 3.3 3.4 new delete 3.5 this 3.6 3.7 3.1 3.1 class struct union struct union C class C++ C++ 3.1 3.1 #include struct STRING { typedef char *CHARPTR; // CHARPTR s; // int strlen(

More information

概述

概述 OPC Version 1.6 build 0910 KOSRDK Knight OPC Server Rapid Development Toolkits Knight Workgroup, eehoo Technology 2002-9 OPC 1...4 2 API...5 2.1...5 2.2...5 2.2.1 KOS_Init...5 2.2.2 KOS_InitB...5 2.2.3

More information

地 方, 硬 件 工 程 师 在 写 完 了 一 个 4*4 键 盘 驱 动 后, 无 需 也 不 必 管 应 用 程 序 在 获 得 键 值 后 做 哪 些 处 理 及 操 作 也 就 是 说 软 件 工 程 师 需 要 看 到 一 个 没 有 硬 件 的 纯 软 件 世 界, 硬 件 必 须 透

地 方, 硬 件 工 程 师 在 写 完 了 一 个 4*4 键 盘 驱 动 后, 无 需 也 不 必 管 应 用 程 序 在 获 得 键 值 后 做 哪 些 处 理 及 操 作 也 就 是 说 软 件 工 程 师 需 要 看 到 一 个 没 有 硬 件 的 纯 软 件 世 界, 硬 件 必 须 透 以 下 是 凌 阳 教 育 的 嵌 入 式 linux 培 训 资 深 讲 师 - 徐 老 师 提 供 的 免 费 的 linux 驱 动 基 础 开 发 教 程 (linux 驱 动 基 础 开 发 0- linux 驱 动 基 础 开 发 3) 理 论 加 实 例 详 解, 重 点 红 字 标 注 linux 初 学 者 必 看! 一 :linux 驱 动 基 础 开 发 0--linux 设

More information

Microsoft Word - 在VMWare-5.5+RedHat-9下建立本机QTopia-2.1.1虚拟平台a.doc

Microsoft Word - 在VMWare-5.5+RedHat-9下建立本机QTopia-2.1.1虚拟平台a.doc 在 VMWare-5.5+RedHat-9 下建立 本机 QTopia-2.1.1 虚拟平台 张大海 2008-5-9 一 资源下载 1. 需要以下安装包 : tmake-1.13.tar.gz qtopia-free-source-2.1.1.tar.gz qt-embedded-2.3.10-free.tar.gz qt-x11-2.3.2.tar.gz qt-x11-free-3.3.4.tar.gz

More information

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double

More information

6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C C C51 C51 ANSI C MCS-51 C51 ANSI C C C51 bit Byte bit sbit

6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C C C51 C51 ANSI C MCS-51 C51 ANSI C C C51 bit Byte bit sbit 6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C51 6.1 C51 6.1.1 C51 C51 ANSI C MCS-51 C51 ANSI C C51 6.1 6.1 C51 bit Byte bit sbit 1 0 1 unsigned char 8 1 0 255 Signed char 8 11 128

More information

EK-STM32F

EK-STM32F STMEVKIT-STM32F10xx8 软 件 开 发 入 门 指 南 目 录 1 EWARM 安 装... 1 1.1 第 一 步 : 在 线 注 册... 1 1.2 第 二 步 : 下 载 软 件... 2 1.3 第 三 步 : 安 装 EWARM... 3 2 基 于 STMEVKIT-STM32F10xx8 的 示 例 代 码 运 行... 6 2.1 GPIO Demo... 6 2.2

More information

A Preliminary Implementation of Linux Kernel Virus and Process Hiding

A Preliminary Implementation of Linux Kernel Virus and Process Hiding 邵 俊 儒 翁 健 吉 妍 年 月 日 学 号 学 号 学 号 摘 要 结 合 课 堂 知 识 我 们 设 计 了 一 个 内 核 病 毒 该 病 毒 同 时 具 有 木 马 的 自 动 性 的 隐 蔽 性 和 蠕 虫 的 感 染 能 力 该 病 毒 获 得 权 限 后 会 自 动 将 自 身 加 入 内 核 模 块 中 劫 持 的 系 统 调 用 并 通 过 简 单 的 方 法 实 现 自 身 的

More information

CC213

CC213 : (Ken-Yi Lee), E-mail: feis.tw@gmail.com 177 [P179] (1) - [P181] [P182] (2) - for [P183] (3) - switch [P184] [P187] [P189] [P194] 178 [ ]; : : int var; : int var[3]; var 2293620 var[0] var[1] 2293620

More information

东南大学硕士学位论文 LCD 显示中灰度控制机理的研究及电路实现姓名 : 曹志香申请学位级别 : 硕士专业 : 微电子学与固体电子学指导教师 : 孙大有 20040327 LCD 显示中灰度控制机理的研究及电路实现 作者 : 曹志香 学位授予单位 : 东南大学 相似文献 (1 条 ) 1.

More information

Microsoft Word - 01.DOC

Microsoft Word - 01.DOC 第 1 章 JavaScript 简 介 JavaScript 是 NetScape 公 司 为 Navigator 浏 览 器 开 发 的, 是 写 在 HTML 文 件 中 的 一 种 脚 本 语 言, 能 实 现 网 页 内 容 的 交 互 显 示 当 用 户 在 客 户 端 显 示 该 网 页 时, 浏 览 器 就 会 执 行 JavaScript 程 序, 用 户 通 过 交 互 式 的

More information

Linux服务器构建与运维管理

Linux服务器构建与运维管理 1 Linux 服务器构建与运维管理 第 2 章 :Linux 基本命令 阮晓龙 13938213680 / rxl@hactcm.edu.cn http://linux.xg.hactcm.edu.cn http://www.51xueweb.cn 河南中医药大学管理科学与工程学科 2018.3 2 提纲 目录与文件的操作 mkdir touch mv cp rm rmdir file tree

More information

ebook15-C

ebook15-C C 1 1.1 l s ( 1 ) - i i 4. 14 - d $ l s -ldi /etc/. /etc/.. - i i 3077 drwxr-sr-x 7 bin 2048 Aug 5 20:12 /etc/./ 2 drwxr-xr-x 13 root 512 Aug 5 20:11 /etc/../ $ls -ldi /. /..... i 2 2 drwxr-xr-x 13 root

More information

FY.DOC

FY.DOC 高 职 高 专 21 世 纪 规 划 教 材 C++ 程 序 设 计 邓 振 杰 主 编 贾 振 华 孟 庆 敏 副 主 编 人 民 邮 电 出 版 社 内 容 提 要 本 书 系 统 地 介 绍 C++ 语 言 的 基 本 概 念 基 本 语 法 和 编 程 方 法, 深 入 浅 出 地 讲 述 C++ 语 言 面 向 对 象 的 重 要 特 征 : 类 和 对 象 抽 象 封 装 继 承 等 主

More information

Microsoft Word - Driver For Wince 4.2.doc

Microsoft Word - Driver For Wince 4.2.doc LCD TO VGA Card Drivers For WINCE 4.2 LCD 转 VGA 输出视频卡基于 WINCE 4.2 的驱动编程 在 WIN CE 操作系统中,LCD2VGA Card ( 简称 ) 使用的是标准 16BIT_TFT 真彩 LCD 的驱动程序 在这里只以 1024*768 分辨率为例说明在 WIN CE 4.2 中驱动程序的修改事项, 目标板的微处理器是 S3C2410X

More information

epub 33-8

epub 33-8 8 1) 2) 3) A S C I I 4 C I / O I / 8.1 8.1.1 1. ANSI C F I L E s t d i o. h typedef struct i n t _ f d ; i n t _ c l e f t ; i n t _ m o d e ; c h a r *_ n e x t ; char *_buff; /* /* /* /* /* 1 5 4 C FILE

More information

Converting image (bmp/jpg) file into binary format

Converting image (bmp/jpg) file into binary format RAiO Image Tool 操作说明 Version 1.0 July 26, 2016 RAiO Technology Inc. Copyright RAiO Technology Inc. 2013 RAiO TECHNOLOGY INC. www.raio.com.tw Revise History Version Date Description 0.1 September 01, 2014

More information

第11章 可调内核参数

第11章 可调内核参数 11 11 Unix BSD 4.4 Linux sysctl Unix Linux /proc window /proc /proc/sys /proc/sys sysctl Unix root /proc/sys/vm root /proc/sys sysctl /proc/sys struct ctl_table 18274 struct ctl_tables /proc/sys struct

More information

audiogram3 Owners Manual

audiogram3 Owners Manual USB AUDIO INTERFACE ZH 2 AUDIOGRAM 3 ( ) * Yamaha USB Yamaha USB ( ) ( ) USB Yamaha (5)-10 1/2 AUDIOGRAM 3 3 MIC / INST (XLR ) (IEC60268 ): 1 2 (+) 3 (-) 2 1 3 Yamaha USB Yamaha Yamaha Steinberg Media

More information

C/C++ 语言 - 循环

C/C++ 语言 - 循环 C/C++ Table of contents 7. 1. 2. while 3. 4. 5. for 6. 8. (do while) 9. 10. (nested loop) 11. 12. 13. 1 // summing.c: # include int main ( void ) { long num ; long sum = 0L; int status ; printf

More information

WinMDI 28

WinMDI 28 WinMDI WinMDI 2 Region Gate Marker Quadrant Excel FACScan IBM-PC MO WinMDI WinMDI IBM-PC Dr. Joseph Trotter the Scripps Research Institute WinMDI HP PC WinMDI WinMDI PC MS WORD, PowerPoint, Excel, LOTUS

More information

How to Debug Tuxedo Server printf( Input data is: %s, inputstr); fprintf(stdout, Input data is %s, inputstr); fprintf(stderr, Input data is %s, inputstr); printf( Return data is: %s, outputstr); tpreturn(tpsuccess,

More information

<4D F736F F D20B5DAC8FDCBC4D5C2D7F7D2B5B4F0B0B82E646F63>

<4D F736F F D20B5DAC8FDCBC4D5C2D7F7D2B5B4F0B0B82E646F63> 第三章 Q3 1 1. 省略了 I/O 操作的复杂逻辑, 易实现, 耗费低 ; 2. 可以利用丰富的内存寻址模式实现灵活的 I/O 操作 Q3 2 假设存储单元 ds1 处寄存器地址为 0x2000, 代码如下 #define ds1 0x2000 while ( *ds1 == 0 ) ; Q3 3 假设设备 (dev1) 中有两个寄存器 ds1 和 dd1,dev1 的地址为 0x1000,ds1

More information

OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料

OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢   学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 Email: 51141201063@ecnu.cn 学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料 OOP with Java Java 类型 引用 不可变类型 对象存储位置 作用域 OOP

More information

<4D F736F F D20B5DA32D5C220416E64726F6964BFAAB7A2BBB7BEB3B4EEBDA82E646F6378>

<4D F736F F D20B5DA32D5C220416E64726F6964BFAAB7A2BBB7BEB3B4EEBDA82E646F6378> Android 应用程序开发与典型案例 作者 : 华清远见 第 2 章 Android 开发环境搭建 本章简介 本章主要介绍在 Windows 环境下,Android 开发环境的搭建步骤及注意事项, 包括 JDK 和 Java 开发环境的安装和配置 Eclipse 的安装 Android SDK 和 ADT 的安装和配置等 ; 同时介绍了 Android 开发的基本步骤 2.1 Android 开发环境的安装与配置

More information

Chapter #

Chapter # 第三章 TCP/IP 协议栈 本章目标 通过本章的学习, 您应该掌握以下内容 : 掌握 TCP/IP 分层模型 掌握 IP 协议原理 理解 OSI 和 TCP/IP 模型的区别和联系 TCP/IP 介绍 主机 主机 Internet TCP/IP 早期的协议族 全球范围 TCP/IP 协议栈 7 6 5 4 3 应用层表示层会话层传输层网络层 应用层 主机到主机层 Internet 层 2 1 数据链路层

More information

Microsoft Word - MSP430 Launchpad 指导书.docx

Microsoft Word - MSP430 Launchpad 指导书.docx Contents 3... 9... 14 MSP430 LAUNCHPAD 指导书 3 第一部分第一个工程 New Project File > New > CCS Project Project name: ButtonLED Device>Family: MSP430 Variant: MSP430G2553 Project templates and examples : Empty Project

More information

untitled

untitled MODBUS 1 MODBUS...1 1...4 1.1...4 1.2...4 1.3...4 1.4... 2...5 2.1...5 2.2...5 3...6 3.1 OPENSERIAL...6 3.2 CLOSESERIAL...8 3.3 RDMULTIBIT...8 3.4 RDMULTIWORD...9 3.5 WRTONEBIT...11 3.6 WRTONEWORD...12

More information

《C语言程序设计》教材习题参考答案

《C语言程序设计》教材习题参考答案 教材名称 : C 语言程序设计 ( 第 1 版 ) 黄保和 江弋编著清华大学出版社 ISBN:978-7-302-13599-9, 红色封面 答案制作时间 :2011 年 2 月 -5 月 一 选择题 1. 设已定义 int a, * p, 下列赋值表达式中正确的是 :C)p=&a 2. 设已定义 int x,*p=&x;, 则下列表达式中错误的是 :B)&*x 3. 若已定义 int a=1,*b=&a;,

More information

Important Notice SUNPLUS TECHNOLOGY CO. reserves the right to change this documentation without prior notice. Information provided by SUNPLUS TECHNOLO

Important Notice SUNPLUS TECHNOLOGY CO. reserves the right to change this documentation without prior notice. Information provided by SUNPLUS TECHNOLO Car DVD New GUI IR Flow User Manual V0.1 Jan 25, 2008 19, Innovation First Road Science Park Hsin-Chu Taiwan 300 R.O.C. Tel: 886-3-578-6005 Fax: 886-3-578-4418 Web: www.sunplus.com Important Notice SUNPLUS

More information

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 odps-sdk 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基 开放数据处理服务 ODPS SDK SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基础功能的主体接口, 搜索关键词 "odpssdk-core" 一些

More information

untitled

untitled 1 5 IBM Intel 1. IBM 第 1/175 页 第 2/175 页 第 3/175 页 80 第 4/175 页 2. IBM 第 5/175 页 3. (1) 第 6/175 页 第 7/175 页 第 8/175 页 = = 第 9/175 页 = = = = = 第 10/175 页 = = = = = = = = 3. (2) 第 11/175 页 第 12/175 页 第 13/175

More information

你的第一本 Photoshop 书 图 1.3 图 1.4 RGB 图 1.5 图 三原色光的概念 R Red G Green B Blue RGB RGB R B 3 1 RGB RGB 256 0~ RGB

你的第一本 Photoshop 书 图 1.3 图 1.4 RGB 图 1.5 图 三原色光的概念 R Red G Green B Blue RGB RGB R B 3 1 RGB RGB 256 0~ RGB 第 1 章色彩基础知识 Photoshop Photoshop 1.1 RGB 色彩模式 1.1 1.2 图 1.1 图 1.2 Photoshop sample0101.png 1.3 > CTRL O Windows Photoshop Photoshop Photoshop F8 > 1.4 B R 你的第一本 Photoshop 书 图 1.3 图 1.4 RGB 1.5 1.6 图 1.5

More information

目 录(目录名)

目  录(目录名) 目录 目录...1-1 1.1 域名解析配置命令... 1-1 1.1.1 display dns domain... 1-1 1.1.2 display dns dynamic-host... 1-1 1.1.3 display dns server... 1-2 1.1.4 display ip host... 1-3 1.1.5 dns domain... 1-4 1.1.6 dns resolve...

More information

C++ 程式設計

C++ 程式設計 C C 料, 數, - 列 串 理 列 main 數串列 什 pointer) 數, 數, 數 數 省 不 不, 數 (1) 數, 不 數 * 料 * 數 int *int_ptr; char *ch_ptr; float *float_ptr; double *double_ptr; 數 (2) int i=3; int *ptr; ptr=&i; 1000 1012 ptr 數, 數 1004

More information

(Load Project) (Save Project) (OffLine Mode) (Help) Intel Hex Motor

(Load Project) (Save Project) (OffLine Mode) (Help) Intel Hex Motor 1 4.1.1.1 (Load) 14 1.1 1 4.1.1.2 (Save) 14 1.1.1 1 4.1.2 (Buffer) 16 1.1.2 1 4.1.3 (Device) 16 1.1.3 1 4.1.3.1 (Select Device) 16 2 4.1.3.2 (Device Info) 16 2.1 2 4.1.3.3 (Adapter) 17 2.1.1 CD-ROM 2 4.1.4

More information

Microsoft Word - 11.doc

Microsoft Word - 11.doc 除 錯 技 巧 您 將 於 本 章 學 到 以 下 各 項 : 如 何 在 Visual C++ 2010 的 除 錯 工 具 控 制 下 執 行 程 式? 如 何 逐 步 地 執 行 程 式 的 敘 述? 如 何 監 看 或 改 變 程 式 中 的 變 數 值? 如 何 監 看 程 式 中 計 算 式 的 值? 何 謂 Call Stack? 何 謂 診 斷 器 (assertion)? 如 何

More information

c_cpp

c_cpp C C++ C C++ C++ (object oriented) C C++.cpp C C++ C C++ : for (int i=0;i

More information

1.01

1.01 2013 操作系统课程设计 内容简介 设计目的 设计内容 实施方法及要求 时间安排 辅导 2 设计目的 掌握 Linux 操作系统的使用方法 ; 了解 Linux 系统内核代码结构 ; 掌握实例操作系统的实现方法 3 内容简介 设计目的 设计内容 实施方法及要求 时间安排 辅导 4 设计内容 (1) 要求 : 熟悉和理解 Linux 编程环境 内容 编写一个 C 程序, 使用 Linux 下的图形库,

More information

ICD ICD ICD ICD ICD

ICD ICD ICD ICD ICD MPLAB ICD2 MPLAB ICD2 PIC MPLAB-IDE V6.0 ICD2 usb PC RS232 MPLAB IDE PC PC 2.0 5.5V LED EEDATA MPLAB ICD2 Microchip MPLAB-IDE v6.0 Windows 95/98 Windows NT Windows 2000 www.elc-mcu.com 1 ICD2...4 1.1 ICD2...4

More information

手册 doc

手册 doc 1. 2. 3. 3.1 3.2 3.3 SD 3.4 3.5 SD 3.6 3.7 4. 4.1 4.2 4.3 SD 4.4 5. 5.1 5.2 5.3 SD 6. 1. 1~3 ( ) 320x240~704x288 66 (2G SD 320x2401FPS ) 32M~2G SD SD SD SD 24V DC 3W( ) -10~70 10~90% 154x44x144mm 2. DVR106

More information

学习MSP430单片机推荐参考书

学习MSP430单片机推荐参考书 MSP430 16 MSP430 C MSP430 C MSP430 FLASH 16 1 CPU 16 ALU 16 PC SP SR R4~R15 2 3 00-FFH 100-1FFH 4 5 1 2 51 24 27 6 1 2 3 4 5 6 4 12 SR SP SR CPU SR CPU C Z N GIE CPUOff CPU OscOff SCG0 SCG1 CPU EXIT SP

More information

中文手册

中文手册 PCC-3428 PC/104 1. PCC-3428 1.1 PCC-3428 90mm 96mm ST CPU STPC Atlas Atlas CPU 486 DX/DX2 CPU DX2 133MHz Atlas 2D LCD/CRT 100MHz SDRAM 64MBytes PCC-3428 10/100Mbps DOC EIDE USB PC/104 ST STPC Atlas STPC

More information

C 1

C 1 C homepage: xpzhangme 2018 5 30 C 1 C min(x, y) double C // min c # include # include double min ( double x, double y); int main ( int argc, char * argv []) { double x, y; if( argc!=

More information

DVK530/531扩展板

DVK530/531扩展板 DVK710 扩展板 驱动移植手册 2014.06.03 V1.0 版权声明 本手册所有权由深圳市微雪电子有限公司独家持有 未经本公司的书 面许可, 不得以任何方式或形式进行修改 分发或复制本文档的任何 部分, 否则一切后果由违者自负 版本更新记录 版本日期说明 V1.0 2014.06.03 初始发布 深圳市微雪电子有限公司 www.waveshare.netii I 目录版权声明... I 版本更新记录...

More information

系统架构 - 模块划分 功能 状态机 H265 主要的模块 : 1. 顶层模块 H265ENC_top 包括 sys_ctrl,enc_core 及 fetch 三个模块 2. sys_ctrl 就是一个状态机, 控制 fetch 和 enc_core 中各子模块的工作 3. enc_core 编码

系统架构 - 模块划分 功能 状态机 H265 主要的模块 : 1. 顶层模块 H265ENC_top 包括 sys_ctrl,enc_core 及 fetch 三个模块 2. sys_ctrl 就是一个状态机, 控制 fetch 和 enc_core 中各子模块的工作 3. enc_core 编码 3.1 系统架构与模块仿真文件 作者 : 江亲炜 日期 :2017/1/8 系统架构 - 模块划分 功能 状态机 H265 主要的模块 : 1. 顶层模块 H265ENC_top 包括 sys_ctrl,enc_core 及 fetch 三个模块 2. sys_ctrl 就是一个状态机, 控制 fetch 和 enc_core 中各子模块的工作 3. enc_core 编码器的核心 4. 存取 cur_pixel

More information

Abstract arm linux tool-chain root NET-Start! 2

Abstract arm linux tool-chain root NET-Start! 2 Lab III - Embedding Linux 1 Abstract arm linux tool-chain root NET-Start! 2 Part 1.4 Step1. tool-chain 4 Step2. PATH 4 Part 2 kernel 5 Step1. 5 Step2... 6 Step3...8 Part 3 root. 8 Step1. 8 Step2. 8 Part

More information

untitled

untitled XP248 1 XP248 XP248 DCS PLC SCnet SCnet DCS SCnet DCS 1.1 XP248 Modbus HostLink Modbus XP248 4 DB25 XP248 MODBUS XP248 SCControl XP248 4 RS232 RS485 4 32 XP248 COM0-COM1 COM2-COM3 1200 19200bit/s 5 8 1

More information

1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un

1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un Linux C July 27, 2016 Contents 1 Linux IDE 1 2 GCC 3 2.1 hello.c hello.exe........................... 5 2.2............................... 9 2.2.1 -Wall................................ 9 2.2.2 -E..................................

More information

无类继承.key

无类继承.key 无类继承 JavaScript 面向对象的根基 周爱 民 / aimingoo aiming@gmail.com https://aimingoo.github.io https://github.com/aimingoo rand = new Person("Rand McKinnon",... https://docs.oracle.com/cd/e19957-01/816-6408-10/object.htm#1193255

More information

嵌入式Linux块设备驱动开发解析

嵌入式Linux块设备驱动开发解析 The success's road 嵌 入 式 LINUX 网 络 驱 动 开 发 Copyright 2007-2008 Farsight. All rights reserved. 要 点 Linux 网 络 设 备 驱 动 程 序 概 述 计 算 机 网 络 概 述 skbuf 数 据 结 构 介 绍 Linux 网 络 设 备 驱 动 程 序 API 介 绍 Linux 网 络 设 备 驱

More information

Microsoft PowerPoint - Chapter7-DriverDevices.ppt

Microsoft PowerPoint - Chapter7-DriverDevices.ppt Chapter 7 Device Drivers and Software Interface Design Professor Ching-Lung Su E-mail: kevinsu@yuntech.edu.tw Http://www.eecs.yuntech.edu.tw NYUST/EL P-2/80 Outline 7.1 Introduction to Device Driver 7.2

More information

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc 2 5 8 11 0 13 1. 13 2. 15 3. 18 1 23 1. 23 2. 26 3. 28 2 36 1. 36 2. 39 3. 42 4. 44 5. 49 6. 51 3 57 1. 57 2. 60 3. 64 4. 66 5. 70 6. 75 7. 83 8. 85 9. 88 10. 98 11. 103 12. 108 13. 112 4 115 1. 115 2.

More information

Microsoft Word - 正文.doc

Microsoft Word - 正文.doc 1 2 1 2 3 4 5 6 7 8 9 10 3 1 150 2 150 1 1 1.1 1.1.1 1.2 1.2.1 1.2.2 1.2.3 1.3 1.3.1 1.3.2 1.4 1.4.1 CPU 1.4.2 I/O 1.4.3 I/O 1.5 1.5.1 CISC RISC 1.5.2 1.5.3 1.6 1.6.1 1.6.2 N 1.6.3 2 2.1 2.1.1 2.1.2 2.1.3

More information

C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40

C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40 C C trio@seu.edu.cn C C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40 Week3 C Week5 Week5 Memory & Pointer

More information

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File 51 C 51 51 C C C C C C * 2003-3-30 pnzwzw@163.com C C C C KEIL uvision2 MCS51 PLM C VC++ 51 KEIL51 KEIL51 KEIL51 KEIL 2K DEMO C KEIL KEIL51 P 1 1 1 1-1 - 1 Project New Project 1 2 Windows 1 3 N C test

More information

Windows 2000 Server for T100

Windows 2000 Server for T100 2 1 Windows 95/98 Windows 2000 3.5 Windows NT Server 4.0 2 Windows DOS 3.5 T200 2002 RAID RAID RAID 5.1 Windows 2000 Server T200 2002 Windows 2000 Server Windows 2000 Server Windows 2000 Server 3.5 for

More information

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d

More information

Measurement Studio Expands Your Test and Measurement Programming Power

Measurement Studio Expands Your Test and Measurement Programming Power NI-DAQmx NI-DAQ NI-DAQmx NI-DAQ NI-DAQmx NI-DAQmx NI-DAQ NI-DAQmx NI-DAQmx LabVIEW LabWindows/CVI ANSI C Measurement Studio Visual Studio I/O 1. I/O API I/O NI NI NI NI ADE 1.NI-DAQmx NI & MAX DAQ Assistant

More information

untitled

untitled 2006 6 Geoframe Geoframe 4.0.3 Geoframe 1.2 1 Project Manager Project Management Create a new project Create a new project ( ) OK storage setting OK (Create charisma project extension) NO OK 2 Edit project

More information

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1 21 , 7, Windows,,,, : 010-62782989 13501256678 13801310933,,,, ;,, ( CIP) /,,. : ;, 2005. 11 ( 21 ) ISBN 7-81082 - 634-4... - : -. TP316-44 CIP ( 2005) 123583 : : : : 100084 : 010-62776969 : 100044 : 010-51686414

More information

科学计算的语言-FORTRAN95

科学计算的语言-FORTRAN95 科 学 计 算 的 语 言 -FORTRAN95 目 录 第 一 篇 闲 话 第 1 章 目 的 是 计 算 第 2 章 FORTRAN95 如 何 描 述 计 算 第 3 章 FORTRAN 的 编 译 系 统 第 二 篇 计 算 的 叙 述 第 4 章 FORTRAN95 语 言 的 形 貌 第 5 章 准 备 数 据 第 6 章 构 造 数 据 第 7 章 声 明 数 据 第 8 章 构 造

More information

全国计算机技术与软件专业技术资格(水平)考试

全国计算机技术与软件专业技术资格(水平)考试 全 国 计 算 机 技 术 与 软 件 专 业 技 术 资 格 ( 水 平 ) 考 试 2008 年 上 半 年 程 序 员 下 午 试 卷 ( 考 试 时 间 14:00~16:30 共 150 分 钟 ) 试 题 一 ( 共 15 分 ) 阅 读 以 下 说 明 和 流 程 图, 填 补 流 程 图 中 的 空 缺 (1)~(9), 将 解 答 填 入 答 题 纸 的 对 应 栏 内 [ 说 明

More information

MATLAB 1

MATLAB 1 MATLAB 1 MATLAB 2 MATLAB PCI-1711 / PCI-1712 MATLAB PCI-1711 / PCI-1712 MATLAB The Mathworks......1 1...........2 2.......3 3................4 4. DAQ...............5 4.1. DAQ......5 4.2. DAQ......6 5.

More information

2/80 2

2/80 2 2/80 2 3/80 3 DSP2400 is a high performance Digital Signal Processor (DSP) designed and developed by author s laboratory. It is designed for multimedia and wireless application. To develop application

More information

51 C 51 isp 10 C PCB C C C C KEIL

51 C 51 isp 10   C   PCB C C C C KEIL http://wwwispdowncom 51 C " + + " 51 AT89S51 In-System-Programming ISP 10 io 244 CPLD ATMEL PIC CPLD/FPGA ARM9 ISP http://wwwispdowncom/showoneproductasp?productid=15 51 C C C C C ispdown http://wwwispdowncom

More information

Microsoft PowerPoint - 4. 数组和字符串Arrays and Strings.ppt [兼容模式]

Microsoft PowerPoint - 4. 数组和字符串Arrays and Strings.ppt [兼容模式] Arrays and Strings 存储同类型的多个元素 Store multi elements of the same type 数组 (array) 存储固定数目的同类型元素 如整型数组存储的是一组整数, 字符数组存储的是一组字符 数组的大小称为数组的尺度 (dimension). 定义格式 : type arrayname[dimension]; 如声明 4 个元素的整型数组 :intarr[4];

More information

bingdian001.com

bingdian001.com TSM12M TSM12 STM8L152C6, STM8L152R8 MSP430F5325 whym1987@126.com! /******************************************************************************* * : TSM12.c * : * : 2013/10/21 * : TSM12, STM8L f(sysclk)

More information

Microsoft Word - PHP7Ch01.docx

Microsoft Word - PHP7Ch01.docx PHP 01 1-6 PHP PHP HTML HTML PHP CSSJavaScript PHP PHP 1-6-1 PHP HTML PHP HTML 1. Notepad++ \ch01\hello.php 01: 02: 03: 04: 05: PHP 06:

More information

穨control.PDF

穨control.PDF TCP congestion control yhmiu Outline Congestion control algorithms Purpose of RFC2581 Purpose of RFC2582 TCP SS-DR 1998 TCP Extensions RFC1072 1988 SACK RFC2018 1996 FACK 1996 Rate-Halving 1997 OldTahoe

More information

Guide to Install SATA Hard Disks

Guide to Install SATA Hard Disks SATA RAID 1. SATA. 2 1.1 SATA. 2 1.2 SATA 2 2. RAID (RAID 0 / RAID 1 / JBOD).. 4 2.1 RAID. 4 2.2 RAID 5 2.3 RAID 0 6 2.4 RAID 1.. 10 2.5 JBOD.. 16 3. Windows 2000 / Windows XP 20 1. SATA 1.1 SATA Serial

More information

1 CPU

1 CPU 2000 Tel 82316285 82317634 Mail liuxd@buaa.edu.cn 1 CPU 2 CPU 7 72 A B 85 15 3 1/2 M301 2~17 : 3/4 1/2 323 IBM PC 1. 2. 3. 1. 2. 3. 1.1 Hardware Software 1.2 M3 M2 M1 1.2 M3 M1 M2 M2 M1 M1 M1 1.2 M3 M1

More information

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 Java V1.0.1 2007 4 10 1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 6.2.10 6.3..10 6.4 11 7.12 7.1

More information

Ioncube Php Encoder 8 3 Crack 4. llamaba octobre traslado General Search colony

Ioncube Php Encoder 8 3 Crack 4. llamaba octobre traslado General Search colony Ioncube Php Encoder 8 3 Crack 4 ->>->>->> DOWNLOAD 1 / 5 2 / 5 Press..the..General..Tools..category4Encrypt..and..protect..files..with..PHP..encoding,..encryption,..ob fuscation..and..licensing... 2016

More information

BOOL EnumWindows(WNDENUMPROC lparam); lpenumfunc, LPARAM (Native Interface) PowerBuilder PowerBuilder PBNI 2

BOOL EnumWindows(WNDENUMPROC lparam); lpenumfunc, LPARAM (Native Interface) PowerBuilder PowerBuilder PBNI 2 PowerBuilder 9 PowerBuilder Native Interface(PBNI) PowerBuilder 9 PowerBuilder C++ Java PowerBuilder 9 PBNI PowerBuilder Java C++ PowerBuilder NVO / PowerBuilder C/C++ PowerBuilder 9.0 PowerBuilder Native

More information