本文内容由浅入深主要介绍了JZ2440的LED裸板程序,LED的简单驱动程序 一、LED裸板程序 arm 开发板的裸板程序和51 单片机类似,需要通过配置寄存器来实现。s3c2440 有130 个I/O 口,共分为A-J 共9 组。 1.硬件原理图: JZ2440的硬件连接图,如下图所示: 从图中可以看出LED1、LED2、LED3、LED4这四个LED灯分别于GPB5-GPB8相连,因此需要通过控制GPB5-GPB8的寄存器的输出来控制,LED等的亮灭。 2.寄存器的配置 s3c2440的I/O口可以用于输入、输出或是其他特殊功能,因此需要有寄存器来对引脚的功能进行配置。GPB引脚的位置及配置可以从s3c2440手册上查到,如下图所示: 由上图可以看出对GPB引脚进行设置的有4个寄存器,其中包括一个保留的,即有三个寄存器来对GPB引脚进行设置。 这三个寄存器的功能如下: GPBCON:主要用于配置,选择引脚的功能。GPBDAT:用于读写引脚,当引脚被设为输入时,读此寄存器可知相应引脚的电平状态是高还是低;当引脚被设为输出时,写此寄存器相应位可令此引脚输出高电平或低电平。GPBUP寄存器:某位为1时,相应引脚无内部上拉电阻;为0时,相应引脚使用内不上拉电阻。 3、代码分析 点亮LED的C语言代码很简单,如下所示: /* 定义GPBCON 的地址,其中的vola tile 主要是为了防止编译器在编译时对代码进行优化,从而产生错误*/ #define GPBCON (*(volatile unsigned long*)0x56000010) #define GPBDAT (*(volatile unsigned long*)0x56000014) int main() { GPBCON=0x00015400;//设置GPB5-GPB8位输出端口 GPBDAT=0x00000000;//GPB5-GPB8输出0,LED1-4点亮 } 二、LED驱动程序1.驱动简介 一个软件系统可以分为:应用程序、库、操作系统、驱动程序四部分,其架构图如下所示: 首先应用程序使用库提供的open函数打开代表LED的设备文件;库根据open函数传入的参数执行swi指令,该指令引起系统调用;内核的异常处理函数根据这些参数找到对应的驱动程序,返回文件的句柄;应用程序得到文件句柄后,使用库提供的write或ioctl函数发出控制命令;库根据write或ioctl函数传入的参数执行swi指令,这条指令会引起CPU异常,进入内核;内核的异常处理函数根据这些参数调用驱动程序的相关函数,点亮LED。 Linux的外设可以分为3类:字符设备、块设备和网络设备。字符设备是能够像字节流一样被访问的设备,对设备的读写是以字节为单位的。块设备的数据是以块的形式存放的,如硬盘、U盘等。 2.源码分析 #define LED_MATOR0 Static unsignedlong led_table[]={ S3C2410_GPB(5), S3C2410_GPB(6), S3C2410_GPB(7), S3C2410_GPB(8), }; staticint s3c2440_leds_open(struct inode *inode,struct file *file) { int i; for(i=0;i<4;i++) { S3c2410_gpio_cfgpin(led_table, S3C2410_GPIO_OUTPUT);//配置引脚为输出 } return 0; } staticint s3c2440_leds_ioctl(struct inode *inode,struct file *file,unsigned intcmd,unsigned long arg){ if(arg>4) return –EINVAL; switch(cmd){ case IOCTL_LED_ON: s3c2410_gpio_setpin(led_table[arg],0);//设置引脚输出电平为0 return 0; case IOCTL_LED_OFF: s3c2410_gpio_setpin(led_table[arg],1); //设置引脚输出电平为1 return 0; defaule: return –EINVAL; } } /*驱动的操作函数集*/ static structfile_operations s3c2440_leds_fops={ .owner=THIS_MODULE, .open=s3c2440_leds_open, .ioctl=s3c2440_leds_ioctl, }; staticint s3c2440_leds_init(void) { int ret; ret=register_chrdev(LED_MATOR,”leds”,&s3c2440_leds_fops);//向内核注册驱动函数 if(ret<0) return ret; return 0; } Staticvoid s3c2440_leds_exit(void) { Unregister_chrdev(LED_MATOR, ”leds”);//卸载驱动的函数 } module_init(s3c2440_leds_init);//指定驱动程序的初始化函数 module_exit(s3c2440_leds_exit);//指定驱动程序的卸载函数
|