1. Preparations
First, install the GCC tool chain and the development environment. You can check the previous steps.
You have to compile the kernel. Generally, the Development Board has the kernel. Now I do not know how to configure the kernel. You can only compile the kernel according to the default settings of the Development Board. uboot needs to be compiled before compilation, it is recommended that new users like me learn to write drivers first and learn Kernel configuration pruning slowly. I think this is definitely a very simple process, but I didn't find a way, I will share with you some time later. If you have any questions, I am very grateful.
My embedded kernel compilation path is/home/cfan/Linux/linux-3.0.1/, which will be used soon.
Today, I will teach you how to use eclipse to develop a simple driver, LED driver. In fact, it may be a little troublesome to compile this simple driver using eclipse, if it is a big project, I think the advantages of the integrated development environment will be reflected, and the eclipse Editor interface is friendly, just like rvds4.0.
2. Create a driver project and set up eclipse
Open eclipse
You can create a shortcut key pointing to eclipse on the desktop or execute it in the eclipse directory. /eclipse can be started. I have set the global variables of Eclipse, so you only need to enter eclipse in the terminal to start it, as shown in
We recommend that you select the directory shared by NFS for the project directory, so that you can easily load the driver or execute the program from the Development Board, and select the shared directory nfs6410.
Create a C Project, empty project
Continue to the next step and fill in the path of your arm-Linux-GCC.
Click Finish after setting.
Now that the new project has been created, another important task is to add the. c file. Right-click the project, and select Properties to C/C ++ regular ----> code analysis ----> path and symbol
Click exportsettings at the bottom to export the settings as an XML file. I spoke to the desktop.
Click OK to exit the application.
Open the. xml file at the location you just saved and use a text editor. on the desktop, right-click it and use a text editor.
Now we need to add the macro definition in Autoconf. h to eclipse and perform the following steps:
Open the kernel directory include/generated/which depends on your actual situation, my CD/home/cfan/Linux/linux-3.0.1/include/generated /, in addition, open a terminal CD to this directory.
Run
cat autoconf.h |grep define |awk '{print "<macro><name>" $2 "</name><value>" $3 "</value></macro>"}' > symbol.xml
Open this directory/home/cfan/Linux/linux-3.0.1/include/generated, there will be an additional file
Use a text editor to open the symbol. xml file.
In this case, two XML files are opened in the text editor. To open the XML file exported from eclipse, you need to add a line of code between the two lines of code (if there are two lines, is the one below)
<Language name = "C source file"> </language>
Add
<macro><name>__KERNEL__</name><value>1</value></macro>
For example
After adding
Copy all the code in the symbol. xml file.
<macro><name>__KERNEL__</name><value>1</value></macro>
The next line of this line, as shown in figure
In the previous
<Language name = "C source file"> </language>
Add
<includepath>/home/cfan/linux/linux-3.0.1/include</includepath><includepath>/home/cfan/linux/linux-3.0.1/arch/arm/include</includepath><includepath>/home/cfan/linux/linux-3.0.1/arch/arm/plat-samsung/include</includepath><includepath>/home/cfan/linux/linux-3.0.1/arch/arm/mach-s3c64xx/include</includepath>
The path here must be modified according to your actual kernel path. You can also add one by one in the project properties, that is, add a Linux-related path.
Save and exit.
Open the export location of eclipse, and now import the exported file.
Click Finish. If the Import fails, check my tutorial carefully. Application, exit. After the import, there will be several more paths, including the header file path in the kernel directory.
Create a new. c file
The Code was previously written.
/*************************************** **************************************** * ********************************** File Name: led_drive.c * Introduction: ok6410 LED driver * Author: different spirit yuan (cp1300@139.com) * Creation Time: 2012/08/27 17:28 * modification time: 2012/08/27 * Description: ok6410 Development Board (s3c246410) LED (gpio) *************************************** **************************************** * ******************************* // system header file # include <Linux/miscdevice. H> # include <Linux/delay. h> # include <ASM/IRQ. h> # include <Mach/hardware. h> # include <Linux/kernel. h> # include <Linux/module. h> # include <Linux/init. h> # include <Linux/mm. h> # include <Linux/Fs. h> # include <Linux/types. h> # include <Linux/delay. h> # include <Linux/moduleparam. h> # include <Linux/slab. h> # include <Linux/errno. h> # include <Linux/IOCTL. h> # include <Linux/cdev. h> # include <Linux/string. h> # include <Linux/ List. h> # include <Linux/PCI. h> # include <ASM/uaccess. h> # include <ASM/atomic. h> # include <ASM/unistd. h> // -------------------------- // # include <Mach/map. h> # include <Mach/regs-clock.h> # include <Mach/regs-gpio.h> // ------------------------ // # include <plat/gpio-cfg.h> # include <Mach/gpio-bank-e.h> # include <Mach/ gpio-bank-m.h> ////////////////////////////////////// ///// // Driver Module name # define device_name "ok641 0_led "// function declaration ////////////////////////////////// ///// // static long ok6410_led_ioctl (struct file * file, unsigned int cmd, unsigned long Arg); static ssize_t ok6410_led_write (struct file * file, const char _ User * buff, size_t size, loff_t * Loff ); static ssize_t ok6410_led_read (struct file * file, char _ User * buff, size_t size, loff_t * Loff ); //////////////////////////////////////// //// // * The structure is driven by a character device. Core * When the application operates the open, read, write and other functions provided by the device file, * will eventually call the corresponding function in this structure */static struct file_operations dev_fops = {. owner = this_module, // This is a macro that points to the _ this_module variable automatically created during compilation. unlocked_ioctl = ok6410_led_ioctl ,. read = ok6410_led_read ,. write = ok6410_led_write}; // register the information used by the driver static struct miscdevice MISC = {. minor = misc_dynamic_minor ,. name = device_name, // Driver Module name. foPs = & dev_fops,}; // struct semaphore led_sem when the LED Device accesses the semaphores ;/** **************************************** **************************************** * ****************************** Function Name: static int _ init ok6410_led_init (void) * function: LED module initialization function * parameter: none * returned: 0: Successful; <0: Failed * dependency: underlying Linux macro definition * Author: heterogeneous element (cp1300@139.com) * Creation Time: * last modification time: * Description: Initialize led hardware, register the LED driver ************************************* **************************************** *************************** */Static int _ init ok6410_led_init (void) {int ret; unsigned int reg; // The GPIOM0-3 pushes the output Reg = readl (initi64xx_gpmcon ); // obtain the gpiom register data Reg & = (~ 0 xFFFF); // clear the previously set Reg | = 0x1111; // push and pull output writel (Reg, cloud64xx_gpmcon); // configure Io mode Reg = readl (cloud64xx_gpmdat ); // Reg | = 0xf; writel (Reg, initi64xx_gpmdat) before reading the data in the output register; // write 1 to turn off all the lights. ret = misc_register (& MISC ); // register the driver if (Ret <0) {printk (device_name "can't initialized led! \ N "); return ret;} init_mutex (& led_sem); // register the semaphore printk (device_name" initialized \ n "); Return 0; // return success }/********************************** **************************************** * ************************************ Function name: static long ok6410_led_ioctl (struct file * file, unsigned int cmd, unsigned long Arg) * function: send a command to the LED driver module, without any practical effect, directly return the 0 * parameter: no effect * return: 0 * dependency: none * Author: Alien (cp1300@139.com) * Creation Time: * last modification time: * Note: no *************************************** **************************************** * *******************************/static long ok6410_led_ioctl (struct File * file, unsigned int cmd, unsigned long Arg) {return 0 ;} /*************************************** **************************************** * ********************************** Function Name: static ssize_t ok6410_led_write (struct file * file, cons T char _ User * buff, size_t size, loff_t * Loff) * function: write data to the LED driver module, with low-level light on * parameter: file pointer (useless ); buff: data buffer pointer; Buff: number of data; Loff: no function * returned: 0: Successful; <0: Failure * dependency: Linux underlying macro * Author: heterogeneous element (cp1300@139.com) * Creation Time: 2012/08/27 * last modification time: 2012/08/27 * Description: lighting function, low-power flat, 0-3 bit; corresponding to four LEDs ************************************ **************************************** * *********************************/static ssize_t ok6410_led_write (struct F Ile * file, const char _ User * buff, size_t size, loff_t * Loff) {unsigned int reg; If (down_interruptible (& led_sem) // obtain the semaphore return-erestartsys; reg = readl (initi64xx_gpmdat); Reg & = (~ 0xf); Reg | = buff [0] & 0xf; writel (Reg, initi64xx_gpmdat); up (& led_sem); // release semaphore return 0 ;} /*************************************** **************************************** * ********************************** Function Name: static ssize_t ok6410_led_read (struct file * file, char _ User * buff, size_t size, loff_t * Loff) * function: Read led status, low light on * parameter: file: file pointer (ineffective); Buff: data buffer pointer; Buff: data quantity; Loff: ineffective * return: 0: Successful; <0: Failed * dependency: underlying Linux macro * Author: heterogeneous element (CP 1300@139.com) * Creation Time: * last modification time: * Description: Read the Light status, low-level light on, 0-3 bit effective; corresponding to four LEDs ************************************ **************************************** * *********************************/static ssize_t ok6410_led_read (struct file * file, char _ User * buff, size_t size, loff_t * Loff) {unsigned int reg; If (down_interruptible (& led_sem) // obtain the semaphore return-erestartsys; Reg = readl (initi64xx_gpmdat ); Buff [0] = reg | 0xfffffff0; up (& led_sem); // release semaphore return 0 ;} /*************************************** **************************************** * ********************************** Function Name: static void _ exit ok6410_led_exit (void) * function: unmount LED driver * parameter: No * returned: No * dependency: Linux underlying macro * Author: heterogeneous element (cp1300@139.com) * Creation Time: * last modification time: * description: uninstall the driver ************************************** ***************************** **************************************** * ***/Static void _ exit ok6410_led_exit (void) {unsigned int reg; // GPIOM0-3 input Reg = readl (initi64xx_gpmcon); // obtain gpiom register data Reg & = (~ 0 xFFFF); // clear the previously set writel (Reg, initi64xx_gpmcon); // configure the IO mode misc_deregister (& MISC ); // uninstall driver} // Dynamic Load Driver Interface (required) module_init (ok6410_led_init); module_exit (ok6410_led_exit); // other information (not required) module_author ("cp1300@139.com "); // driver author module_description ("ok6410 (cloud6410) LED driver"); // some description information module_license ("GPL"); // The following protocol
There will be a warning, regardless of him.
Remove the automatically generated makefile option from the project properties.
3. Create a New makefile and modify the makefile to compile the driver file.
ARCH=armCROSS_COMPILE=arm-linux-obj-m := led.oKDIR :=/home/cfan/linux/linux-3.0.1 PWD :=$(shell pwd)all:$(MAKE) -C $(KDIR) M=$(PWD) modulesclean:$(MAKE) -C $(KDIR) M=$(PWD) clean
The LED. o file is the name of your compiled file, which is fixed according to your actual situation.
Save and press Ctrl + B to compile the project.
After completion, you will find an additional led. KO in the directory, which is the compiled LED driver module.
4. Load the driver
Load the driver on the Development Board, and copy led. Ko to the Development Board without NFS. Whether it is an SD card or a USB flash drive, it is easy to do with NFS. CD to the project directory on the serial port terminal.
Run insmod led. Ko to load the driver. After the driver is loaded successfully, the LED lights are destroyed and the driver test program will be added later.
Now, you can use eclipse to write the driver. It will certainly be too cumbersome for new users. In fact, there are only three steps in total, but I have written more details, in the future, you can directly copy the project or import the XML file before the project is created, which may be helpful to you.
5. attaching to solve the problem that the ok6410 driver cannot be detached.
The driver needs to be loaded and detached frequently during embedded driver development. However, when rmmod is used, you will find that the driver cannot be detached, such as rmmod led. ko is the module name. I wrote it wrong.
This can read my article: http://blog.csdn.net/cp1300/article/details/7994014
After the solution, you can uninstall the driver.
Note: indicate the source for reprinting