Development of uClinux drivers

Source: Internet
Author: User

Development of uClinux drivers

Basic knowledge:

Kernel space ------- user space (memory application data exchange, etc)

Device ---- Device Driver ----- device No.

Driver category: character device block device network device

Interrupt handling

Driver development for uClinux and Linux is the same, but the debugging method is different. Learning driver development for uClinux is the process of learning the driver development for Linux. Linux driver debugging requires at least one computer, plus source code-level kernel debugging tools such as GDB and kdbg. If a virtual machine is installed, you only need one computer, however, this requires higher computer performance. For Driver debugging like uClinux, it is best to have a development board or a simulator. Transplantation on the ARM chip is an important application of uClinux. The most common Simulator for simulation of ARM is Skyeye, an open-source software developed by Chinese people. It can not only simulate the ARM kernel, but also provide further support for Chips Using arm as the kernel. You can use Skyeye
-H: view the ARM chips that Skyeye can simulate. Of course, you can also make some extensions to Skyeye to meet your own requirements. The following describes how to add a driver to uClinux.

1. Compile a simple character driver

// ----------------------------------------------- Mydevice. c -------------------------------------------

# Include <Linux/module. h>

# Include <Linux/init. h>

# Include <Linux/fs. h>

# Include <ASM/uaccess. h>

Module_license ("GPL ");

# Define major_num 254 // master device number

# Define driver_name "mydevice"

Static int global_var = 0; // global variable of the "mydevice" Device

Static ssize_t mydevice_read (struct file *, char *, size_t, loff_t *);

Static ssize_t mydevice_write (struct file *, const char *, size_t, loff_t *);

// Initialize the file_operations struct of the character Device Driver

Struct file_operations mydevice_fops =

{

. Read = mydevice_read,

. Write = mydevice_write,

};

Int mydevice_init (void)

{

Int ret;

// Register the device driver

Printk ("<0> mydevice_init \ n ");

Ret = register_chrdev (major_num, driver_name, & mydevice_fops );

Printk ("<0> register_chr_dev return % d \ n", RET );

If (Ret <0)

{

Printk ("<0> mydevice register failed \ n ");

}

Else

{

Printk ("<0> mydevice register success \ n ");

}

Return ret;

}

Void mydevice_exit (void)

{

Printk ("<0> mydevice_exit! \ N ");

Unregister_chrdev (major_num, driver_name );

}

Static ssize_t mydevice_read (struct file * filp, char * Buf, size_t Len, loff_t * Off)

{

// Copy global_var from kernel space to user space

If (copy_to_user (BUF, & global_var, sizeof (INT )))

{

Return-efault;

}

Return sizeof (INT );

}

Static ssize_t mydevice_write (struct file * filp, const char * Buf, size_t Len, loff_t * Off)

{

// Copy data from user sapce to kernel space

If (copy_from_user (& global_var, Buf, sizeof (INT )))

{

Return-efault;

}

Return sizeof (INT );

}

// Configure //-----------------------------------------------------------------------------------------------------------------

2. statically compile the driver into the uClinux kernel

To add a written driver to uClinux, you need to make some modifications to the configuration file and makefile. Because our driver is used as a drivers, we use mydevice. copy C to the (uClinux directory)/(Linux Kernel Directory)/Drivers/Char directory. Modify config. In, makefile, And mem. c In this directory.

1. Modify config. In:

Add the following line under the comment 'character devices' line:

Bool 'support for mydevice' config_mydevice y

2. Modify makefile

In

#

# UClinux drivers

#

Add the following content:

OBJ-$ (config_mydevice) + = mydevice. o

3. Modify mem. C.

Mem. c initializes some virtual devices. These devices usually use memory as the basic "device". We add the mydevice initialization code to it:

Add the following code to the start position of the mem. c file:

# Ifdef config_mydevice

Extern int mydevice_init (void );

# Endif

Modify the chr_dev_init function of mem. C.

If (devfs_register_chrdev (mem_major, "mem", & memory_fops ))

Printk ("unable to get Major % d For memory Devs \ n", mem_major );

Memory_devfs_register ();

Rand_initialize ();

# Ifdef config_mydevice

Mydevice_init ();

# Endif

# Ifdef config_i2c

I2c_init_all ();

# Endif

4. Compile the mydevice driver

All the modifications are so simple. The next question is how to compile our driver into the kernel.

(1) configure the kernel

Run make menuconfig

Go to the kernel/library/defaults selection menu

Select customize kernel settings

Exit and Save settings

Go to the character devices sub-menu in the new menu

Choose support for mydevice

Exit and Save settings

Use make Dep and make commands to generate kernel images and memory file system images

3. test our driver

How to deal with our drivers? Of course, the answer is to build an application. In "study Note 2", I have explained in detail how to add an application to uClinux, now let's take a look at how to call our driver in the application.

In order for our driver to be used by the application, we must create a file node in advance. In general Linux, we can use the mknod command to create the node in the/dev directory. But in the embedded Linux system uClinux, a better way is to let uClinux do these things at startup:

Open the makefile in the (uClinux directory)/vendors/GDB/armulator-EB directory and make some modifications as follows:

(Note: select the makefile under vendors according to the selection in the menu of Vendor/product selection during configuration.

The positions of different makefiles on the chip are different)

Devices = \

Mydevice, C, 254,0 \

Tty, C, 5, 0 console, C, 5, 1 cua0, C, 5, 64 cua1, C, 5, 65 \

Here, mydevice, C, and 0 are the content we added. The meanings of each item are as follows:

Mydevice: Device Name

C: character device

254: master device number

0: Sub-device number

Let's take a look at our testing program:

// ------------------------------------ Hello. c --------------------------------------

# Include <sys/types. h>

# Include <sys/STAT. h>

# Include <stdio. h>

# Include <fcntl. h>

Int main (void)

{

Int FD, num;

FD = open ("/dev/mydevice", o_rdwr, s_irusr | s_iwusr );

If (FD! =-1)

{

Read (FD, & num, sizeof (INT ));

Printf ("The globalvar is % d \ n", num );

Printf ("Please input the num written to globalvar \ n ");

Scanf ("% d", & num );

Write (FD, & num, sizeof (INT ));

Read (FD, & num, sizeof (INT ));

Printf ("The globalvar is % d \ n", num );

Close (FD );

}

Else

{

Printf ("device open failure \ n ");

}

}

This code should be easy to understand. First open the device and then write and read it out.

After the configuration, re-compile the kernel and use Skyeye simulation (we can also use the Development Board for PS)

Now, we have started the development of uClinux drivers.

References:

Http://dev.yesky.com/186/2623186.shtml

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/I2Cbus/archive/2008/08/26/2834849.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.