# ifndef  __HEAD_H__ # define  __HEAD_H__ # define  PHY_LED1_MODER  0X50006000 # define  PHY_LED1_ODR  0X50006014 # define  PHY_LED2_MODER  0X50007000 # define  PHY_LED2_ODR  0X50007014 # define  PHY_LED3_MODER  0X50006000 # define  PHY_LED3_ODR  0X50006014 # define  PHY_RCC  0X50000A28 # endif # include  <stdio.h> # include  <stdlib.h> # include  <sys/types.h> # include  <sys/stat.h> # include  <fcntl.h> # include  <unistd.h> # include  <string.h> int  main ( int  argc,  char  const  * argv[ ] ) 
{ 
    char  buf[ 128 ]  =  { 0 } ; 
    int  fd =  open ( "/dev/mychrdev" , O_RDWR) ; 
    if ( fd <  0 ) 
    { 
        printf ( "打开设备文件失败\n" ) ; 
        exit ( - 1 ) ; 
    } 
    while ( 1 ) 
    { 
        printf ( "请输入控制命令--11:LED1开灯  10:LED1关灯\n21:LED2开灯  20:LED2关灯\n31:LED3开灯  30:LED3关灯>>>" ) ; 
        fgets ( buf, sizeof ( buf) , stdin ) ;            
        buf[ strlen ( buf) - 1 ]  =  '\0' ; 
        write ( fd, buf, sizeof ( buf) ) ; 
    } 
    close ( fd) ; 
    return  0 ; 
} 
# include  <linux/init.h> # include  <linux/module.h> # include  <linux/fs.h> # include  <linux/uaccess.h> # include  <linux/io.h> # include  "head.h" int  major;       
char  kbuf[ 128 ]  =  { 0 } ; 
unsigned  int  * vir_led1_moder; 
unsigned  int  * vir_led1_odr; 
unsigned  int  * vir_led2_moder; 
unsigned  int  * vir_led2_odr; 
unsigned  int  * vir_led3_moder; 
unsigned  int  * vir_led3_odr; 
unsigned  int  * vir_rcc; 
int  mycdev_open ( struct  inode  * inode, struct  file  * file) 
{ 
    printk ( "%s:%s:%d\n" , __FILE__ , __func__ , __LINE__ ) ; 
    return  0 ; 
} 
ssize_t  mycdev_read ( struct  file  * file, char  * ubuf, size_t  size, loff_t  * lof) 
{ 
    int  ret; 
    if ( sizeof ( kbuf)  <  size) 
        size =  sizeof ( kbuf) ; 
    ret =  copy_to_user ( ubuf, kbuf, size) ; 
    if ( ret) 
    { 
        printk ( "copy to user filed\n" ) ; 
        return  - EIO; 
    } 
    printk ( "%s:%s:%d\n" , __FILE__ , __func__ , __LINE__ ) ; 
    return  0 ; 
} 
ssize_t  mycdev_write ( struct  file  * file, const  char  * ubuf, size_t  size, loff_t  * lof) 
{ 
    int  ret; 
    if ( sizeof ( kbuf)  <  size) 
        size =  sizeof ( kbuf) ; 
    ret =  copy_from_user ( kbuf, ubuf, size) ; 
    if ( ret) 
    { 
        printk ( "copy from user filed\n" ) ; 
        return  - EIO; 
    } 
    
    if ( kbuf[ 0 ] == '1'  &&  kbuf[ 1 ] == '1' ) 
    { 
        ( * vir_led1_odr)  |=  ( 0x1  <<  10 ) ; 
    } 
    
    else  if ( kbuf[ 0 ] == '1'   &&  kbuf[ 1 ] == '0' )  
    { 
        ( * vir_led1_odr)  &=  ( ~ ( 0x1  <<  10 ) ) ; 
    } 
     
    if ( kbuf[ 0 ] == '2'   &&  kbuf[ 1 ] == '1' ) 
    { 
        ( * vir_led2_odr)  |=  ( 0x1  <<  10 ) ; 
    } 
    
    else  if ( kbuf[ 0 ] == '2'   &&  kbuf[ 1 ] == '0' ) 
    { 
        ( * vir_led2_odr)  &=  ( ~ ( 0x1  <<  10 ) ) ; 
    } 
     
    if ( kbuf[ 0 ] == '3'   &&  kbuf[ 1 ] == '1' ) 
    { 
        ( * vir_led3_odr)  |=  ( 0x1  <<  8 ) ; 
    } 
    
    else  if ( kbuf[ 0 ] == '3'   &&  kbuf[ 1 ] == '0' ) 
    { 
        ( * vir_led3_odr)  &=  ( ~ ( 0x1  <<  8 ) ) ; 
    } 
    printk ( "%s:%s:%d\n" , __FILE__ , __func__ , __LINE__ ) ; 
    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, 
    . read =  mycdev_read, 
    . write =  mycdev_write, 
    . release =  mycdev_close, 
} ; 
static  int  __init mycdev_init ( void ) 
{ 
    
    major =  register_chrdev ( 0 , "mychrdev" , & fops) ; 
    if  ( major <  0 ) 
    { 
        printk ( "字符驱动设备注册失败\n" ) ; 
        return  major; 
    } 
    printk ( "字符驱动注册成功major = %d\n" , major) ; 
    
    vir_led1_moder =  ioremap ( PHY_LED1_MODER, 4 ) ; 
    if ( vir_led1_moder== NULL ) 
    { 
        printk ( "MODER寄存器地址映射失败\n" ) ; 
        return  - EFAULT; 
    } 
    vir_led1_odr =  ioremap ( PHY_LED1_ODR, 4 ) ; 
    if ( vir_led1_odr== NULL ) 
    { 
        printk ( "ODR寄存器地址映射失败\n" ) ; 
        return  - EFAULT; 
    } 
    vir_led2_moder =  ioremap ( PHY_LED2_MODER, 4 ) ; 
    if ( vir_led2_moder== NULL ) 
    { 
        printk ( "MODER寄存器地址映射失败\n" ) ; 
        return  - EFAULT; 
    } 
    vir_led2_odr =  ioremap ( PHY_LED2_ODR, 4 ) ; 
    if ( vir_led2_odr== NULL ) 
    { 
        printk ( "ODR寄存器地址映射失败\n" ) ; 
        return  - EFAULT; 
    } 
    vir_led3_moder =  ioremap ( PHY_LED3_MODER, 4 ) ; 
    if ( vir_led3_moder== NULL ) 
    { 
        printk ( "MODER寄存器地址映射失败\n" ) ; 
        return  - EFAULT; 
    } 
    vir_led3_odr =  ioremap ( PHY_LED3_ODR, 4 ) ; 
    if ( vir_led3_odr== NULL ) 
    { 
        printk ( "ODR寄存器地址映射失败\n" ) ; 
        return  - EFAULT; 
    } 
    vir_rcc =  ioremap ( PHY_RCC, 4 ) ; 
    if ( vir_rcc== NULL ) 
    { 
        printk ( "MODER寄存器地址映射失败\n" ) ; 
        return  - EFAULT; 
    } 
    printk ( "寄存器地址映射成功\n" ) ; 
    
    ( * vir_rcc)  |=  ( 0x1  <<  4 ) ; 
    ( * vir_rcc)  |=  ( 0x1  <<  5 ) ; 
    ( * vir_led1_moder)  &=  ( ~ ( 0x3  <<  20 ) ) ; 
    ( * vir_led1_moder)  |=  ( 0x1  <<  20 ) ; 
    ( * vir_led1_odr)  &=  ( ~ ( 0x1  <<  10 ) ) ; 
    ( * vir_led2_moder)  &=  ( ~ ( 0x3  <<  20 ) ) ; 
    ( * vir_led2_moder)  |=  ( 0x1  <<  20 ) ; 
    ( * vir_led2_odr)  &=  ( ~ ( 0x1  <<  10 ) ) ; 
    ( * vir_led3_moder)  &=  ( ~ ( 0x3  <<  16 ) ) ; 
    ( * vir_led3_moder)  |=  ( 0x1  <<  16 ) ; 
    ( * vir_led3_odr)  &=  ( ~ ( 0x1  <<  8 ) ) ; 
    return  0 ; 
} 
static  void  __exit mycdev_exit ( void ) 
{ 
    
    iounmap ( vir_led1_moder) ; 
    iounmap ( vir_led1_odr) ; 
    iounmap ( vir_led2_moder) ; 
    iounmap ( vir_led2_odr) ; 
    iounmap ( vir_led3_moder) ; 
    iounmap ( vir_led3_odr) ; 
    iounmap ( vir_rcc) ; 
    
    unregister_chrdev ( major, "mychrdev" ) ; 
} 
module_init ( mycdev_init) ; 
module_exit ( mycdev_exit) ; 
MODULE_LICENSE ( "GPL" ) ;