iny6410 simple LED character device driver io driver

Publisher:oplkjjjLatest update time:2019-10-30 Source: 51heiKeywords:iny6410 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Step1: Driver loading function: ***_init;

This function is executed only once when driving the hardware, and its function is to initialize the hardware, such as configuring the output direction of the IO port, configuring the IO pull-up, etc. This function is passed into the module_init(***_init); function so that it is automatically executed when the driver is loaded;


Step 2: Write open, read, write, and release functions;

The purpose of these three functions is to pass in the file_operations structure; these three functions are called as excuses when the application calls the driver.

The function of open is to load the driver when writing an application; its prototype is pen(strpath, authority), such as: fd = open("/dev/led",O_RDWR); //The open function loads the driver, and the return value is a descriptor. When the return value is 0, the driver is loaded successfully.

The prototype of the Write function is: (structfile *filp, const char __user *buf, size_t count,loff_t *f_pos)   


Step 3: Assign the function in step 2 to the operations structure

struct file_operations led_fops =  

{   

    .owner = THIS_MODULE,   

    .open = led_open,   

    .read = led_read,   

    .write = led_write,   

    .release = led_release,   

};

Step4: Register the character device driver module in the ***_init function; the following is the registration LED driver function:

register_chrdev(LED_MAJOR,"led",&led_fops);

int register_chrdev(unsigned int major,const char *name,struct file_operations *fops);

If the parameter major is equal to 0, it means that the major device number dynamically allocated by the system is used; if it is not 0, it means static registration.

To unregister a character device, you can use the unregister_chrdev function.


Step 5: Unregister the character device driver module:

In led_exit (you can use any name, just pass the function name to module_exit) use unregister_chrdev(LED_MAJOR,"led"); function to unregister the driver. And assign it to module_exit(led_exit);



A living example   


1. Check the user manual


LED1, LED2, LED3, LED4 are connected to GPK4, GPK5, GPK6, GPK7 respectively

2. Check the 6410 chip manual





There are 3 more steps to follow:

1. Set GPIO to OUTPUT.

   Set GPK4, GPK5, GPK6, GPK7 to output=0001

   That is, 19:28 of GPKCON0 are configured as 0001


2. Set the GPIO data.

   Set bits 4:7 of GPKDATA to 0


3. Set GPKUP to pull up.

   Set bits 4:7 of GPKUP to 10


3. Code

led_driver.cStep1: driver loading function: ***_init;


This function is executed only once when driving the hardware, and its function is to initialize the hardware, such as configuring the output direction of the IO port, configuring the IO pull-up, etc. This function is passed into the module_init(***_init); function so that it is automatically executed when the driver is loaded;


Step 2: Write open, read, write, and release functions;

The purpose of these three functions is to pass in the file_operations structure; these three functions are called as excuses when the application calls the driver.

The function of open is to load the driver when writing an application; its prototype is pen(strpath, authority), such as: fd = open("/dev/led",O_RDWR); //The open function loads the driver, and the return value is a descriptor. When the return value is 0, the driver is loaded successfully.

The prototype of the Write function is: (structfile *filp, const char __user *buf, size_t count,loff_t *f_pos)   


Step 3: Assign the function in step 2 to the operations structure

struct file_operations led_fops =  

{   

    .owner = THIS_MODULE,   

    .open = led_open,   

    .read = led_read,   

    .write = led_write,   

    .release = led_release,   

};

Step4: Register the character device driver module in the ***_init function; the following is the registration LED driver function:

register_chrdev(LED_MAJOR,"led",&led_fops);

int register_chrdev(unsigned int major,const char *name,struct file_operations *fops);

If the parameter major is equal to 0, it means that the major device number dynamically allocated by the system is used; if it is not 0, it means static registration.

To unregister a character device, you can use the unregister_chrdev function.


Step 5: Unregister the character device driver module:

In led_exit (you can use any name, just pass the function name to module_exit) use unregister_chrdev(LED_MAJOR,"led"); function to unregister the driver. And assign it to module_exit(led_exit);



A living example   


1. Check the user manual


LED1, LED2, LED3, LED4 are connected to GPK4, GPK5, GPK6, GPK7 respectively

2. Check the 6410 chip manual





There are 3 more steps to follow:

1. Set GPIO to OUTPUT.

   Set GPK4, GPK5, GPK6, GPK7 to output=0001

   That is, 19:28 of GPKCON0 are configured as 0001


2. Set the GPIO data.

   Set bits 4:7 of GPKDATA to 0


3. Set GPKUP to pull up.

   Set bits 4:7 of GPKUP to 10


3. Code

led_driver.c


