# include  <stdlib.h> # include  <stdio.h> # include  <sys/types.h> # include  <sys/stat.h> # include  <fcntl.h> # include  <unistd.h> # include  <string.h> # include  <sys/ioctl.h> # include  "head.h" void  LED_control ( ) 
{ 
    int  a,  num,  fd; 
    while  ( 1 ) 
    { 
        printf ( "请输入操作的设备文件:0(LED1) 1(LED2) 2(LED3) 其他字符(重新选择设备文件)>>>" ) ; 
        scanf ( "%d" ,  & num) ; 
        switch  ( num) 
        { 
        case  0 : 
            fd =  open ( "/dev/myled0" ,  O_RDWR) ; 
            break ; 
        case  1 : 
            fd =  open ( "/dev/myled1" ,  O_RDWR) ; 
            break ; 
        case  2 : 
            fd =  open ( "/dev/myled2" ,  O_RDWR) ; 
            break ; 
        default : 
            printf ( "输入有误,请重新输入!\n" ) ; 
            break ; 
        } 
        if  ( ! ( num ==  0  ||  num ==  1  ||  num ==  2 ) ) 
        { 
            continue ; 
        } 
        if  ( fd <  0 ) 
        { 
            printf ( "打开led设备文件失败\n" ) ; 
            exit ( - 1 ) ; 
        } 
        while  ( 1 ) 
        { 
            
            printf ( "请选择要实现的功能\n" ) ; 
            printf ( "0(关灯) 1(开灯) 2(重新选择开关灯功能) 其他字符(重新选择设备文件)>>>" ) ; 
            scanf ( "%d" ,  & a) ; 
            if  ( a ==  1 )  
            { 
                ioctl ( fd,  LED_ON,  & num) ; 
            } 
            else  if  ( a ==  0 )  
            { 
                ioctl ( fd,  LED_OFF,  & num) ; 
            } 
            else  if  ( a ==  2 ) 
            { 
                continue ; 
            } 
            else 
                break ; 
        } 
        close ( fd) ; 
    } 
} 
int  main ( int  argc,  char  const  * argv[ ] ) 
{ 
    LED_control ( ) ; 
    return  0 ; 
} 
# include  <linux/init.h> # include  <linux/module.h> # include  <linux/cdev.h> # include  <linux/fs.h> # include  <linux/io.h> # include  <linux/device.h> # include  <linux/slab.h> # include  "head.h" struct  cdev  * cdev; 
unsigned  int  major =  500 ; 
unsigned  int  minor =  0 ;  
dev_t  devno; 
struct  class  * cls; 
struct  device  * dev; 
gpio_t  * vir_led1; 
gpio_t  * vir_led2; 
gpio_t  * vir_led3; 
unsigned  int  * vir_rcc; 
int  mycdev_open ( struct  inode  * inode,  struct  file  * file) 
{ 
    unsigned  int  aaa= MINOR ( inode-> i_rdev) ; 
    file-> private_data= ( void  * ) aaa; 
    printk ( "%s:%s:%d\n" ,  __FILE__ ,  __func__ ,  __LINE__ ) ; 
    return  0 ; 
} 
long  mycdev_ioctl ( struct  file  * file,  unsigned  int  cmd,  unsigned  long  arg) 
{ 
    unsigned  int  aaa= ( int ) file-> private_data; 
   switch ( aaa) 
   { 
       case  0 : 
           
            switch ( cmd) 
            { 
                case  LED_ON: 
                    vir_led1-> ODR |=  ( 0x1  <<  10 ) ; 
                    break ; 
                case  LED_OFF: 
                    vir_led1-> ODR &=  ( ~ ( 0X1  <<  10 ) ) ; 
                    break ; 
            } 
           break ;    
        case  1 : 
           
           switch ( cmd) 
            { 
                case  LED_ON: 
                    vir_led2-> ODR |=  ( 0x1  <<  10 ) ; 
                    break ; 
                case  LED_OFF: 
                    vir_led2-> ODR &=  ( ~ ( 0X1  <<  10 ) ) ; 
                    break ; 
            } 
           break ;  
        case  2 : 
           
           switch ( cmd) 
            { 
                case  LED_ON: 
                    vir_led3-> ODR |=  ( 0x1  <<  8 ) ; 
                    break ; 
                case  LED_OFF: 
                    vir_led3-> ODR &=  ( ~ ( 0X1  <<  8 ) ) ; 
                    break ; 
            } 
           break ;  
   } 
    return  0 ; 
} 
int  all_led_init ( void ) 
{ 
    
    vir_led1 =  ioremap ( PHY_LED1_ADDR,  sizeof ( gpio_t ) ) ; 
    if  ( vir_led1 ==  NULL ) 
    { 
        printk ( "ioremap filed:%d\n" ,  __LINE__ ) ; 
        return  - ENOMEM; 
    } 
    vir_led2 =  ioremap ( PHY_LED2_ADDR,  sizeof ( gpio_t ) ) ; 
    if  ( vir_led2 ==  NULL ) 
    { 
        printk ( "ioremap filed:%d\n" ,  __LINE__ ) ; 
        return  - ENOMEM; 
    } 
    vir_led3 =  vir_led1; 
    vir_rcc =  ioremap ( PHY_RCC_ADDR,  4 ) ; 
    if  ( vir_rcc ==  NULL ) 
    { 
        printk ( "ioremap filed:%d\n" ,  __LINE__ ) ; 
        return  - ENOMEM; 
    } 
    printk ( "物理地址映射成功\n" ) ; 
    
    
    ( * vir_rcc)  |=  ( 3  <<  4 ) ; 
    
    vir_led1-> MODER &=  ( ~ ( 3  <<  20 ) ) ; 
    vir_led1-> MODER |=  ( 1  <<  20 ) ; 
    vir_led1-> ODR &=  ( ~ ( 1  <<  10 ) ) ; 
    
    vir_led2-> MODER &=  ( ~ ( 3  <<  20 ) ) ; 
    vir_led2-> MODER |=  ( 1  <<  20 ) ; 
    vir_led2-> ODR &=  ( ~ ( 1  <<  10 ) ) ; 
    
    vir_led3-> MODER &=  ( ~ ( 3  <<  16 ) ) ; 
    vir_led1-> MODER |=  ( 1  <<  16 ) ; 
    vir_led1-> ODR &=  ( ~ ( 1  <<  8 ) ) ; 
    printk ( "寄存器初始化成功\n" ) ; 
 
    return  0 ; 
} 
int  mycdev_close ( struct  inode  * inode,  struct  file  * file) 
{ 
    printk ( "%s:%s:%d\n" ,  __FILE__ ,  __func__ ,  __LINE__ ) ; 
    return  0 ; 
} 
struct  file_operations  fops = 
    { 
        . open =  mycdev_open, 
        . unlocked_ioctl =  mycdev_ioctl, 
        . release =  mycdev_close, 
} ; 
static  int  __init mycdev_init ( void ) 
{ 
    int  ret,  i; 
    
    cdev =  cdev_alloc ( ) ; 
    if  ( cdev ==  NULL ) 
    { 
        printk ( "分配字符设备驱动对象失败\n" ) ; 
        ret =  - EFAULT; 
        goto  OUT1; 
    } 
    printk ( "字符设备驱动对象申请成功\n" ) ; 
    
    cdev_init ( cdev,  & fops) ; 
    
    if  ( major >  0 )  
    { 
        ret =  register_chrdev_region ( MKDEV ( major,  minor) ,  3 ,  "myled" ) ; 
        if  ( ret) 
        { 
            printk ( "静态指定设备号失败\n" ) ; 
            goto  out2; 
        } 
    } 
    else  
    { 
        ret =  alloc_chrdev_region ( & devno,  minor,  3 ,  "myled" ) ; 
        if  ( ret) 
        { 
            printk ( "动态申请设备号失败\n" ) ; 
            goto  out2; 
        } 
        major =  MAJOR ( devno) ;  
        minor =  MINOR ( devno) ;  
    } 
    printk ( "申请设备号成功\n" ) ; 
    
    ret =  cdev_add ( cdev,  MKDEV ( major,  minor) ,  3 ) ; 
    if  ( ret) 
    { 
        printk ( "注册字符设备驱动对象失败\n" ) ; 
        goto  out3; 
    } 
    printk ( "注册字符设备驱动对象成功\n" ) ; 
    
    cls =  class_create ( THIS_MODULE,  "myled" ) ; 
    if  ( IS_ERR ( cls) ) 
    { 
        printk ( "向上提交目录失败\n" ) ; 
        ret =  - PTR_ERR ( cls) ; 
        goto  out4; 
    } 
    printk ( "向上提交目录成功\n" ) ; 
    
    for  ( i =  0 ;  i <  3 ;  i++ ) 
    { 
        dev =  device_create ( cls,  NULL ,  MKDEV ( major,  i) ,  NULL ,  "myled%d" ,  i) ; 
        if  ( IS_ERR ( dev) ) 
        { 
            printk ( "向上提交节点信息失败\n" ) ; 
            ret =  - PTR_ERR ( dev) ; 
            goto  out5; 
        } 
    } 
    printk ( "向上提交设备节点信息成功\n" ) ; 
    all_led_init ( ) ; 
    return  0 ; 
out5: 
    for  ( -- i;  i >=  0 ;  i-- ) 
    { 
        
        device_destroy ( cls,  MKDEV ( major,  i) ) ; 
    } 
    class_destroy ( cls) ; 
out4: 
    cdev_del ( cdev) ; 
out3: 
    unregister_chrdev_region ( MKDEV ( major,  minor) ,  3 ) ; 
out2: 
    kfree ( cdev) ; 
OUT1: 
    return  ret; 
} 
static  void  __exit mycdev_exit ( void ) 
{ 
    
    int  i; 
    for  ( i =  0 ;  i <  3 ;  i++ ) 
    { 
        device_destroy ( cls,  MKDEV ( major,  i) ) ; 
    } 
    
    class_destroy ( cls) ; 
    
    cdev_del ( cdev) ; 
    
    unregister_chrdev_region ( MKDEV ( major,  minor) ,  3 ) ; 
    
    kfree ( cdev) ; 
} 
module_init ( mycdev_init) ; 
module_exit ( mycdev_exit) ; 
MODULE_LICENSE ( "GPL" ) ; 
# ifndef  __HEAD_H__ # define  __HEAD_H__  typedef  struct { 
    volatile  unsigned  int  MODER;    
	volatile  unsigned  int  OTYPER;   
	volatile  unsigned  int  OSPEEDR;  
	volatile  unsigned  int  PUPDR;    
	volatile  unsigned  int  IDR;      
	volatile  unsigned  int  ODR;      
	volatile  unsigned  int  BSRR;     
	volatile  unsigned  int  LCKR;     
	volatile  unsigned  int  AFRL;     
	volatile  unsigned  int  AFRH;     
	volatile  unsigned  int  BRR;      
	volatile  unsigned  int  res; 
	volatile  unsigned  int  SECCFGR;  
} gpio_t ; 
# define  PHY_LED1_ADDR  0X50006000 # define  PHY_LED2_ADDR     0X50007000 # define  PHY_LED3_ADDR  0X50006000 # define  PHY_RCC_ADDR     0X50000A28 # define  GPIOB  0X50003000 # define  GPIOE  0X50006000 # define  GPIOF  0X50007000 # define  LED_ON  _IOW ( 'l' , 1 , int )   # define  LED_OFF  _IOW ( 'l' , 0 , int ) # endif