1. 程式人生 > >LED驅動程式相關標頭檔案簡單介紹

LED驅動程式相關標頭檔案簡單介紹

[cpp] view plain copy print?
  1. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
  2.                                 《常識》  
  3. ¥應用程式----->系統核心----->裝置驅動----->硬體裝置  
  4. ¥裝置驅動既是系統核心的下屬,又是硬體裝置的老大。    
  5. ¥在inux系統中用一個檔案來代表一個裝置。這個檔案就叫裝置檔案。裝置驅動的責任是將應用程式對裝置檔案  
  6. 的開啟、讀、寫、定位等操作轉化為對硬體裝置的開啟、讀、寫、定位等操作。而對於任何硬體裝置,應用程式  
  7. 只需利用這些基本操作就可以完全控制它!  
  8. ¥編寫linux裝置驅動需要的知識結構:  
  9. 1、40%的設計模式相關知識。設計模式是系統核心限定的,做別人的下屬就得按照別人的規矩辦事。  
  10. 2、30%的核心工作原理相關知識。核心是你領導,領會領導意圖才能把事情辦好。  
  11. 3、30%的硬體相關知識。控制好硬體是你的的本質工作,你得把你的小弟管理好.  
  12. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                《常識》
¥應用程式----->系統核心----->裝置驅動----->硬體裝置
¥裝置驅動既是系統核心的下屬,又是硬體裝置的老大。  
¥在inux系統中用一個檔案來代表一個裝置。這個檔案就叫裝置檔案。裝置驅動的責任是將應用程式對裝置檔案
的開啟、讀、寫、定位等操作轉化為對硬體裝置的開啟、讀、寫、定位等操作。而對於任何硬體裝置,應用程式
只需利用這些基本操作就可以完全控制它!
¥編寫linux裝置驅動需要的知識結構:
1、40%的設計模式相關知識。設計模式是系統核心限定的,做別人的下屬就得按照別人的規矩辦事。
2、30%的核心工作原理相關知識。核心是你領導,領會領導意圖才能把事情辦好。
3、30%的硬體相關知識。控制好硬體是你的的本質工作,你得把你的小弟管理好.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

在解讀OK6410官方提供的LED驅動程式原始碼的過程中,發現很多沒見過的巨集和函式。例如S3C64XX_GPM(0)、S3C64XX_GPM_OUTPUT(0)、__raw_writel(tmp,S3C64XX_GPMPUD)、__raw_writel(tmp,S3C64XX_GPMCON)等。而這些都包含在一些標頭檔案裡面。另一方面,我們自己動手編寫LED的驅動程式也必須知道相關的標頭檔案有哪些,對我們有哪些用。因此,我覺得在自己動手編寫LED驅動程式之前對相關標頭檔案進行簡單的分析是非常有必要的。以下是我自己結合原始碼分析得出的一些結論,如有不正確的地方,希望能夠得到指正。

OK6410官方提供的LED驅動程式原始碼:

[cpp] view plain copy print?
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/fs.h>
  4. #include <linux/init.h>
  5. #include <linux/miscdevice.h>
  6. #include <linux/delay.h>
  7. #include <linux/device.h>
  8. #include <linux/cdev.h>
  9. #include <asm/irq.h>
  10. #include <mach/gpio.h>
  11. #include <plat/regs-gpio.h>
  12. #include <plat/gpio-cfg.h>
  13. #include <mach/hardware.h>
  14. #include <linux/io.h>
  15. #define DEVICE_NAME "leds"
  16. #define LED_MAJOR 231
  17. static unsigned long led_table [] = {  
  18.        S3C64XX_GPM(0),  
  19.        S3C64XX_GPM(1),  
  20.        S3C64XX_GPM(2),  
  21.        S3C64XX_GPM(3),  
  22. };  
  23. static unsigned int led_cfg_table [] = {  
  24.     S3C64XX_GPM_OUTPUT(0),  
  25.     S3C64XX_GPM_OUTPUT(1),  
  26.     S3C64XX_GPM_OUTPUT(2),  
  27.     S3C64XX_GPM_OUTPUT(3),  
  28. };  
  29. staticint s3c6410_leds_ioctl(  
  30.     struct inode *inode,   
  31.     struct file *file,   
  32.     unsigned int cmd,   
  33.     unsigned long arg)  
  34. {  
  35.     unsigned long tmp;  
  36.     switch(cmd) {  
  37.     case 0:  
  38.     case 1:  
  39.         if (arg > 4) {  
  40.             return -EINVAL;  
  41.         }  
  42.         tmp = __raw_readl(S3C64XX_GPMDAT);  
  43.         if(cmd)  
  44.             tmp &= (~(1<<arg));  
  45.         else
  46.             tmp |= (1<<arg);  
  47.         __raw_writel(tmp,S3C64XX_GPMDAT);  
  48. //      gpio_set_value(led_table[arg], !cmd);
  49.         return 0;  
  50.     default:  
  51.         return -EINVAL;  
  52.     }  
  53. }  
  54. staticstruct file_operations s3c6410_leds_fops = {  
  55.     .owner  =   THIS_MODULE,  
  56.     .ioctl  =   s3c6410_leds_ioctl,  
  57. };  
  58. staticstruct cdev cdev_leds;  
  59. structclass * my_class;  
  60. staticint __init s3c6410_leds_init(void)  
  61. {  
  62.     int ret;  
  63.     unsigned long tmp;  
  64.     int i;  
  65.     dev_t devno;  
  66.     printk(KERN_NOTICE "enter s3c6410_leds_init\n");  
  67.     devno = MKDEV(LED_MAJOR,0);  
  68.     ret = register_chrdev_region(devno,1,DEVICE_NAME);  
  69.     ret = 0;  
  70.     if(ret<0)  
  71.     {  
  72.         printk(KERN_NOTICE "can not register led device");  
  73.         return ret;  
  74.     }  
  75.     cdev_init(&cdev_leds,&s3c6410_leds_fops);  
  76.     cdev_leds.owner = THIS_MODULE;  
  77.     ret =cdev_add(&cdev_leds,devno,1);  
  78.     if(ret)  
  79.     {  
  80.         printk(KERN_NOTICE "can not add leds device");  
  81.         return ret;  
  82.     }  
  83.     my_class = class_create(THIS_MODULE,"my_class");  
  84.     if(IS_ERR(my_class))  
  85.     {  
  86.         printk("Err: Failed in creating class\n");  
  87.         return -1;    
  88.     }  
  89.     device_create(my_class,NULL,MKDEV(LED_MAJOR,0),NULL,DEVICE_NAME);  
  90.     //gpm0-3 pull up
  91.     tmp = __raw_readl(S3C64XX_GPMPUD);  
  92.     tmp &= (~0xFF);  
  93.     tmp |= 0xaa;  
  94.     __raw_writel(tmp,S3C64XX_GPMPUD);  
  95.     //gpm0-3 output mode
  96.     tmp = __raw_readl(S3C64XX_GPMCON);  
  97.     tmp &= (~0xFFFF);  
  98.     tmp |= 0x1111;  
  99.     __raw_writel(tmp,S3C64XX_GPMCON);  
  100.     //gpm0-3 output 0
  101.     tmp = __raw_readl(S3C64XX_GPMDAT);  
  102.     tmp |= 0x10;  
  103.     __raw_writel(tmp,S3C64XX_GPMDAT);  
  104.     //printk("S3C64XX_GPMCON is %x\n",__raw_readl(S3C64XX_GPMCON));
  105.     //printk("S3C64XX_GPMDAT is %x\n",__raw_readl(S3C64XX_GPMDAT));
  106.     //printk("S3C64XX_GPMPUD is %x\n",__raw_readl(S3C64XX_GPMPUD));
  107.     printk(DEVICE_NAME " initialized\n");  
  108.     return 0;  
  109. }  
  110. staticvoid __exit s3c6410_leds_exit(void)  
  111. {  
  112.     cdev_del(&cdev_leds);  
  113.     unregister_chrdev_region(MKDEV(LED_MAJOR,0),1);  
  114.     printk(KERN_NOTICE "s3c2440_leds_exit\n");  
  115. }  
  116. module_init(s3c6410_leds_init);  
  117. module_exit(s3c6410_leds_exit);  
  118. MODULE_LICENSE("GPL");  
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <asm/irq.h>
#include <mach/gpio.h>
#include <plat/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/hardware.h>
#include <linux/io.h>

#define DEVICE_NAME	"leds"
#define LED_MAJOR 231


static unsigned long led_table [] = {
       S3C64XX_GPM(0),
       S3C64XX_GPM(1),
       S3C64XX_GPM(2),
       S3C64XX_GPM(3),
};

static unsigned int led_cfg_table [] = {
	S3C64XX_GPM_OUTPUT(0),
	S3C64XX_GPM_OUTPUT(1),
	S3C64XX_GPM_OUTPUT(2),
	S3C64XX_GPM_OUTPUT(3),
};

static int s3c6410_leds_ioctl(
	struct inode *inode, 
	struct file *file, 
	unsigned int cmd, 
	unsigned long arg)
{
	unsigned long tmp;
	switch(cmd) {
	case 0:
	case 1:
		if (arg > 4) {
			return -EINVAL;
		}
		tmp = __raw_readl(S3C64XX_GPMDAT);
		if(cmd)
			tmp &= (~(1<<arg));
		else
			tmp |= (1<<arg);
		__raw_writel(tmp,S3C64XX_GPMDAT);
//		gpio_set_value(led_table[arg], !cmd);
		return 0;
	default:
		return -EINVAL;
	}
}


static struct file_operations s3c6410_leds_fops = {
	.owner	=	THIS_MODULE,
	.ioctl	=	s3c6410_leds_ioctl,
};

static struct cdev cdev_leds;
struct class * my_class;

