LED驱动GPIO相关头文件简要分析

2023-11-10

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
                                《常识》  
¥应用程序----->系统内核----->设备驱动----->硬件设备  
¥设备驱动既是系统内核的下属,又是硬件设备的老大。    
¥在inux系统中用一个文件来代表一个设备。这个文件就叫设备文件。设备驱动的责任是将应用程序对设备文件  
的打开、读、写、定位等操作转化为对硬件设备的打开、读、写、定位等操作。而对于任何硬件设备,应用程序  
只需利用这些基本操作就可以完全控制它!  
¥编写linux设备驱动需要的知识结构:  
1、40%的设计模式相关知识。设计模式是系统内核限定的,做别人的下属就得按照别人的规矩办事。  
2、30%的内核工作原理相关知识。内核是你领导,领会领导意图才能把事情办好。  
3、30%的硬件相关知识。控制好硬件是你的的本质工作,你得把你的小弟管理好.  
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 



在简要介绍了led驱动相关头文件的基础上(参考:点击打开链接),可以发现这些头文件里面包含了很多gpio的宏定义和gpio的操作函数。利用这些宏定义和操作函数,我们就能够很好地控制gpio以达到我们的目的。GPIO相关的的头文件包括<mach/gpio.h>、<plat/regs-gpio.h>和<plat/gpio-cfg.h>。下面是对这些头文件进行简单的分析,如有不正确,希望留言指正:

一、<mach/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 <ben@simtec.co.uk> 
 * 
 * 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   //对gpio单个引脚的读函数进行了宏定义
#define gpio_set_value  __gpio_set_value   //对gpio单个引脚的写函数进行了宏定义
#define gpio_cansleep   __gpio_cansleep   //???
#define gpio_to_irq __gpio_to_irq   //???
  
/* GPIO bank sizes */  
//这里对每个端口(gpioa--gpioq)的引脚个数进行了宏定义
#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)  
//用黏贴符号(双#号)来运算的,以A组的0起始,依次加每组的GPIO个数  
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)  
                                                                
//由上面的分析可知,这个头文件对s3c64xx系列的芯片的引脚进行了统一的编号,按GPA-->GPQ的顺序对给每个引脚编了个号。

#include <asm-generic/gpio.h> //这个头文件是包含在此文件中的,它里面包含了许多gpio的操作函数,而这些函数可以直接使用上述宏定义对具体的单个引脚进行操作,如下:

#ifndef _ASM_GENERIC_GPIO_H
#define _ASM_GENERIC_GPIO_H

#include <linux/types.h>
#include <linux/errno.h>

#ifdef CONFIG_GPIOLIB

#include <linux/compiler.h>

/* Platforms may implement their GPIO interface with library code,
 * at a small performance cost for non-inlined operations and some
 * extra memory (for code and for per-GPIO table entries).
 *
 * While the GPIO programming interface defines valid GPIO numbers
 * to be in the range 0..MAX_INT, this library restricts them to the
 * smaller range 0..ARCH_NR_GPIOS-1.
 */

#ifndef ARCH_NR_GPIOS
#define ARCH_NR_GPIOS		256
#endif

static inline int gpio_is_valid(int number)
{
	/* only some non-negative numbers are valid */
	return ((unsigned)number) < ARCH_NR_GPIOS;
}

struct seq_file;
struct module;

/**
 * struct gpio_chip - abstract a GPIO controller
 * @label: for diagnostics
 * @dev: optional device providing the GPIOs
 * @owner: helps prevent removal of modules exporting active GPIOs
 * @request: optional hook for chip-specific activation, such as
 *	enabling module power and clock; may sleep
 * @free: optional hook for chip-specific deactivation, such as
 *	disabling module power and clock; may sleep
 * @direction_input: configures signal "offset" as input, or returns error
 * @get: returns value for signal "offset"; for output signals this
 *	returns either the value actually sensed, or zero
 * @direction_output: configures signal "offset" as output, or returns error
 * @set: assigns output value for signal "offset"
 * @to_irq: optional hook supporting non-static gpio_to_irq() mappings;
 *	implementation may not sleep
 * @dbg_show: optional routine to show contents in debugfs; default code
 *	will be used when this is omitted, but custom code can show extra
 *	state (such as pullup/pulldown configuration).
 * @base: identifies the first GPIO number handled by this chip; or, if
 *	negative during registration, requests dynamic ID allocation.
 * @ngpio: the number of GPIOs handled by this controller; the last GPIO
 *	handled is (base + ngpio - 1).
 * @can_sleep: flag must be set iff get()/set() methods sleep, as they
 *	must while accessing GPIO expander chips over I2C or SPI
 *
 * A gpio_chip can help platforms abstract various sources of GPIOs so
 * they can all be accessed through a common programing interface.
 * Example sources would be SOC controllers, FPGAs, multifunction
 * chips, dedicated GPIO expanders, and so on.
 *
 * Each chip controls a number of signals, identified in method calls
 * by "offset" values in the range 0..(@ngpio - 1).  When those signals
 * are referenced through calls like gpio_get_value(gpio), the offset
 * is calculated by subtracting @base from the gpio number.
 */
