基于mini2440的mp3播放器毕业设计(编辑修改稿)内容摘要:

LINUX 系统移植及按键驱动开发 Linux 系统移植 获取 Linux 内核源代码 从 linux 官方网站下载 Linux 内核代码。 指定交叉编译变量 我们移植目的是让 可以在 mini2440 上运行。 修改总目录下面的 Makefile,改为: export KBUILD_BUILDHOST :=$(SUBARCH) ARCH ?= arm CROSS_COMPILE ?= armlinux 其中, ARCH 是指定目标平台为 arm, CROSS_COMPILE 是指定交叉编译器,这里指定的是系统默认的交叉编译器。 内核配置菜单中的 MINI2440 选项 输入命令 make menuconfig 出现内核配置菜单如图 41: 第四章 LINUX 系统移植及按键驱动开发 10 图 41 按上下键移动到 System Type,按回车进入该子菜单,如图 42: 图 42 南京工业大学本科生毕业设计(论文) 11 再找到 S3C2440 Machines,按回车进入该子菜单,选择 mini2440 development 即可。 为内核打上 yaffs2 补丁 进入 yaffs2 目录执行: cd yaffs2 ./ /opt/FriendlyARM/mini2440/ Yaffs2 补丁成功打上。 配置和编译带 YAFFS2支持的内核 在 lunux 内核源代码根目录运行: make menuconfig,移动上下键找到 File System,如图 43,按回车进入该子菜单 图 43 第四章 LINUX 系统移植及按键驱动开发 12 再找到“ Miscellaneous filesystem”菜单栏,按回车进入该子菜单,如图 44: 图 44 出现如图 45,找到“ YAFFS2 file system support”,并按空格选中它,这样我们就在内核中添加了 YAFFS2 文件系统的支持。 南京工业大学本科生毕业设计(论文) 13 图 45 在命令行输入 make zImage 按键驱动开发 按键驱动原理 Mini2440 具有 6 个用户测试用按键,它们都是连接到 CPU的中断引脚。 6个用户按键分 别对应如下表 41: 表 41 按键 对应的端口寄存器 对应的中断 对应的复用功能 K1 GPG0 EINT8 仅有 GPIO 和中断功能 K2 GPG3 EINT11 nSS1 K3 GPG5 EINT13 SPISIMO K4 GPG6 EINT14 SPISIMI K5 GPG7 EINT15 SPICLK K6 GPG11 EINT19 TCLK 第四章 LINUX 系统移植及按键驱动开发 14 按键驱动设计思路 ( 1)整体思路 按键的捕获, Mini2440 是用的中断方式,所以要对每个按键进行结构体定义,然后使用中断服务 程序对中断进行捕获。 ( 2) 中断模式 Mini2440 一共有 7 种工作模式,中断模式是其中一种,是特权模式,也是异常模式。 中断的控制寄存器比较多,其实总开关就在 CPSR 种的 I位和 F 位,一个是中断允许,一个是快中断允许。 当一个异常模式发生时候(这里关心中断模式), ARM core 会自动地完成许多事情: LR 寄存器种保存上一个模式的的下一条,即将执行的指令的地址 CPSR 值复制到异常模式的 SPSR CPSR 设置为异常模式的数值 PC的数值等于异常模式在异常向量表中的地址,即跳转执行 异常向量表中的指令 当退出异常模式的时候,由软件完成下列事情: LR的数值减去适当的数值,赋给 PC寄存器 SPSR 复制给 CPSR 使用中断的步骤如下: ,并且要中断核心的程序 ISR,最后清除中断 ,出中断需要保存运行环境 ,设置外设 , FIQ 还是 IRQ ,设置 INTMSK 寄存器, FIQ 不受 INTMSK 影响 CPSR 中的总中断位 IF 位 南京工业大学本科生毕业设计(论文) 15 ( 3) 驱动 程序的分析和编写 按键是利用中断的方式进行操作的,所以要定义一个结构体来存放按键的中断号, GPIO 端口,定义键值,用来传递给应用层让客户可以在写程序时候用到,实际代码如下: struct button_irq_desc { int irq。 //按键对应的中断号 int pin。 //按键所对应的 GPIO 端口 int pin_setting。 //按键对应的引脚描述,实际并未用到,保留 int number。 //定义键值,以传递给应用层 /用户态 char *name。 //每个按键的名称 }。 /*结构体实体定义 */ static struct button_irq_desc button_irqs [] = { {IRQ_EINT8 , S3C2410_GPG(0) , S3C2410_GPG0_EINT8 , 0, KEY0}, {IRQ_EINT11, S3C2410_GPG(3) , S3C2410_GPG3_EINT11 , 1, KEY1}, {IRQ_EINT13, S3C2410_GPG(5) , S3C2410_GPG5_EINT13 , 2, KEY2}, {IRQ_EINT14, S3C2410_GPG(6) , S3C2410_GPG6_EINT14 , 3, KEY3}, }。 因为本驱动是基于中断方式的,所以要创建一个等待队列,以配合中断函数使用;当有按键按下并读取到键值时,将会唤醒此队列,并设置中断标志,以便能通过 read 函数判断和读取键值传递到用户态;当没有按键按下时,系统并不会轮询按键状态,以节省时钟资源。 具体实现代码如下: static DECLARE_WAIT_QUEUE_HEAD(button_waitq)。 /*中断标识变量,配合上面的队列使用,中断服务程序会把它设置为 1, read 函数会把它清零 */ static volatile int ev_press = 0。 static irqreturn_t buttons_interrupt(int irq, void *dev_id) { struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id。 int down。 udelay(0)。 第四章 LINUX 系统移植及 按键驱动开发 16 down = !s3c2410_gpio_getpin(button_irqspin)。 if (down != (key_values[button_irqsnumber] amp。 1)) { // Changed key_values[button_irqsnumber] = 39。 039。 + down。 ev_press = 1。 wake_up_interruptible(amp。 button_waitq)。 } return IRQ_RETVAL(IRQ_HANDLED)。 } 在应用程序执行 open(“ /dev/buttons” ,„ )时会调用到此函数,在这里,它的作用主要是注册按键的中断。 所用的中断类型是 IRQ_TYPE_EDGE_BOTH,也就是双沿触发,在上升沿和下降沿均会产生中断,这样做是为了更加有效地判断按键状态具体实现代码如下: static int s3c24xx_buttons_open(struct inode *inode, struct file *file) { int i。 int err = 0。 for (i = 0。 i sizeof(button_irqs)/sizeof(button_irqs[0])。 i++) { if (button_irqs[i].irq 0) { continue。 } err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH, button_irqs[i].name, (void *)amp。 button_irqs[i])。 if (err) break。 if (err) { i。 for (。 i = 0。 i) { if (button_irqs[i].irq 0) { continue。 } disable_irq(button_irqs[i].irq)。 free_irq(button_irqs[i].irq, (void *)amp。 button_irqs[i])。 return EBUSY。 ev_press = 1。 return 0。 南京工业大学本科生毕业设计(论文) 17 下面这段 close(fd)函数对应用程序的系统调用,在此,它的主要作用是当关闭设备时释放按键的中断: static int s3c24xx_buttons_close(struct inode *inode, struct file *file) { int i。 for (i = 0。 i sizeof(button_irqs)/sizeof(button_irqs[0])。 i++) { if (button_irqs[i].irq 0) { continue。 } free_irq(button_irqs[i].irq, (void *)amp。 button_irqs[i])。 return 0。 通过下面这段函数实现对按键的读取,以及返回给用户空间,是用户空间可以对按键进行使用: static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp) { unsigned long err。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。