static int __init s3c6410_leds_init(void)
{
	int ret;
	unsigned long tmp;
	int i;
	dev_t devno;
	printk(KERN_NOTICE "enter s3c6410_leds_init\n");


	devno = MKDEV(LED_MAJOR,0);

	ret = register_chrdev_region(devno,1,DEVICE_NAME);
	ret = 0;
	if(ret<0)
	{
		printk(KERN_NOTICE "can not register led device");
		return ret;
	}
	
	cdev_init(&cdev_leds,&s3c6410_leds_fops);
	cdev_leds.owner = THIS_MODULE;

	ret =cdev_add(&cdev_leds,devno,1);
	if(ret)
	{
		printk(KERN_NOTICE "can not add leds device");
		return ret;
	}

	my_class = class_create(THIS_MODULE,"my_class");
	if(IS_ERR(my_class))
	{
		printk("Err: Failed in creating class\n");
		return -1;	
	}

	device_create(my_class,NULL,MKDEV(LED_MAJOR,0),NULL,DEVICE_NAME);

	//gpm0-3 pull up
	tmp = __raw_readl(S3C64XX_GPMPUD);
	tmp &= (~0xFF);
	tmp |= 0xaa;
	__raw_writel(tmp,S3C64XX_GPMPUD);

	//gpm0-3 output mode
	tmp = __raw_readl(S3C64XX_GPMCON);
	tmp &= (~0xFFFF);
	tmp |= 0x1111;
	__raw_writel(tmp,S3C64XX_GPMCON);
	
	//gpm0-3 output 0
	tmp = __raw_readl(S3C64XX_GPMDAT);
	tmp |= 0x10;
	__raw_writel(tmp,S3C64XX_GPMDAT);

	//printk("S3C64XX_GPMCON is %x\n",__raw_readl(S3C64XX_GPMCON));
	//printk("S3C64XX_GPMDAT is %x\n",__raw_readl(S3C64XX_GPMDAT));
	//printk("S3C64XX_GPMPUD is %x\n",__raw_readl(S3C64XX_GPMPUD));

	printk(DEVICE_NAME " initialized\n");

	return 0;
}

static void __exit s3c6410_leds_exit(void)
{
	cdev_del(&cdev_leds);

	unregister_chrdev_region(MKDEV(LED_MAJOR,0),1);

	printk(KERN_NOTICE "s3c2440_leds_exit\n");
}


module_init(s3c6410_leds_init);
module_exit(s3c6410_leds_exit);

MODULE_LICENSE("GPL");



 一、模組相關標頭檔案:

1、#include <Linux/module.h>:在編寫任何模組都需要包含此標頭檔案。該標頭檔案自動包含了 <linux/version.h>標頭檔案,該標頭檔案包含了巨集MODULE_LICENSE("GPL")的定義。
2、#include <linux/init.h>:此標頭檔案也是必須的,module_init()與module_exit()巨集就是定義在它裡面的。而且正是這個標頭檔案定義了初始化函式加__init和推出函式加__exit的作用(static int __init s3c6410_leds_init(void)和static void __exit s3c6410_leds_exit(void))
3、#include <linux/kernel.h>:此標頭檔案也是常用標頭檔案,如果需要使用printk函式,則必須包含此標頭檔案。另外該標頭檔案還包含了<types.h>標頭檔案,而這個標頭檔案定義許多常用的資料型別,其中就包括裝置號型別dev_t。如下:

[cpp] view plain copy print?
  1. #ifndef _LINUX_TYPES_H
  2. #define _LINUX_TYPES_H
  3. #ifdef  __KERNEL__
  4. #define DECLARE_BITMAP(name,bits) \
  5.     unsigned long name[BITS_TO_LONGS(bits)]  
  6. #endif
  7. #include <linux/posix_types.h>
  8. #include <asm/types.h>
  9. #ifndef __KERNEL_STRICT_NAMES
  10. typedef __u32 __kernel_dev_t;  
  11. typedef __kernel_fd_set     fd_set;  
  12. typedef __kernel_dev_t      dev_t;  
  13. typedef __kernel_ino_t      ino_t;  
  14. typedef __kernel_mode_t     mode_t;  
  15. typedef __kernel_nlink_t    nlink_t;  
  16. typedef __kernel_off_t      off_t;  
  17. typedef __kernel_pid_t      pid_t;  
  18. typedef __kernel_daddr_t    daddr_t;  
  19. typedef __kernel_key_t      key_t;  
  20. typedef __kernel_suseconds_t    suseconds_t;  
  21. typedef __kernel_timer_t    timer_t;  
  22. typedef __kernel_clockid_t  clockid_t;  
  23. typedef __kernel_mqd_t      mqd_t;  
  24. #ifdef __KERNEL__
  25. typedef _Bool           bool;  
  26. typedef __kernel_uid32_t    uid_t;  
  27. typedef __kernel_gid32_t    gid_t;  
  28. typedef __kernel_uid16_t        uid16_t;  
  29. typedef __kernel_gid16_t        gid16_t;  
  30. typedef unsigned longuintptr_t;  
  31. #ifdef CONFIG_UID16
  32. /* This is defined by include/asm-{arch}/posix_types.h */
  33. typedef __kernel_old_uid_t  old_uid_t;  
  34. typedef __kernel_old_gid_t  old_gid_t;  
  35. #endif /* CONFIG_UID16 */
  36. /* libc5 includes this file to define uid_t, thus uid_t can never change 
  37.  * when it is included by non-kernel code 
  38.  */
  39. #else
  40. typedef __kernel_uid_t      uid_t;  
  41. typedef __kernel_gid_t      gid_t;  
  42. #endif /* __KERNEL__ */
  43. #if defined(__GNUC__)
  44. typedef __kernel_loff_t     loff_t;  
  45. #endif
  46. /* 
  47.  * The following typedefs are also protected by individual ifdefs for 
  48.  * historical reasons: 
  49.  */
  50. #ifndef _SIZE_T
  51. #define _SIZE_T
  52. typedef __kernel_size_t     size_t;  
  53. #endif
  54. #ifndef _SSIZE_T
  55. #define _SSIZE_T
  56. typedef __kernel_ssize_t    ssize_t;  
  57. #endif
  58. #ifndef _PTRDIFF_T
  59. #define _PTRDIFF_T
  60. typedef __kernel_ptrdiff_t  ptrdiff_t;  
  61. #endif
  62. #ifndef _TIME_T
  63. #define _TIME_T
  64. typedef __kernel_time_t     time_t;  
  65. #endif
  66. #ifndef _CLOCK_T
  67. #define _CLOCK_T
  68. typedef __kernel_clock_t    clock_t;  
  69. #endif
  70. #ifndef _CADDR_T
  71. #define _CADDR_T
  72. typedef __kernel_caddr_t    caddr_t;  
  73. #endif
  74. /* bsd */
  75. typedef unsigned char       u_char;  
  76. typedef unsigned short      u_short;  
  77. typedef unsigned int        u_int;  
  78. typedef unsigned long       u_long;  
  79. /* sysv */
  80. typedef unsigned char       unchar;  
  81. typedef unsigned short      ushort;  
  82. typedef unsigned int        uint;  
  83. typedef unsigned long       ulong;  
  84. #ifndef __BIT_TYPES_DEFINED__
  85. #define __BIT_TYPES_DEFINED__
  86. typedef     __u8        u_int8_t;  
  87. typedef     __s8        int8_t;  
  88. typedef     __u16       u_int16_t;  
  89. typedef     __s16       int16_t;  
  90. typedef     __u32       u_int32_t;  
  91. typedef     __s32       int32_t;  
  92. #endif /* !(__BIT_TYPES_DEFINED__) */
  93. typedef     __u8        uint8_t;  
  94. typedef     __u16       uint16_t;  
  95. typedef     __u32       uint32_t;  
  96. #if defined(__GNUC__)
  97. typedef     __u64       uint64_t;  
  98. typedef     __u64       u_int64_t;  
  99. typedef     __s64       int64_t;  
  100. #endif
  101. /* this is a special 64bit data type that is 8-byte aligned */
  102. #define aligned_u64 __u64 __attribute__((aligned(8)))
  103. #define aligned_be64 __be64 __attribute__((aligned(8)))
  104. #define aligned_le64 __le64 __attribute__((aligned(8)))
  105. /** 
  106.  * The type used for indexing onto a disc or disc partition. 
  107.  * 
  108.  * Linux always considers sectors to be 512 bytes long independently 
  109.  * of the devices real block size. 
  110.  */
  111. #ifdef CONFIG_LBD
  112. typedef u64 sector_t;  
  113. #else
  114. typedef unsigned long sector_t;  
  115. #endif
  116. /* 
  117.  * The type of the inode's block count. 
  118.  */
  119. #ifdef CONFIG_LSF
  120. typedef u64 blkcnt_t;  
  121. #else
  122. typedef unsigned long blkcnt_t;  
  123. #endif
  124. /* 
  125.  * The type of an index into the pagecache.  Use a #define so asm/types.h 
  126.  * can override it. 
  127.  */
  128. #ifndef pgoff_t
  129. #define pgoff_t unsigned long
  130. #endif
  131. #endif /* __KERNEL_STRICT_NAMES */
  132. /* 
  133.  * Below are truly Linux-specific types that should never collide with 
  134.  * any application/library that wants linux/types.h. 
  135.  */
  136. #ifdef __CHECKER__
  137. #define __bitwise__ __attribute__((bitwise))
  138. #else
  139. #define __bitwise__
  140. #endif
  141. #ifdef __CHECK_ENDIAN__
  142. #define __bitwise __bitwise__
  143. #else
  144. #define __bitwise
  145. #endif
  146. typedef __u16 __bitwise __le16;  
  147. typedef __u16 __bitwise __be16;  
  148. typedef __u32 __bitwise __le32;  
  149. typedef __u32 __bitwise __be32;  
  150. #if defined(__GNUC__)
  151. typedef __u64 __bitwise __le64;  
  152. typedef __u64 __bitwise __be64;  
  153. #endif
  154. typedef __u16 __bitwise __sum16;  
  155. typedef __u32 __bitwise __wsum;  
  156. #ifdef __KERNEL__
  157. typedef unsigned __bitwise__ gfp_t;  
  158. typedef unsigned __bitwise__ fmode_t;  
  159. #ifdef CONFIG_PHYS_ADDR_T_64BIT
  160. typedef u64 phys_addr_t;  
  161. #else
  162. typedef u32 phys_addr_t;  
  163. #endif
  164. typedef phys_addr_t resource_size_t;  
  165. struct ustat {  
  166.     __kernel_daddr_t    f_tfree;  
  167.     __kernel_ino_t      f_tinode;  
  168.     char            f_fname[6];  
  169.     char            f_fpack[6];  
  170. };  
  171. #endif  /* __KERNEL__ */
  172. #endif /* _LINUX_TYPES_H */