struct gpio_chip {
	const char		*label;
	struct device		*dev;
	struct module		*owner;

	int			(*request)(struct gpio_chip *chip,
						unsigned offset);
	void			(*free)(struct gpio_chip *chip,
						unsigned offset);

	int			(*direction_input)(struct gpio_chip *chip,
						unsigned offset);
	int			(*get)(struct gpio_chip *chip,
						unsigned offset);
	int			(*direction_output)(struct gpio_chip *chip,
						unsigned offset, int value);
	void			(*set)(struct gpio_chip *chip,
						unsigned offset, int value);

	int			(*to_irq)(struct gpio_chip *chip,
						unsigned offset);

	void			(*dbg_show)(struct seq_file *s,
						struct gpio_chip *chip);
	int			base;
	u16			ngpio;
	unsigned		can_sleep:1;
	unsigned		exported:1;
};

extern const char *gpiochip_is_requested(struct gpio_chip *chip,
			unsigned offset);
extern int __must_check gpiochip_reserve(int start, int ngpio);

/* add/remove chips */
extern int gpiochip_add(struct gpio_chip *chip);
extern int __must_check gpiochip_remove(struct gpio_chip *chip);


/* Always use the library code for GPIO management calls,
 * or when sleeping may be involved.
 */
extern int gpio_request(unsigned gpio, const char *label);
//通过查看该gpio保存的记录标志是否为NULL来判断GPIO是否被占用,并为它去个*lable 
//例如:if(gpio_request(S3C64XX_GPB(0), "GPB"))

extern void gpio_free(unsigned gpio);
//释放gpio,就是把对应GPIO口的控制标志FLAG_REQUESTED清掉,成NULL,之后可以再被其他调用。

extern int gpio_direction_input(unsigned gpio);
//将gpio配置成输入模式
extern int gpio_direction_output(unsigned gpio, int value);
//将gpio配置成输出模式,并且将gpio置为value,
//例如:gpio_direction_output (S3C64XX_GPB(0), 1)

extern int gpio_get_value_cansleep(unsigned gpio);//???
extern void gpio_set_value_cansleep(unsigned gpio, int value);//???


/* A platform's <asm/gpio.h> code may want to inline the I/O calls when
 * the GPIO is constant and refers to some always-present controller,
 * giving direct access to chip registers and tight bitbanging loops.
 */
extern int __gpio_get_value(unsigned gpio);
//读取gpio的值
extern void __gpio_set_value(unsigned gpio, int value);
//设置gpio的值为value

extern int __gpio_cansleep(unsigned gpio);//???

extern int __gpio_to_irq(unsigned gpio);///???

#ifdef CONFIG_GPIO_SYSFS

/*
 * A sysfs interface can be exported by individual drivers if they want,
 * but more typically is configured entirely from userspace.
 */
extern int gpio_export(unsigned gpio, bool direction_may_change);
extern void gpio_unexport(unsigned gpio);

#endif	/* CONFIG_GPIO_SYSFS */

#else	/* !CONFIG_HAVE_GPIO_LIB */

static inline int gpio_is_valid(int number)
{
	/* only non-negative numbers are valid */
	return number >= 0;
}

/* platforms that don't directly support access to GPIOs through I2C, SPI,
 * or other blocking infrastructure can use these wrappers.
 */

static inline int gpio_cansleep(unsigned gpio)
{
	return 0;
}

