The IOCTL test is an advanced Note of the coolder (1). The underlying IOCTL processing can control all registers by means of shift !~
Main. c upper-layer application test code
# 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 io_ctl; <br/> void main (void) <br/>{< br/> int testdev; <br/> int I; <br/> char Buf [10]; <br/> testdev = open ("/dev/test", o_rdwr); <br/> If (testdev =-1) <br/>{< br/> printf ("cann't open file ..... /n "); <br/> exit (0); <br/>}< br/> printf (" Buf = 0x % x/N ", Buf ); <br/> Read (testdev, Buf, 10); <br/> write (testdev, Buf, 1); <br/> while (1) <br/>{< br/> io_ctl.port = 6; <br/> io_ctl.bit = 5; <br/> io_ctl.value = 1; <br/> io_ctl.v = 0; <br/> IOCTL (testdev, gpio_io_set, & io_ctl); <br/> IOCTL (testdev, gpio_io_write, & io_ctl); <br/> IOCTL (testdev, gpio_io_read, & io_ctl); <br/> io_ctl.port = 6; <br/> io_ctl.bit = 6; <br/> io_ctl.value = 1; <br/> io_ctl.v = 1; <br/> IOCTL (testdev, gpio_io_set, & io_ctl); <br/> IOCTL (testdev, gpio_io_write, & io_ctl); <br/> IOCTL (testdev, gpio_io_read, & io_ctl); <br/> sleep (1); <br/> io_ctl.port = 6; <br/> io_ctl.bit = 6; <br/> io_ctl.value = 1; <br/> io_ctl.v = 0; <br/> IOCTL (testdev, gpio_io_set, & io_ctl); <br/> IOCTL (testdev, gpio_io_write, & io_ctl ); <br/> IOCTL (testdev, gpio_io_read, & io_ctl); <br/> io_ctl.port = 6; <br/> io_ctl.bit = 5; <br/> io_ctl.value = 1; <br/> io_ctl.v = 1; <br/> IOCTL (testdev, gpio_io_set, & io_ctl); <br/> IOCTL (testdev, gpio_io_write, & io_ctl ); <br/> IOCTL (testdev, gpio_io_read, & io_ctl); <br/> sleep (1); <br/>}< br/> // IOCTL (testdev, gpio_io_write, sizeof (gpio_data_s); <br/> // IOCTL (testdev, gpio_io_read, sizeof (gpio_data_s); <br/> printf ("% s", Buf ); <br/> // for (I = 0; I <10; I ++) <br/> // printf ("[% d]/n ", buf [I]); <br/> close (testdev ); <br/>}< br/>/* <br/> mknod/dev/test C 253 0 <br/> */
IOCTL underlying driver code implementation
# 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 <SM/Io. h> <br/> # include <ASM/ARCH/regs-gpio.h> <br/> # include "ioctl_c.h" <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 IOCTL; </P> <p> 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/> stat IC 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 void gpio_cfg () <br/>{< br/> size_t data; <br/> printk ("gpio_cfg start! /N "); <br/> DATA = _ raw_readl (IOCTL. Port * 0x10 + s3c2410_gpacon); <br/> Data & = ~ (3 <2 * IOCTL. bit); <br/> data | = (IOCTL. value <2 * IOCTL. bit); <br/>__ raw_writel (data, IOCTL. port * 0x10 + s3c2410_gpacon); <br/>}< br/> static void gpio_read () <br/>{< br/> printk ("gpio_read start !! /N "); <br/> size_t data_con, data_dat; <br/> data_con = _ raw_readl (IOCTL. port * 0x10 + s3c2410_gpacon); <br/> data_dat = _ raw_readl (IOCTL. port * 0x10 + s3c2410_gpadat); <br/> printk ("% LD/n % LD/N", data_con, data_dat ); <br/>}< br/> static void gpio_write () <br/>{< br/> printk ("gpio-Write Start !! /N "); <br/> size_t data; <br/> DATA = _ raw_readl (IOCTL. port * 0x10 + s3c2410_gpadat); <br/> Data & = ~ (1 <IOCTL. bit); <br/> data | = (IOCTL. v <IOCTL. bit); <br/>__ raw_writel (data, IOCTL. port * 0x10 + s3c2410_gpadat); <br/>}< br/> static int ioctl_test (struct inode * inode, struct file * filp, unsigned int cmd, unsigned long Arg) <br/>{< br/> If (copy_from_user (& ioctl, ARG, sizeof (gpio_data_s) <br/>{< br/> return-efault; <br/>}< br/> printk ("/n ioctl_test"); <br/> switch (CMD) <br/>{< br/> case gpio_io_set: gpio_cfg (); break; <br/> // case gpio_io_get:; break; <br/> case gpio_io_write: gpio_write (); break; <br/> case gpio_io_read: gpio_read (); 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 );