IOCTL is one of the functions popular among the masses. Here, I will take a few notes and sort out the code I wrote below.
Main. c
# Include <stdio. h> <br/> # include <sys/types. h> <br/> # include <sys/STAT. h> <br/> # include <fcntl. h> <br/> # include <unistd. h> <br/> # include <Linux/IOCTL. h> <br/> # include ".. /ioctl_c.h "<br/> gpio_data_s led_ctl; <br/> int main (INT argc, char ** argv) <br/>{< br/> int testdev = 0; <br/> int I = 0; <br/> int erro = 0; <br/> char Buf [10]; </P> <p> // open the device file <br/> testdev = open ("/dev/test", o_rdwr ); <br/> If (testdev =-1) <br/> {<br/> printf ("cann't open file ..... /n "); <br/> exit (0); <br/>}< br/> while (1) <br/>{< br/> // led_ctl Structure assignment <br/> led_ctl.port = 'G'; <br/> led_ctl.bit = 5; <br/> led_ctl.value = 0; </P> <p> // call the ioctl function <br/> IOCTL (testdev, gpio_io_set, & led_ctl); <br/> IOCTL (testdev, gpio_io_write, & led_ctl ); <br/> IOCTL (testdev, gpio_io_read, & led_ctl); <br/> sleep (1); </P> <p> led_ctl.port = 'G '; <br/> led_ctl.bit = 6; <br/> led_ctl.value = 0; <br/> IOCTL (testdev, gpio_io_set, & led_ctl); <br/> IOCTL (testdev, gpio_io_write, & led_ctl); <br/> IOCTL (testdev, gpio_io_read, & led_ctl); <br/> sleep (1 ); <br/>}< br/> close (testdev ); <br/>}< br/>/* <br/> mknod/dev/test C 253 0 <br/> */
IOCTL. h
# Ifndef _ ioctl_c_h __< br/> # DEFINE _ ioctl_c_h __< br/> typedef struct gpio_data_t <br/>{< br/> unsigned char port; <br/> unsigned int bit; <br/> unsigned int value; <br/>} gpio_data_s; <br/> # define gpio_ioc_magic 12 // documentation/ioctl-number.txt <br/> # define gpio_io_set_gpg _ Iow (gpio_ioc_magic, 0, sizeof (gpio_data_s )) <br/> # define writable _ IOWR (gpio_ioc_magic, 1, sizeof (gpio_data_s) <br/> # define gpio_io_write _ Iow (gpio_ioc_magic, 2, sizeof (random )) <br/> # define gpio_io_read _ IOWR (gpio_ioc_magic, 3, sizeof (gpio_data_s) <br/> # endif
Driver Layer Code test. c
/************ <Br/> Linux headers <br/> ***************/< br/> # include <Linux/types. h> <br/> # include <Linux/Fs. h> <br/> # include <Linux/mm. h> <br/> # include <Linux/errno. h> <br/> # include <Linux/module. h> <br/> # include <Linux/moduleparam. h> <br/> # include <Linux/kernel. h> <br/> # include <ASM/uaccess. h> <br/> # include <Linux/cdev. h> <br/> # include <Linux/IOCTL. h> <br/> # include <Linux/slab. h> <br/> # include <Linux/fcntl. h> <br/> # include <ASM/segment. h> <br/> # include <ASM/Io. h> <br/> # include <ASM/ARCH/regs-gpio.h> <br/> # include "ioctl_c.h" <br/> // device primary/secondary device number <br/> unsigned int test_major= 253; <br/> unsigned int test_minor = 0; <br/> struct cdev cdevc; <br/> module_license ("dual BSD/GPL"); <br/> gpio_data_s led; <br/> static void led_ctl () <br/>{< br/> // write the register at G50, for details, see S3C2440 datasheet <br/> // here, it mainly controls the flashing of the led of the development board, And flashes below per second <br/> If (LED. port = 'G' & LED. bit = 5 & LED. value = 0) <br/>{< br/> printk ("G50/N"); <br/>__ raw_writel (0x400, s3c2410_gpgcon ); <br/> _ raw_writel (0 xffdf, s3c2410_gpgdat); <br/>}< br/> // g60 write register <br/> else if (LED. port = 'G' & LED. bit = 6 & LED. value = 0) <br/>{< br/> printk ("g60/N"); <br/>__ raw_writel (0x1000, s3c2410_gpgcon ); <br/> _ raw_writel (0 xffbf, s3c2410_gpgdat); <br/>}< br/> static int read_test (struct file * file, char * Buf, int count, loff_t * f_pos) <br/> {<br/> printk ("/n read_test"); <br/> printk ("% d ", count); <br/> return count; <br/>}< br/> static int write_test (struct file * file, const char * Buf, int count, loff_t * f_pos) <br/>{< br/> printk ("/n write_test"); <br/> return count; <br/>}< br/> static int ioctl_test (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long Arg) <br/>{< br/> If (copy_from_user (& LED, ARG, sizeof (gpio_data_s) <br/>{< br/> return-efault; <br/>}< br/> printk ("% C % d/N", LED. port, LED. bit, LED. value); <br/> printk ("/n ioctl_test"); <br/> switch (CMD) <br/>{< br/> case gpio_io_set_gpg: led_ctl (); break; <br/> case gpio_io_get_gpg: led_ctl (); break; <br/> // case gpio_io_write: printk ("cmd3"); break; <br/> // case gpio_io_read: printk ("cmd3"); break; <br/> default: break; <br/>}< br/> return cmd; <br/>}< br/> static int open_test (struct inode * inode, struct file * file) <br/>{< br/> printk ("/n open_test"); <br/> return 0; <br/>}< br/> static void release_test (struct inode * inode, struct file * file) <br/>{< br/> printk ("/n release_test"); <br/>}< br/> struct file_operations test_fops ={ <br/>. owner = this_module, <br/>. read = read_test, <br/>. write = write_test, <br/>. open = open_test, <br/>. IOCTL = ioctl_test, <br/>. release = release_test, <br/>}; <br/> int simple_c_init_module (void) <br/>{< br/> int result; <br/> dev_t Dev = 0; </P> <p> Dev = mkdev (test_major, test_minor); <br/> result = register_chrdev_region (Dev, 1, "test "); </P> <p> printk ("Major = % d, minor = % d/N", test_major, test_minor ); </P> <p> If (result <0) <br/> {<br/> printk (kern_info "test: Can't Get Major number/N "); <br/> return result; <br/>}</P> <p> cdev_init (& cdevc, & test_fops); <br/> cdevc. owner = this_module; <br/> cdevc. ops = & test_fops; <br/> result = cdev_add (& cdevc, Dev, 1); <br/> If (result) <br/> printk ("error % d adding test", result); <br/> return 0; <br/>}< br/> void simple_c_cleanup_module (void) <br/>{ <br/> dev_t Dev = 0; <br/> Dev = mkdev (test_major, test_minor); <br/> cdev_del (& cdevc ); <br/> unregister_chrdev_region (Dev, 1); <br/>}< br/> module_init (simple_c_init_module); <br/> module_exit (simple_c_cleanup_module );
Makefile is required for compilation.
# To build modules outside of the kernel tree, we run "make" <br/> # in the kernel source tree; the makefile these then provided des this <br/> # makefile once again. <br/> # This conditional selects whether we are being encoded from the <br/> # kernel makefile or not. <br/> ifeq ($ (kernelrelease),) <br/> # assume the source tree is where the running kernel was built <br/> # You shoshould set kerneldir in Environment if it's elsewhere <br/> # kerneldir? =/Lib/modules/$ (shell uname-R)/build <br/> kerneldir =/home/utu-linux_for_s3c2440_V1.5.3 <br/> # kerneldir = $ (kdir) <br/>#< br/> # the current directory is passed to sub-makes as argument <br/> pwd :=$ (shell PWD) <br/> modules: <br/> $ (make)-C $ (kerneldir) M = $ (PWD) Modules <br/> modules_install: <br/> $ (make) -C $ (kerneldir) M = $ (PWD) modules_install <br/> clean: <br/> RM-RF *. O *~ Core. depend. *. CMD *. ko *. mod. c. tmp_versions <br/>. phony: modules modules_install clean <br/> else <br/> # called from kernel build system: just declare what our modules are <br/> obj-M: = test. O <br/> endif <br/>