static inline int gpio_get_value_cansleep(unsigned gpio)
{
	might_sleep();
	return gpio_get_value(gpio);
}

static inline void gpio_set_value_cansleep(unsigned gpio, int value)
{
	might_sleep();
	gpio_set_value(gpio, value);
}

#endif /* !CONFIG_HAVE_GPIO_LIB */

#ifndef CONFIG_GPIO_SYSFS

/* sysfs support is only available with gpiolib, where it's optional */

static inline int gpio_export(unsigned gpio, bool direction_may_change)
{
	return -ENOSYS;
}

static inline void gpio_unexport(unsigned gpio)
{
}
#endif	/* CONFIG_GPIO_SYSFS */

#endif /* _ASM_GENERIC_GPIO_H */



二、<plat/regs-gpio.h>头文件:

/* linux/arch/arm/plat-s3c64xx/include/plat/regs-gpio.h 
 * 
 * Copyright 2008 Openmoko, Inc. 
 * Copyright 2008 Simtec Electronics 
 *      Ben Dooks <ben@simtec.co.uk> 
 *      http://armlinux.simtec.co.uk/ 
 * 
 * S3C64XX - GPIO register definitions 
 */  
  
#ifndef __ASM_PLAT_S3C64XX_REGS_GPIO_H   
#define __ASM_PLAT_S3C64XX_REGS_GPIO_H __FILE__   
//这里包含了从a-q的相关头文件,这些头文件里分别是gpa-gpq相关的宏,
//以下只列出<plat/gpio-bank-m.h>中的内容 
#include <plat/gpio-bank-a.h>   
#include <plat/gpio-bank-b.h>   
#include <plat/gpio-bank-c.h>   
#include <plat/gpio-bank-d.h>   
#include <plat/gpio-bank-e.h>   
#include <plat/gpio-bank-f.h>   
#include <plat/gpio-bank-g.h>   
#include <plat/gpio-bank-h.h>   
#include <plat/gpio-bank-i.h>   
#include <plat/gpio-bank-j.h>   
#include <plat/gpio-bank-k.h>   
#include <plat/gpio-bank-l.h>
#include <plat/gpio-bank-m.h>   
#include <plat/gpio-bank-n.h>   
#include <plat/gpio-bank-q.h>   
#include <plat/gpio-bank-o.h>   
#include <plat/gpio-bank-p.h>   
#include <plat/gpio-bank-q.h>   
#include <mach/map.h>   
  
/* Base addresses for each of the banks */  

//由虚拟地址加偏移地址计算基地址。以GPM的基地址计算为例:
//gpm的虚拟地址是S3C64XX_VA_GPIO,定义在mach/map.h中:

//#define S3C64XX_VA_GPIO S3C_ADDR(0x00500000)
//S3C_ADDR(0x00500000)是定义在plat/map.h中的:

//#define S3C_ADDR(x) ((void __iomem __force *)S3C_ADDR_BASE+ (x))
//S3C_ADDR_BASE是全局虚拟地址,它的定义是:#define S3C_ADDR_BASE (0xF4000000)
//void __iomem __force *作用是强制转化为地址
//综合以上,GPM的宏S3C64XX_GPM_BASE展开的情形是:
//(0xF4000000+0x00500000)+ 0x0820 = 0xf4500820,括号里面的是虚拟地址,后面的是
//偏移量,查S3C6410的手册会发现这个地址刚好是GPMCON寄存器的地址!!!!!
#define S3C64XX_GPA_BASE    (S3C64XX_VA_GPIO + 0x0000)   
#define S3C64XX_GPB_BASE    (S3C64XX_VA_GPIO + 0x0020)   
#define S3C64XX_GPC_BASE    (S3C64XX_VA_GPIO + 0x0040)   
#define S3C64XX_GPD_BASE    (S3C64XX_VA_GPIO + 0x0060)   
#define S3C64XX_GPE_BASE    (S3C64XX_VA_GPIO + 0x0080)   
#define S3C64XX_GPF_BASE    (S3C64XX_VA_GPIO + 0x00A0)   
#define S3C64XX_GPG_BASE    (S3C64XX_VA_GPIO + 0x00C0)   
#define S3C64XX_GPH_BASE    (S3C64XX_VA_GPIO + 0x00E0)   
#define S3C64XX_GPI_BASE    (S3C64XX_VA_GPIO + 0x0100)   
#define S3C64XX_GPJ_BASE    (S3C64XX_VA_GPIO + 0x0120)   
#define S3C64XX_GPK_BASE    (S3C64XX_VA_GPIO + 0x0800)   
#define S3C64XX_GPL_BASE    (S3C64XX_VA_GPIO + 0x0810)   
#define S3C64XX_GPM_BASE    (S3C64XX_VA_GPIO + 0x0820)   
#define S3C64XX_GPN_BASE    (S3C64XX_VA_GPIO + 0x0830)   
#define S3C64XX_GPO_BASE    (S3C64XX_VA_GPIO + 0x0140)   
#define S3C64XX_GPP_BASE    (S3C64XX_VA_GPIO + 0x0160)   
#define S3C64XX_GPQ_BASE    (S3C64XX_VA_GPIO + 0x0180)   
#define S3C64XX_SPC_BASE    (S3C64XX_VA_GPIO + 0x01A0)   
#define S3C64XX_MEM0CONSTOP (S3C64XX_VA_GPIO + 0x01B0)   
#define S3C64XX_MEM1CONSTOP (S3C64XX_VA_GPIO + 0x01B4)   
#define S3C64XX_MEM0CONSLP0 (S3C64XX_VA_GPIO + 0x01C0)   
#define S3C64XX_MEM0CONSLP1 (S3C64XX_VA_GPIO + 0x01C4)   
#define S3C64XX_MEM1CONSLP  (S3C64XX_VA_GPIO + 0x01C8)   
#define S3C64XX_MEM0DRVCON  (S3C64XX_VA_GPIO + 0x01D0)   
#define S3C64XX_MEM1DRVCON  (S3C64XX_VA_GPIO + 0x01D4)   
#define S3C64XX_EINT0CON0   (S3C64XX_VA_GPIO + 0x0900)   
#define S3C64XX_EINT0CON1   (S3C64XX_VA_GPIO + 0x0904)   
#define S3C64XX_EINT0FLTCON0    (S3C64XX_VA_GPIO + 0x0910)   
#define S3C64XX_EINT0FLTCON1    (S3C64XX_VA_GPIO + 0x0914)   
#define S3C64XX_EINT0FLTCON2    (S3C64XX_VA_GPIO + 0x0918)   
#define S3C64XX_EINT0FLTCON3    (S3C64XX_VA_GPIO + 0x091C)   
#define S3C64XX_EINT0MASK   (S3C64XX_VA_GPIO + 0x0920)   
#define S3C64XX_EINT0PEND   (S3C64XX_VA_GPIO + 0x0924)   
#define S3C64XX_SPCONSLP    (S3C64XX_VA_GPIO + 0x0880)   
#define S3C64XX_SLPEN       (S3C64XX_VA_GPIO + 0x0930)   
#define S3C64XX_EINT12CON   (S3C64XX_VA_GPIO + 0x0200)   
#define S3C64XX_EINT34CON   (S3C64XX_VA_GPIO + 0x0204)   
#define S3C64XX_EINT56CON   (S3C64XX_VA_GPIO + 0x0208)   
#define S3C64XX_EINT78CON   (S3C64XX_VA_GPIO + 0x020C)   
#define S3C64XX_EINT9CON    (S3C64XX_VA_GPIO + 0x0210)   
#define S3C64XX_EINT12FLTCON    (S3C64XX_VA_GPIO + 0x0220)   
#define S3C64XX_EINT34FLTCON    (S3C64XX_VA_GPIO + 0x0224)   
#define S3C64XX_EINT56FLTCON    (S3C64XX_VA_GPIO + 0x0228)   
#define S3C64XX_EINT78FLTCON    (S3C64XX_VA_GPIO + 0x022C)   
#define S3C64XX_EINT9FLTCON (S3C64XX_VA_GPIO + 0x0230)   
#define S3C64XX_EINT12MASK  (S3C64XX_VA_GPIO + 0x0240)   
#define S3C64XX_EINT34MASK  (S3C64XX_VA_GPIO + 0x0244)   
#define S3C64XX_EINT56MASK  (S3C64XX_VA_GPIO + 0x0248)   
#define S3C64XX_EINT78MASK  (S3C64XX_VA_GPIO + 0x024C)   
#define S3C64XX_EINT9MASK   (S3C64XX_VA_GPIO + 0x0250)   
#define S3C64XX_EINT12PEND  (S3C64XX_VA_GPIO + 0x0260)   
#define S3C64XX_EINT34PEND  (S3C64XX_VA_GPIO + 0x0264)   
#define S3C64XX_EINT56PEND  (S3C64XX_VA_GPIO + 0x0268)   
#define S3C64XX_EINT78PEND  (S3C64XX_VA_GPIO + 0x026C)   
#define S3C64XX_EINT9PEND   (S3C64XX_VA_GPIO + 0x0270)   
#define S3C64XX_PRIORITY    (S3C64XX_VA_GPIO + 0x0280)   
#define S3C64XX_SERVICE     (S3C64XX_VA_GPIO + 0x0284)   
#define S3C64XX_SERVICEPEND (S3C64XX_VA_GPIO + 0x0288)   
  