#ifndef _LINUX_TYPES_H
#define _LINUX_TYPES_H

#ifdef	__KERNEL__

#define DECLARE_BITMAP(name,bits) \
	unsigned long name[BITS_TO_LONGS(bits)]

#endif

#include <linux/posix_types.h>
#include <asm/types.h>

#ifndef __KERNEL_STRICT_NAMES

typedef __u32 __kernel_dev_t;

typedef __kernel_fd_set		fd_set;
typedef __kernel_dev_t		dev_t;
typedef __kernel_ino_t		ino_t;
typedef __kernel_mode_t		mode_t;
typedef __kernel_nlink_t	nlink_t;
typedef __kernel_off_t		off_t;
typedef __kernel_pid_t		pid_t;
typedef __kernel_daddr_t	daddr_t;
typedef __kernel_key_t		key_t;
typedef __kernel_suseconds_t	suseconds_t;
typedef __kernel_timer_t	timer_t;
typedef __kernel_clockid_t	clockid_t;
typedef __kernel_mqd_t		mqd_t;

#ifdef __KERNEL__
typedef _Bool			bool;

typedef __kernel_uid32_t	uid_t;
typedef __kernel_gid32_t	gid_t;
typedef __kernel_uid16_t        uid16_t;
typedef __kernel_gid16_t        gid16_t;

typedef unsigned long		uintptr_t;

#ifdef CONFIG_UID16
/* This is defined by include/asm-{arch}/posix_types.h */
typedef __kernel_old_uid_t	old_uid_t;
typedef __kernel_old_gid_t	old_gid_t;
#endif /* CONFIG_UID16 */

/* libc5 includes this file to define uid_t, thus uid_t can never change
 * when it is included by non-kernel code
 */
#else
typedef __kernel_uid_t		uid_t;
typedef __kernel_gid_t		gid_t;
#endif /* __KERNEL__ */

#if defined(__GNUC__)
typedef __kernel_loff_t		loff_t;
#endif

/*
 * The following typedefs are also protected by individual ifdefs for
 * historical reasons:
 */
#ifndef _SIZE_T
#define _SIZE_T
typedef __kernel_size_t		size_t;
#endif

#ifndef _SSIZE_T
#define _SSIZE_T
typedef __kernel_ssize_t	ssize_t;
#endif

#ifndef _PTRDIFF_T
#define _PTRDIFF_T
typedef __kernel_ptrdiff_t	ptrdiff_t;
#endif

#ifndef _TIME_T
#define _TIME_T
typedef __kernel_time_t		time_t;
#endif

#ifndef _CLOCK_T
#define _CLOCK_T
typedef __kernel_clock_t	clock_t;
#endif

#ifndef _CADDR_T
#define _CADDR_T
typedef __kernel_caddr_t	caddr_t;
#endif

/* bsd */
typedef unsigned char		u_char;
typedef unsigned short		u_short;
typedef unsigned int		u_int;
typedef unsigned long		u_long;

/* sysv */
typedef unsigned char		unchar;
typedef unsigned short		ushort;
typedef unsigned int		uint;
typedef unsigned long		ulong;

#ifndef __BIT_TYPES_DEFINED__
#define __BIT_TYPES_DEFINED__

typedef		__u8		u_int8_t;
typedef		__s8		int8_t;
typedef		__u16		u_int16_t;
typedef		__s16		int16_t;
typedef		__u32		u_int32_t;
typedef		__s32		int32_t;

#endif /* !(__BIT_TYPES_DEFINED__) */

typedef		__u8		uint8_t;
typedef		__u16		uint16_t;
typedef		__u32		uint32_t;

#if defined(__GNUC__)
typedef		__u64		uint64_t;
typedef		__u64		u_int64_t;
typedef		__s64		int64_t;
#endif

/* this is a special 64bit data type that is 8-byte aligned */
#define aligned_u64 __u64 __attribute__((aligned(8)))
#define aligned_be64 __be64 __attribute__((aligned(8)))
#define aligned_le64 __le64 __attribute__((aligned(8)))

/**
 * The type used for indexing onto a disc or disc partition.
 *
 * Linux always considers sectors to be 512 bytes long independently
 * of the devices real block size.
 */
#ifdef CONFIG_LBD
typedef u64 sector_t;
#else
typedef unsigned long sector_t;
#endif

/*
 * The type of the inode's block count.
 */