#include /*It defines the module's API, type and macros (MODULE_LICENSE, MODULE_AUTHOR, etc.). All kernel modules must include this header file. */   

        

    #include /*This file should be included when using kernel information priority. Priority information is generally used when using the printk function*/  

      

    #include     

    #include /* copy_to_user,copy_from_user */     

    #include /*readl writel*/  

    #include      

    #include       

    #include       

      

        

    #define LED_MAJOR 243  

      

    #define LED_ON 1  

    #define LED_OFF 0  

    #define LED_1_ON 2  

    #define LED_1_OFF 3  

    #define LED_2_ON 4  

    #define LED_2_OFF 5  

    #define LED_3_ON 6  

    #define LED_3_OFF 7  

    #define LED_4_ON 8  

    #define LED_4_OFF 9  

      

       

    static int led_open (struct inode *inode,struct file *filp)    

        

    {    

        unsigned tmp;       

      

        tmp = readl(S3C64XX_GPKCON);      

        tmp = (tmp&0x0000ffff)| 0x1111ffff;  

        writel(tmp, S3C64XX_GPKCON);     

      

        printk("#########open#######n");    

        return 0;    

    }    

        

    static int led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)    

    {      

        return count;    

    }    

        

        

    static int led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)  

      

    {    

        char wbuf[10];    

        unsigned tmp;       

          

        if(copy_from_user(wbuf,buf,count))  

            return -EFAULT;    

      

            switch(wbuf[0])    

            {    

              

            case LED_ON:   

                    tmp = readl(S3C64XX_GPKDAT);       

                tmp &= (0x0f);       

                writel(tmp, S3C64XX_GPKDAT);  

                printk("turn on!n");      

                    break;  

      

            case LED_OFF:    

                tmp = readl(S3C64XX_GPKDAT);       

                tmp |= (0xf0);       

                writel(tmp, S3C64XX_GPKDAT);   

                printk("turn off!n");     

                break;             

      

            case LED_1_ON:    

                tmp = readl(S3C64XX_GPKDAT);       

                tmp &= (0xef);       

                writel(tmp, S3C64XX_GPKDAT);   

                printk("turn off!n");     

                break;    

      

            case LED_1_OFF:   

                    tmp = readl(S3C64XX_GPKDAT);       

                tmp |= (0xf0);       

                writel(tmp, S3C64XX_GPKDAT);  

                printk("turn on!n");      

                    break;    

      

            case LED_2_ON:    

                tmp = readl(S3C64XX_GPKDAT);       

                tmp &= (0xdf);       

                writel(tmp, S3C64XX_GPKDAT);   

                printk("turn off!n");     

                break;    

      

            case LED_2_OFF:   

                    tmp = readl(S3C64XX_GPKDAT);       

                tmp |= (0xf0);       

                writel(tmp, S3C64XX_GPKDAT);  

                printk("turn on!n");      

                    break;    

      

            case LED_3_ON:    

                tmp = readl(S3C64XX_GPKDAT);       

                tmp &= (0xbf);       

                writel(tmp, S3C64XX_GPKDAT);   

                printk("turn off!n");     

                break;    

      

            case LED_3_OFF:   

                    tmp = readl(S3C64XX_GPKDAT);       

                tmp |= (0xf0);       

                writel(tmp, S3C64XX_GPKDAT);  

                printk("turn on!n");      

                    break;    

      

            case LED_4_ON:    

                tmp = readl(S3C64XX_GPKDAT);       

                tmp &= (0x7f);       

                writel(tmp, S3C64XX_GPKDAT);   

                printk("turn off!n");     

                break;    

      

            case LED_4_OFF:   

                    tmp = readl(S3C64XX_GPKDAT);       

                tmp |= (0xf0);       

                writel(tmp, S3C64XX_GPKDAT);  

                printk("turn on!n");      

                    break;    

              

      

            default :    

                    break;    

            }    

         return 0;    

    }    

        

    int led_release (struct inode *inode, struct file *filp)    

    {    

        printk("#########release######n");    

        return 0;    

    }    

        

    struct file_operations led_fops =  

    {    

        .owner = THIS_MODULE,    

        .open = led_open,    

        .read = led_read,    

        .write = led_write,    

        .release = led_release,    

    };    

        

    int __init led_init (void)    

    {     

        int rc;    

        printk ("Test led devn");    

        rc = register_chrdev(LED_MAJOR,"led",&led_fops);   

       

        if (rc <0)    

        {    

            printk ("register %s char dev errorn","led");    

            return -1;    

        }    

        printk ("ok!n");    

        return 0;    

    }    

        

    void __exit led_exit (void)    

    {    

        unregister_chrdev(LED_MAJOR,"led");    

        printk ("module exitn");    

[1] [2] [3]
Keywords:iny6410 Reference address:iny6410 simple LED character device driver io driver

Previous article:Tips for getting started with ARM and embedded systems
Next article:Samsung S3C2440 ARM920T core processor register arrangement-very useful information

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号