/* values for S3C_EXTINT0 */  
#define S3C64XX_EXTINT_LOWLEV    (0x00)   
#define S3C64XX_EXTINT_HILEV     (0x01)   
#define S3C64XX_EXTINT_FALLEDGE  (0x02)   
#define S3C64XX_EXTINT_RISEEDGE  (0x04)   
#define S3C64XX_EXTINT_BOTHEDGE  (0x06)   
  
#endif /* __ASM_PLAT_S3C64XX_REGS_GPIO_H */  
以下仅列出<plat/gpio-bank-m.h>中的内容:
/* linux/arch/arm/plat-s3c64xx/include/plat/gpio-bank-m.h 
 * 
 * Copyright 2008 Openmoko, Inc. 
 * Copyright 2008 Simtec Electronics 
 *  Ben Dooks <ben@simtec.co.uk> 
 *  http://armlinux.simtec.co.uk/ 
 * 
 * GPIO Bank M register and configuration definitions 
 * 
 * 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 S3C64XX_GPMCON          (S3C64XX_GPM_BASE + 0x00)   
//经过上面的计算容易知道,这个宏就是GPMCON的地址
#define S3C64XX_GPMDAT          (S3C64XX_GPM_BASE + 0x04)   
//GPMDAT的地址
#define S3C64XX_GPMPUD          (S3C64XX_GPM_BASE + 0x08)   
//GPMPUD的地址
  
#define S3C64XX_GPM_CONMASK(__gpio) (0x3 << ((__gpio) * 2))   
#define S3C64XX_GPM_INPUT(__gpio)   (0x0 << ((__gpio) * 2))  
//输入的配置数据宏,将GPMCON与之按位与就能将gpio位配置为输入
#define S3C64XX_GPM_OUTPUT(__gpio)  (0x1 << ((__gpio) * 2)) 
//输出的配置数据宏,将GPMCON与之按位或就能将gpio位配置为输出 
  
#define S3C64XX_GPM0_HOSTIF_CS      (0x02 << 0)   
#define S3C64XX_GPM0_EINT23      (0x03 << 0)   
#define S3C64XX_GPM0_RESERVED1      (0x04 << 0)   
#define S3C64XX_GPM0_DATA_CF10      (0x05 << 0)   
#define S3C64XX_GPM0_CE_CF0      (0x06 << 0)   
#define S3C64XX_GPM0_RESERVED2      (0x07 << 0)   
  
#define S3C64XX_GPM1_HOSTIF_CS_M      (0x02 << 0)   
#define S3C64XX_GPM1_EINT24      (0x03 << 0)   
#define S3C64XX_GPM1_RESERVED1      (0x04 << 0)   
#define S3C64XX_GPM1_DATA_CF11      (0x05 << 0)   
#define S3C64XX_GPM1_CE_CF1      (0x06 << 0)   
#define S3C64XX_GPM1_RESERVED2      (0x07 << 0)   
  
#define S3C64XX_GPM2_HOSTIF_IF_CS_S      (0x02 << 0)   
#define S3C64XX_GPM2_EINT25      (0x03 << 0)   
#define S3C64XX_GPM2_HOSTIF_MDP_VSYNC      (0x04 << 0)   
#define S3C64XX_GPM2_DATA_CF12      (0x05 << 0)   
#define S3C64XX_GPM2_IORD_CF      (0x06 << 0)   
#define S3C64XX_GPM2_RESERVED2      (0x07 << 0)   
  
#define S3C64XX_GPM3_HOSTIF_WE      (0x02 << 0)   
#define S3C64XX_GPM3_EINT26      (0x03 << 0)   
#define S3C64XX_GPM3_RESERVED1      (0x04 << 0)   
#define S3C64XX_GPM3_DATA_CF13      (0x05 << 0)   
#define S3C64XX_GPM3_IOWR_CF      (0x06 << 0)   
#define S3C64XX_GPM3_RESERVED2      (0x07 << 0)   
  
#define S3C64XX_GPM4_HOSTIF_OE      (0x02 << 0)   
#define S3C64XX_GPM4_EINT27      (0x03 << 0)   
#define S3C64XX_GPM4_RESERVED1      (0x04 << 0)   
#define S3C64XX_GPM4_DATA_CF14      (0x05 << 0)   
#define S3C64XX_GPM4_IORDY_CF      (0x06 << 0)   
#define S3C64XX_GPM4_RESERVED2      (0x07 << 0)   
  
#define S3C64XX_GPM5_HOSTIF_INTR      (0x02 << 0)   
#define S3C64XX_GPM5_CF_DATA_DIR      (0x03 << 0)   
#define S3C64XX_GPM5_RESERVED1      (0x04 << 0)   
#define S3C64XX_GPM5_DATA_CF15      (0x05 << 0)   
#define S3C64XX_GPM5_RESERVED2      (0x06 << 0)   
#define S3C64XX_GPM5_RESERVED3      (0x07 << 0)
 
三、<plat/gpio-cfg.h>头文件:
/* linux/arch/arm/plat-s3c/include/plat/gpio-cfg.h 
 * 
 * Copyright 2008 Openmoko, Inc. 
 * Copyright 2008 Simtec Electronics 
 *  http://armlinux.simtec.co.uk/ 
 *  Ben Dooks <ben@simtec.co.uk> 
 * 
 * S3C Platform - GPIO pin configuration 
 * 
 * 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. 
*/  
  