#ifdef CONFIG_LSF
typedef u64 blkcnt_t;
#else
typedef unsigned long blkcnt_t;
#endif

/*
 * The type of an index into the pagecache.  Use a #define so asm/types.h
 * can override it.
 */
#ifndef pgoff_t
#define pgoff_t unsigned long
#endif

#endif /* __KERNEL_STRICT_NAMES */

/*
 * Below are truly Linux-specific types that should never collide with
 * any application/library that wants linux/types.h.
 */

#ifdef __CHECKER__
#define __bitwise__ __attribute__((bitwise))
#else
#define __bitwise__
#endif
#ifdef __CHECK_ENDIAN__
#define __bitwise __bitwise__
#else
#define __bitwise
#endif

typedef __u16 __bitwise __le16;
typedef __u16 __bitwise __be16;
typedef __u32 __bitwise __le32;
typedef __u32 __bitwise __be32;
#if defined(__GNUC__)
typedef __u64 __bitwise __le64;
typedef __u64 __bitwise __be64;
#endif
typedef __u16 __bitwise __sum16;
typedef __u32 __bitwise __wsum;

#ifdef __KERNEL__
typedef unsigned __bitwise__ gfp_t;
typedef unsigned __bitwise__ fmode_t;

#ifdef CONFIG_PHYS_ADDR_T_64BIT
typedef u64 phys_addr_t;
#else
typedef u32 phys_addr_t;
#endif

typedef phys_addr_t resource_size_t;

struct ustat {
	__kernel_daddr_t	f_tfree;
	__kernel_ino_t		f_tinode;
	char			f_fname[6];
	char			f_fpack[6];
};

#endif	/* __KERNEL__ */

#endif /* _LINUX_TYPES_H */




二、字元裝置驅動相關標頭檔案:
1、#include <linux/fs.h>:該標頭檔案包含了常用的資料結構,當然也包括三種最重要的:struct file、struct file_operation、struct inode。另外該標頭檔案還包含了<linux/ioctl.h>標頭檔案。
2、#include <linux/cdev.h>:該標頭檔案定義了struct cdev資料結構,也包含了字元裝置操作的相關函式:

[cpp] view plain copy print?
  1. #ifndef _LINUX_CDEV_H
  2. #define _LINUX_CDEV_H
  3. #include <linux/kobject.h>
  4. #include <linux/kdev_t.h>
  5. #include <linux/list.h>
  6. struct file_operations;  
  7. struct inode;  
  8. struct module;  
  9. struct cdev {  
  10.     struct kobject kobj;  
  11.     struct module *owner;  
  12.     conststruct file_operations *ops;  
  13.     struct list_head list;  
  14.     dev_t dev;  
  15.     unsigned int count;  
  16. };  
  17. void cdev_init(struct cdev *, conststruct file_operations *);  
  18. struct cdev *cdev_alloc(void);  
  19. void cdev_put(struct cdev *p);  
  20. int cdev_add(struct cdev *, dev_t, unsigned);  
  21. void cdev_del(struct cdev *);  
  22. void cd_forget(struct inode *);  
  23. externstruct backing_dev_info directly_mappable_cdev_bdi;  
  24. #endif
#ifndef _LINUX_CDEV_H
#define _LINUX_CDEV_H

#include <linux/kobject.h>
#include <linux/kdev_t.h>
#include <linux/list.h>

struct file_operations;
struct inode;
struct module;

struct cdev {
	struct kobject kobj;
	struct module *owner;
	const struct file_operations *ops;
	struct list_head list;
	dev_t dev;
	unsigned int count;
};

void cdev_init(struct cdev *, const struct file_operations *);

struct cdev *cdev_alloc(void);

void cdev_put(struct cdev *p);

int cdev_add(struct cdev *, dev_t, unsigned);

void cdev_del(struct cdev *);

void cd_forget(struct inode *);

extern struct backing_dev_info directly_mappable_cdev_bdi;

#endif


3、<linux/device.h>:包含自動建立裝置檔案的相關函式的申明:原函式中-class_create(THIS_MODULE,"my_class")、device_create(my_class,NULL,MKDEV(LED_MAJOR,0),NULL,DEVICE_NAME)。


三、s3c64xx  GPIO操作相關標頭檔案:
1、#include <mach/gpio.h>:此標頭檔案包含了對S3C64xx 各個GPIO的巨集定義,幷包含了各個埠的讀寫函式,如下:

[cpp] view plain copy print?
  1. /* linux/arch/arm/mach-s3c6400/include/mach/gpio.h 
  2.  * 
  3.  * Copyright 2008 Openmoko, Inc. 
  4.  * Copyright 2008 Simtec Electronics 
  5.  *  http://armlinux.simtec.co.uk/ 
  6.  *  Ben Dooks <[email protected]> 
  7.  * 
  8.  * S3C6400 - GPIO lib support 
  9.  * 
  10.  * This program is free software; you can redistribute it and/or modify 
  11.  * it under the terms of the GNU General Public License version 2 as 
  12.  * published by the Free Software Foundation. 
  13. */
  14. #define gpio_get_value  __gpio_get_value
  15. #define gpio_set_value  __gpio_set_value
  16. #define gpio_cansleep   __gpio_cansleep
  17. #define gpio_to_irq __gpio_to_irq
  18. /* GPIO bank sizes */
  19. #define S3C64XX_GPIO_A_NR   (8)
  20. #define S3C64XX_GPIO_B_NR   (7)
  21. #define S3C64XX_GPIO_C_NR   (8)
  22. #define S3C64XX_GPIO_D_NR   (5)
  23. #define S3C64XX_GPIO_E_NR   (5)
  24. #define S3C64XX_GPIO_F_NR   (16)
  25. #define S3C64XX_GPIO_G_NR   (7)
  26. #define S3C64XX_GPIO_H_NR   (10)
  27. #define S3C64XX_GPIO_I_NR   (16)
  28. #define S3C64XX_GPIO_J_NR   (12)
  29. #define S3C64XX_GPIO_K_NR   (16)
  30. #define S3C64XX_GPIO_L_NR   (15)
  31. #define S3C64XX_GPIO_M_NR   (6)
  32. #define S3C64XX_GPIO_N_NR   (16)
  33. #define S3C64XX_GPIO_O_NR   (16)
  34. #define S3C64XX_GPIO_P_NR   (15)
  35. #define S3C64XX_GPIO_Q_NR   (9)
  36. /* GPIO bank numbes */
  37. /* CONFIG_S3C_GPIO_SPACE allows the user to select extra 
  38.  * space for debugging purposes so that any accidental 
  39.  * change from one gpio bank to another can be caught. 
  40. */
  41. #define S3C64XX_GPIO_NEXT(__gpio) \
  42.     ((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)  
  43. enum s3c_gpio_number {  
  44.     S3C64XX_GPIO_A_START = 0,  
  45.     S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A),  
  46.     S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B),  
  47.     S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C),  
  48.     S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D),  
  49.     S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E),  
  50.     S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F),  
  51.     S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G),  
  52.     S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H),  
  53.     S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I),  
  54.     S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J),  
  55.     S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K),  
  56.     S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L),  
  57.     S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M),  
  58.     S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N),  
  59.     S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O),  
  60.     S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P),  
  61. };  
  62. /* S3C64XX GPIO number definitions. */
  63. #define S3C64XX_GPA(_nr)    (S3C64XX_GPIO_A_START + (_nr))
  64. #define S3C64XX_GPB(_nr)    (S3C64XX_GPIO_B_START + (_nr))
  65. #define S3C64XX_GPC(_nr)    (S3C64XX_GPIO_C_START + (_nr))
  66. #define S3C64XX_GPD(_nr)    (S3C64XX_GPIO_D_START + (_nr))
  67. #define S3C64XX_GPE(_nr)    (S3C64XX_GPIO_E_START + (_nr))
  68. #define S3C64XX_GPF(_nr)    (S3C64XX_GPIO_F_START + (_nr))
  69. #define S3C64XX_GPG(_nr)    (S3C64XX_GPIO_G_START + (_nr))
  70. #define S3C64XX_GPH(_nr)    (S3C64XX_GPIO_H_START + (_nr))
  71. #define S3C64XX_GPI(_nr)    (S3C64XX_GPIO_I_START + (_nr))
  72. #define S3C64XX_GPJ(_nr)    (S3C64XX_GPIO_J_START + (_nr))
  73. #define S3C64XX_GPK(_nr)    (S3C64XX_GPIO_K_START + (_nr))
  74. #define S3C64XX_GPL(_nr)    (S3C64XX_GPIO_L_START + (_nr))
  75. #define S3C64XX_GPM(_nr)    (S3C64XX_GPIO_M_START + (_nr))
  76. #define S3C64XX_GPN(_nr)    (S3C64XX_GPIO_N_START + (_nr))
  77. #define S3C64XX_GPO(_nr)    (S3C64XX_GPIO_O_START + (_nr))
  78. #define S3C64XX_GPP(_nr)    (S3C64XX_GPIO_P_START + (_nr))
  79. #define S3C64XX_GPQ(_nr)    (S3C64XX_GPIO_Q_START + (_nr))
  80. /* the end of the S3C64XX specific gpios */
  81. #define S3C64XX_GPIO_END    (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
  82. #define S3C_GPIO_END        S3C64XX_GPIO_END
  83. /* define the number of gpios we need to the one after the GPQ() range */
  84. #define ARCH_NR_GPIOS   (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
  85. #include <asm-generic/gpio.h>
/* linux/arch/arm/mach-s3c6400/include/mach/gpio.h
 *
 * Copyright 2008 Openmoko, Inc.
 * Copyright 2008 Simtec Electronics
 *	http://armlinux.simtec.co.uk/
 *	Ben Dooks <[email protected]>
 *
 * S3C6400 - GPIO lib support
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
*/

#define gpio_get_value	__gpio_get_value
#define gpio_set_value	__gpio_set_value
#define gpio_cansleep	__gpio_cansleep
#define gpio_to_irq	__gpio_to_irq

