现在的位置: 首页 > 综合 > 正文

LED&KEYPAD驱动程序编写实验

2013年03月03日 ⁄ 综合 ⁄ 共 2733字 ⁄ 字号 评论关闭
 

LED&KEYPAD驱动程序编写实验
实验目的:
1.      了解驱动程序结构,熟悉编写驱动程序的基本流程;
2.      实现LED和KEYPAD的驱动程序,要求实现基本的接口函数。
实验原理:
1.      驱动程序是一组代码,这部分代码负责将应用程序的一些需求,如读、写等操作,正确无误的传递给相关的硬件,并使硬件能够做出正确反应的代码。驱动程序像是一个黑盒子,它隐藏了硬件的工作细节,应用程序只需要通过一组标准化的接口,就可以实现对硬件的操作;
2.      编写驱动程序应从了解相应设备的硬件原理开始,进而了解并实现内核模块的注册和撤销、虚拟文件接口函数及其结构体。最后,编写测试程序对已实现的驱动程序进行测试。
实验内容:
从硬件原理上来看,KEYPAD以及LED是连接在系统数据总线上。要实现对LED的或者KEYPAD的控制,只需要打开相应的LED或者KEYPAD的片选信号,进行相关的读写操作就可以了。
  1. 驱动编写
l        虚拟文件系统与硬件驱动的接口
LED和KEYPAD都是字符型设备,所以可直接使用file_operations接口;这里定义LED_KEYPAD设备接口函数,
static struct file_ooperations LedKeypad_fops = {
                     open:LedKeypad_open,
                     read: LedKeypad _read,
                     write: LedKeypad _write,
                     release: LedKeypad _release,
              };
l        向内核注册和撤销LED_KEYPAD设备
static int __init ledkeypad_init(void)//注册设备
{
     int result;
     result = register_chrdev(LEDKEYPAD_MAJOR, "ledkeypad", &LedKeypad_fops);
     printk("%s %s initialized./n",LEDKEYPAD_NAME, LEDKEYPAD_VERSION);
     led_off_on();
 return 0;
}
                   module_init(ledkeypad_init);
                   static void __exit ledkeypad_exit(void)//撤销设备
     unregister_chrdev( LEDKEYPAD_MAJOR, "ledkeypad" );           
     led_off_on();
}
module_exit( ledkeypad_exit );
l        定义设备接口函数                  
int LedKeypad_open (struct inode *inode, struct file *filp)//打开设备
{
     MOD_INC_USE_COUNT
     return 0; 
}
int LedKeypad_release(struct inode *inode, struct file *filp)//释放设备
{
     led_off_on()
     MOD_DEC_USE_COUNT
     return (0)
}
ssize_t LedKeypad _read(struct file *filp, char *Putbuf, size_t length, loff_t *f_pos)//读keypad
{
     unsigned short BottonStatus;
            unsigned char Bottontmp = 0;
     int i;
 
     BottonStatus = ( EXT_KEY_CS & 0xff );
 
     for(i = 0 ; i < 8; ++i)
     {
              if( ((BottonStatus >> i) & 1) == 0 )
                       Bottontmp = (i+1);
     }
 
     copy_to_user( Putbuf, &Bottontmp, length);//复制到用户数据区
    
     return length;
}
ssize_t LedKeypad _write(struct file *filp, const char *Getbuf, size_t length, loff_t *f_pos)//写LED
{
     int num;
     unsigned char UsrWantLed;
      
 copy_from_user( &UsrWantLed, Getbuf, length);//从用户数据区复制数据        
    
     num = ( (UsrWantLed) & 0xff );
 
     EXT_LED_CS = ~(1 << (num-1));
 
     return (0);  
}
l        测试驱动程序
    测试程序通过open( dev_name , O_RDWR )打开设备文件,dev_name是指字符串指针,它代表了所要打开的设备文件名,O_RDWR代表了设备文件的打开方式,整个open操作使得/dev目录下的设备文件keypad以可读写的方式打开。Open函数的返回值是一个代表刚被打开的设备文件的整数(例子中以fd来表示)。然后程序进入一循环状态,不断轮询PXA255GPIO端口,看是否有键按下,当有键按下,控制相应的GPIO管脚,去点亮LED灯。
 int main()
 {
 while(1)    
 {
            do
            {
                     pre_data = data;
                     read( fd, (char * )&data, sizeof(data) );
                     data = (data & 0xff);
            }while(data == 0);
 
            if( pre_data == 0)
            {
                     printf("Write %d LED/n",data);
                     write( fd, (const char *)&data, sizeof((const char )data) );
            }              
 }
 return 0;
 }
 

 

抱歉!评论已关闭.