/* This file contains the necessary definitions to get the basic gpio 
 * pin configuration done such as setting a pin to input or output or 
 * changing the pull-{up,down} configurations. 
 */  
  
/* Note, this interface is being added to the s3c64xx arch first and will 
 * be added to the s3c24xx systems later. 
 */  
  
#ifndef __PLAT_GPIO_CFG_H   
#define __PLAT_GPIO_CFG_H __FILE__   
  
typedef unsigned int __bitwise__ s3c_gpio_pull_t;  
  
/* forward declaration if gpio-core.h hasn't been included */  
struct s3c_gpio_chip;  
  
/** 
 * struct s3c_gpio_cfg GPIO configuration 
 * @cfg_eint: Configuration setting when used for external interrupt source 
 * @get_pull: Read the current pull configuration for the GPIO 
 * @set_pull: Set the current pull configuraiton for the GPIO 
 * @set_config: Set the current configuration for the GPIO 
 * @get_config: Read the current configuration for the GPIO 
 * 
 * Each chip can have more than one type of GPIO bank available and some 
 * have different capabilites even when they have the same control register 
 * layouts. Provide an point to vector control routine and provide any 
 * per-bank configuration information that other systems such as the 
 * external interrupt code will need. 
 */  
struct s3c_gpio_cfg {  
    unsigned int    cfg_eint;  
  
    s3c_gpio_pull_t (*get_pull)(struct s3c_gpio_chip *chip, unsigned offs);  
    int     (*set_pull)(struct s3c_gpio_chip *chip, unsigned offs,  
                    s3c_gpio_pull_t pull);  
  
    unsigned (*get_config)(struct s3c_gpio_chip *chip, unsigned offs);  
    int  (*set_config)(struct s3c_gpio_chip *chip, unsigned offs,  
                   unsigned config);  
};  
  
#define S3C_GPIO_SPECIAL_MARK   (0xfffffff0)   
#define S3C_GPIO_SPECIAL(x) (S3C_GPIO_SPECIAL_MARK | (x))   
  
/* Defines for generic pin configurations */  
#define S3C_GPIO_INPUT  (S3C_GPIO_SPECIAL(0))   
#define S3C_GPIO_OUTPUT (S3C_GPIO_SPECIAL(1))   
#define S3C_GPIO_SFN(x) (S3C_GPIO_SPECIAL(x))   
  