/* GPIO bank sizes */
#define S3C64XX_GPIO_A_NR	(8)
#define S3C64XX_GPIO_B_NR	(7)
#define S3C64XX_GPIO_C_NR	(8)
#define S3C64XX_GPIO_D_NR	(5)
#define S3C64XX_GPIO_E_NR	(5)
#define S3C64XX_GPIO_F_NR	(16)
#define S3C64XX_GPIO_G_NR	(7)
#define S3C64XX_GPIO_H_NR	(10)
#define S3C64XX_GPIO_I_NR	(16)
#define S3C64XX_GPIO_J_NR	(12)
#define S3C64XX_GPIO_K_NR	(16)
#define S3C64XX_GPIO_L_NR	(15)
#define S3C64XX_GPIO_M_NR	(6)
#define S3C64XX_GPIO_N_NR	(16)
#define S3C64XX_GPIO_O_NR	(16)
#define S3C64XX_GPIO_P_NR	(15)
#define S3C64XX_GPIO_Q_NR	(9)

/* GPIO bank numbes */

/* CONFIG_S3C_GPIO_SPACE allows the user to select extra
 * space for debugging purposes so that any accidental
 * change from one gpio bank to another can be caught.
*/

#define S3C64XX_GPIO_NEXT(__gpio) \
	((__gpio##_START) + (__gpio##_NR) + CONFIG_S3C_GPIO_SPACE + 1)

enum s3c_gpio_number {
	S3C64XX_GPIO_A_START = 0,
	S3C64XX_GPIO_B_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_A),
	S3C64XX_GPIO_C_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_B),
	S3C64XX_GPIO_D_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_C),
	S3C64XX_GPIO_E_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_D),
	S3C64XX_GPIO_F_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_E),
	S3C64XX_GPIO_G_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_F),
	S3C64XX_GPIO_H_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_G),
	S3C64XX_GPIO_I_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_H),
	S3C64XX_GPIO_J_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_I),
	S3C64XX_GPIO_K_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_J),
	S3C64XX_GPIO_L_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_K),
	S3C64XX_GPIO_M_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_L),
	S3C64XX_GPIO_N_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_M),
	S3C64XX_GPIO_O_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_N),
	S3C64XX_GPIO_P_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_O),
	S3C64XX_GPIO_Q_START = S3C64XX_GPIO_NEXT(S3C64XX_GPIO_P),
};

/* S3C64XX GPIO number definitions. */

#define S3C64XX_GPA(_nr)	(S3C64XX_GPIO_A_START + (_nr))
#define S3C64XX_GPB(_nr)	(S3C64XX_GPIO_B_START + (_nr))
#define S3C64XX_GPC(_nr)	(S3C64XX_GPIO_C_START + (_nr))
#define S3C64XX_GPD(_nr)	(S3C64XX_GPIO_D_START + (_nr))
#define S3C64XX_GPE(_nr)	(S3C64XX_GPIO_E_START + (_nr))
#define S3C64XX_GPF(_nr)	(S3C64XX_GPIO_F_START + (_nr))
#define S3C64XX_GPG(_nr)	(S3C64XX_GPIO_G_START + (_nr))
#define S3C64XX_GPH(_nr)	(S3C64XX_GPIO_H_START + (_nr))
#define S3C64XX_GPI(_nr)	(S3C64XX_GPIO_I_START + (_nr))
#define S3C64XX_GPJ(_nr)	(S3C64XX_GPIO_J_START + (_nr))
#define S3C64XX_GPK(_nr)	(S3C64XX_GPIO_K_START + (_nr))
#define S3C64XX_GPL(_nr)	(S3C64XX_GPIO_L_START + (_nr))
#define S3C64XX_GPM(_nr)	(S3C64XX_GPIO_M_START + (_nr))
#define S3C64XX_GPN(_nr)	(S3C64XX_GPIO_N_START + (_nr))
#define S3C64XX_GPO(_nr)	(S3C64XX_GPIO_O_START + (_nr))
#define S3C64XX_GPP(_nr)	(S3C64XX_GPIO_P_START + (_nr))
#define S3C64XX_GPQ(_nr)	(S3C64XX_GPIO_Q_START + (_nr))

/* the end of the S3C64XX specific gpios */
#define S3C64XX_GPIO_END	(S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)
#define S3C_GPIO_END		S3C64XX_GPIO_END

/* define the number of gpios we need to the one after the GPQ() range */
#define ARCH_NR_GPIOS	(S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1)

#include <asm-generic/gpio.h>

上面的標頭檔案包含了<asm-generic/gpio.h>標頭檔案,該標頭檔案包含了GPIO的資料讀寫函式,如下:

[cpp] view plain copy print?
  1. #ifndef _ASM_GENERIC_GPIO_H
  2. #define _ASM_GENERIC_GPIO_H
  3. #include <linux/types.h>
  4. #include <linux/errno.h>
  5. #ifdef CONFIG_GPIOLIB
  6. #include <linux/compiler.h>
  7. /* Platforms may implement their GPIO interface with library code,