#define s3c_gpio_is_cfg_special(_cfg) \   
    (((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)  
  
/** 
 * s3c_gpio_cfgpin() - Change the GPIO function of a pin. 
 * @pin The pin number to configure. 
 * @to The configuration for the pin's function. 
 * 
 * Configure which function is actually connected to the external 
 * pin, such as an gpio input, output or some form of special function 
 * connected to an internal peripheral block. 
 */  
extern int s3c_gpio_cfgpin(unsigned int pin, unsigned int to);  
//此宏函数将pin引脚配置成“to”功能,to可以取/* Defines for generic pin configurations */ 中定义的值  
/* Define values for the pull-{up,down} available for each gpio pin. 
 * 
 * These values control the state of the weak pull-{up,down} resistors 
 * available on most pins on the S3C series. Not all chips support both 
 * up or down settings, and it may be dependant on the chip that is being 
 * used to whether the particular mode is available. 
 */  
#define S3C_GPIO_PULL_NONE  ((__force s3c_gpio_pull_t)0x00)   
#define S3C_GPIO_PULL_DOWN  ((__force s3c_gpio_pull_t)0x01)   
#define S3C_GPIO_PULL_UP    ((__force s3c_gpio_pull_t)0x02)   
  
/** 
 * s3c_gpio_setpull() - set the state of a gpio pin pull resistor 
 * @pin: The pin number to configure the pull resistor. 
 * @pull: The configuration for the pull resistor. 
 * 
 * This function sets the state of the pull-{up,down} resistor for the 
 * specified pin. It will return 0 if successfull, or a negative error 
 * code if the pin cannot support the requested pull setting. 
*/  
extern int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull);
//将pin引脚的上拉电阻设置成“pull”状态,pull可以去上面宏定义的那些值
  
/** 
 * s3c_gpio_getpull() - get the pull resistor state of a gpio pin 
 * @pin: The pin number to get the settings for 
 * 
 * Read the pull resistor value for the specified pin. 
*/  
extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin);
//读取pin引脚上拉电阻的状态  
  
#endif /* __PLAT_GPIO_CFG_H */















本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LED驱动GPIO相关头文件简要分析 的相关文章

  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • Java项目结构概述

    文章目录 前言 一 项目结构介绍 1 单模块项目结构 2 多模块项目结构 3 分层结构 4 MVC项目结构 5 插件化结构项目 6 微服务架构结构 总结 前言 构建一个良好的Java项目结构是开发高质量 可扩展和易维护应用程序的重要基础 在
  • skimage图像的读取与保存

    首先 说明用opencv与skimage io imread读取和保存图片的区别 读取和保存后的都是numpy格式 但cv2的读取和存储格式是BGR 而skimage的读取和存储格式是RGB 1 读取图片 skimage读取图片 img s
  • The deduced formulas of Conv1d and ConvTranspose1d

    torch nn Conv1d in channels out channels kernel size stride 1 padding 0 dilation 1 groups 1 bias True In the simplest ca
  • 基于树莓派的python界面开发实例教程

    基于树莓派的python界面开发实例教程 环境测试 添加label实例 时钟程序 添加天气 环境测试 点击树莓派的开始菜单 找到programming Python3 IDLE 点击打开 打开后如下 在home pi下面建立home pi
  • UNIX网络编程卷一 学习笔记 第十七章 ioctl操作

    ioctl函数传统上一直作为那些不适合归入现有已定义的类别的系统接口 POSIX正在通过创建特定的包装函数来代替ioctl函数的某些功能 以取而代之的是那些已被POSIX标准化的函数 例如 Unix终端接口传统上使用ioctl函数访问 而P
  • 测试工程师需要具备哪些技能

    测试工程师需要具备以下几项技能 软件测试方法和技巧 测试工程师需要了解不同的测试方法 如黑盒测试 白盒测试 回归测试等 编程能力 有些测试工程师需要编写自动化测试脚本 因此需要具备一定的编程技能 问题诊断能力 测试工程师需要能够识别和定位软
  • 【leetcode刷题】27、移除元素(C++)

    27 移除元素 原题地址 https leetcode cn problems remove element 给你一个数组 nums 和一个值 val 你需要 原地 移除所有数值等于 val 的元素 并返回移除后数组的新长度 不要使用额外的
  • 华为OD2023(A卷)基础题34【新词挖掘】

    知识图谱新词挖掘 题目描述 小华负责公司知识图谱产品 现在要通过新词挖掘完善知识图谱 新词挖掘 给出一个待挖掘文本内容字符串content和一个词的字符串word 找到content中所有word的新词 新词 使用词word的字符排列形成的
  • 使用HTMLTestRunner没有生成测试报告

    原因 没有执行 main函数中的程序 只执行了测试用例 在main函数上方右键运行的是整个py文件 在main函数下方右键运行的是py文件中的测试用例 如果在上方点击出现的和下方点击的一样需要在右上角设置并添加文件路径
  • element 限制文件上传类型

  • Golang依赖注入提升开发效率!

    导语 依赖注入并不是java独有的 也不是web框架独有的 本文用通俗易懂的语言讲解什么是依赖注入 为什么需要依赖注入 以及go语言如何使用依赖注入来提升开发效率 一 什么依赖注入 依赖注入 Dependency Injection 也叫D
  • C++拷贝构造、赋值构造详解

    一 前言 写一个用到指针的程序时 被拷贝 赋值 析构函数坑了一波 网上查相关博客 发现关于拷贝 赋值构造函数调用时机大多都有错误 因此决定自己总结撸一发博客 A A a 拷贝构造函数 A const A a 拷贝构造函数 A operato
  • 谈谈区块链入门技能(三):Layer 2区块链浏览器如何使用?Tokenview

    继介绍了比特币以及EVM系列区块链浏览器使用指南 今天我们再来 介绍一下Layer 2系列浏览器如何使用 Layer 1 是基础区块链 以太坊和比特币都是Layer1区块链因为它们是各种Layer2网络构建的底层基础 Layer2项目包括以
  • 第二个作业:贝叶斯估计

    第二个作业 贝叶斯估计实战 第一小题 试使用西瓜数据集3 0作为训练集 通过AIC准则构建一个贝叶斯网 我先看看scikit learn官网上关于贝叶斯估计 特别是贝叶斯网的构建方面的包和函数 然后再看看这个AIC准则具体是怎么样的 如何构
  • 操作系统5-处理机调度——lab6调度器

    大纲 处理机调度概念 处理机调度 调度时机 调度准则 调度算法 实时调度 多处理器调度 优先级反转 CPU调度的背景 什么是CPU调度 为什么会有这个概念 要研究它的什么 CPU调度的背景是进程切换 当我们说进程切换 其概念是保存当前进程在
  • stm32 CRC-16校验代码,单片机ModBUS-CRC16校验

    stm32系列内部均带有硬件CRC 不过为了方便移植 建议使用纯计算的方式 进行CRC 16计算 可用于ModBUS通信 提供两种实现方法的代码 1 实时计算 CRC 16 耗时多 这种方式耗时会比较多 优点是占用Flash RAM小 CR
  • umi3.5新特性之提速方案mfsu

    前几天 umi 插件化的企业级前端应用框架 正式发布了3 5版本 此次更新带来了一个全新的功能 mfsu 一 mfsu是什么 mfsu是一种基于webpack5新特性Module Federation 模块联邦 的打包提速方案 开启mfsu
  • 域环境的搭建

    域环境 内网渗透测试 很大的程度上就是域渗透测试 搭建域环境 这里使用Windows Server 2012 R2搭建windwos域环境 Windows Server 2012 R2 Windows Server 2008 R2 wind
  • SonarQube 9.x集成阿里p3c代码规范检测java代码;

    文章目录 前言 一 下载p3c pmd插件 二 sonarqube配置使用p3c规则检测 1 新建质量配置 2 将创建好的p3c检测规则设置为默认质量配置 注1 注2 前言 因为我们公司后端主用的是java语言 在进行sonar代码检测的时
  • LED驱动GPIO相关头文件简要分析

    常识 应用程序 gt 系统内核 gt 设备驱动 gt 硬件设备 设备驱动既是系统内核的下属 又是硬件设备的老大 在inux系统中用一个文件来代表一个设备 这个文件就叫设备文件 设备驱动的责任是将应用程序对设备文件 的打开 读 写 定位等操作