我是靠谱客的博主 轻松咖啡,最近开发中收集的这篇文章主要介绍linux用户层gpio使用,Linux用户态控制GPIO,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

/*

* gpio_ctrl.c: user mode software to control the GPIO of S3C2440

* Author Youri Zhang 2010-12-28 (yahui9635@gmail.com)

* Reach the Author first before release this program.

*/

#include

#include

#include

#include

#include

#undef PAGE_SIZE

#undef PAGE_MASK

#define APP_NAME  "gpio_ctrl"

#define VERSION  "1.0"

#define BUILD_DATE  __DATE__

#define PAGE_SHIFT12

#define PAGE_SIZE (1<

#define PAGE_MASK (~(PAGE_SIZE-1) )

#define GPIO_EndAddr0x560000DC

#define GPIO_StartAddr0x56000000

#define CLKREG_StartAddr0x4C000000

#define CLKREG_EndAddr0x4C000018

#define CLKCON 0x0C

#define REG(Addr)(*(volatile unsigned int*) (Addr))

static char* GPIOConStatus[4] = {"INPUT", "OUTPUT", "SpecialUse", "Reserved"};

static char* GPIODataStatus[2] = {"LOW", "HIGH"};

static char* GPIOPullupStatus[2] = {"Enabled", "Disabled"};

static void print_usage(void)

{

fprintf(stdout,"************Help information for %s*************n",APP_NAME);

fprintf(stdout,"[Usage] %s -[b:n:c:w:p:rsdh] n", APP_NAME);

fprintf(stdout,"Version: %s, Date: %s, Author: Youri Zhangnn", VERSION, BUILD_DATE);

fprintf(stdout,"t-b : (Must use 1st)specify the GPIO Bank indexntt==>GPA's index is 0, GPB's index is 1 ... GPH's index is 7, GPJ's index is 8n");

fprintf(stdout,"t-n : (Must use 2nd)specify the GPIO num in GPIO Bankn");

fprintf(stdout,"t-c : Config the GPIO type(GPA use)ntt==>OUTPUT:'-c 0x00', Special use:'-c 0x01'n");

fprintf(stdout,"t-c : Config the GPIO type(GPB--J use)ntt==>INPUT:'-c 0x00', OUTPUT:'-c 0x01', Special use:'-c 0x02', Reserved:'-c 0x03'n");

fprintf(stdout,"t-w : Write value to GPIO pin's Data_regn");

fprintf(stdout,"t-p : Config value to GPIO pin's Pullup_regntt==>Enable:'-p 0x00', Disable:'-p 0x01'n");

fprintf(stdout,"t-r : Read the GPIO pin Data_reg's valuen");

fprintf(stdout,"t-s : Show the GPIO pin Config_reg's valuen");

fprintf(stdout,"t-d : Display the GPIO pin Pullup_reg's valuen");

fprintf(stdout,"t-h : This help informationnn");

fprintf(stdout,"Ex:tConfig GPG4 output & write 0 to GPG4 Data_reg&enable pullup&read Data_reg&show configure&show pullupntt==> (%s -b 6 -n 4 -c 1 -w 0 -p 0 -s -r -d)n", APP_NAME);

fprintf(stdout,"tt==> (%s -b 0x06 -n 0x04 -c 0x01 -w 0x00 -p 0x00 -s -r -d)ntt--> both decimal and hexadecimal input are ok!n", APP_NAME);

fprintf(stdout,"Ex:tConfig the GPA4 output and write 0 to GPG4 Data_regntt==> (%s -b 0 -n 4 -c 0x00 -w 0)n", APP_NAME);

fprintf(stdout,"Ex:tConfig the GPG4 output and read GPG4 Data_reg's valuentt==> (%s -b 6 -n 4 -c 0x01 -r)n", APP_NAME);

fprintf(stdout,"Ex:tConfig the GPG4 output and show GPG4 Config_reg's valuentt==> (%s -b 6 -n 4 -c 0x01 -s)n", APP_NAME);

}

/* enable PCLK(50Mhz) to GPIO Block */

static void s3c2440_clkcon_init(void* REG_CLK)

{

REG((unsigned int)REG_CLK+CLKCON) |=0x2000;

}

static void s3c2440_gpio_cfgpin(void *Regaddr, unsigned int Addr_offset, unsigned int MaskBit, unsigned int Function)

{

unsigned int tmp=0;

tmp=REG((unsigned int)Regaddr +Addr_offset);

if(Addr_offset>0)

{

Function &= 3;

tmp &= ~(3<

}

else

{

Function &= 1;

tmp &= ~(1<

}

tmp|= (Function<

REG((unsigned int)Regaddr +Addr_offset)=tmp;

}

static unsigned int s3c2440_gpio_getcfg(void *Regaddr, unsigned int Addr_offset, unsigned int MaskBit)

{

unsigned int tmp=0;

tmp=REG((unsigned int)Regaddr +Addr_offset);

tmp >>= MaskBit;

if(Addr_offset>0x0c)

tmp &= 3;/*used for GPIO Bank B-J, which use the 2 bits Mask*/

else

tmp &= 1;/*used for GPIO Bank A, which use the 1 bit Mask*/

return tmp;

}

static void s3c2440_gpio_setpin(void *Regaddr, unsigned int Addr_offset, unsigned int MaskBit, unsigned int to)

{

unsigned int tmp=0;

tmp=REG((unsigned int)Regaddr +Addr_offset);

tmp &= ~(1<

tmp |= (!!to<

REG((unsigned int)Regaddr +Addr_offset)=tmp;

}

static unsigned int s3c2440_gpio_getpin(void *Regaddr, unsigned int Addr_offset, unsigned int MaskBit)

{

unsigned int tmp=0;

tmp=REG((unsigned int)Regaddr +Addr_offset);

tmp &= (1<

return tmp?1:0;

}

static void s3c2440_gpio_pullup(void *Regaddr, unsigned int Addr_offset, unsigned int MaskBit, unsigned int to)

{

unsigned int tmp=0;

tmp=REG((unsigned int)Regaddr +Addr_offset);

tmp &= ~(1<

tmp |= !!to << MaskBit;

REG((unsigned int)Regaddr +Addr_offset)=tmp;

}

static unsigned int s3c2440_gpio_getpull(void *Regaddr, unsigned int Addr_offset, unsigned int MaskBit)

{

unsigned int tmp=0;

tmp=REG((unsigned int)Regaddr +Addr_offset);

tmp &= (1<

return tmp?1:0;

}

int main(int argc, char* argv[])

{

int fd=-1, opt = -1, Bank_num=-1, Addr_offset=-1, MaskBit=-1, Function=-1, to=-1,pullup=-1;

void* GpioBase = NULL;

void* CLKBASE = NULL;

if(argc==2 && !strcmp(argv[1],"-h"))

{

print_usage();

exit(1);

}

else if(argc > 5 && argc < 15)

{

if(strcmp(argv[1],"-b") || strcmp(argv[3],"-n"))

{

fprintf(stdout, "[Error]: '-b' must be used as the first option && '-n' must be used as second the optionn");

fprintf(stdout, "For Example: %s -b 6 -n 4 -c 1 -w 0 -p 0 -s -r -dn",APP_NAME);

print_usage();

exit(1);

}

fd = open("/dev/mem", O_RDWR | O_SYNC);

if(fd<0)

{

fprintf(stderr, "open /dev/mem errorn");

exit(1);

}

CLKBASE = mmap(NULL, (CLKREG_EndAddr-CLKREG_StartAddr), PROT_READ|PROT_WRITE, MAP_SHARED,fd, CLKREG_StartAddr & PAGE_MASK);

if(CLKBASE == NULL || CLKBASE == MAP_FAILED)

{

fprintf(stderr, "[Error]: S3C2440 CLKCON base mmap errorn");

goto failed;

}

//fprintf(stdout, "Re-Maped 0x%X to Space Addr:0x%X, Maped Size 0x%X bytesn",CLKREG_StartAddr,CLKBASE ,(CLKREG_EndAddr-CLKREG_StartAddr));

GpioBase = mmap(NULL, (GPIO_EndAddr-GPIO_StartAddr), PROT_READ|PROT_WRITE, MAP_SHARED,fd, GPIO_StartAddr & PAGE_MASK);

if(GpioBase == NULL || GpioBase == MAP_FAILED)

{

fprintf(stderr, "S3C2440 gpio base mmap errorn");

goto failed;

}

//fprintf(stdout, "Re-Maped 0x%X to Space Addr:0x%X, Maped Size 0x%Xn",GPIO_StartAddr,GpioBase,(GPIO_EndAddr-GPIO_StartAddr));

s3c2440_clkcon_init(CLKBASE);

while ((opt = getopt(argc, argv, "b: n: c: w: p: rsdh")) != -1)

{

switch (opt)

{

case 'b': /* Bank num to program */

Bank_num = strtoul(optarg, NULL, 0);

if( Bank_num < 0 || Bank_num > 8){

fprintf(stderr, "[Error]: Please input correct Bank index num, the Bank index num should be 0--8 !n");

goto failed;

}

Addr_offset = Bank_num * 0x10;

if(Addr_offset==0x80)

Addr_offset += 0x50;

//fprintf(stdout,"The Addr_offset is 0x%Xn",Addr_offset);

break;

case 'n': /*GPIO num in Bank to program, GPIO num is the Mask bit*/

MaskBit = strtoul(optarg, NULL, 0);

if( MaskBit < 0 || MaskBit > 25){

fprintf(stderr, "[Error]: Please input correct GPIO index num, the GPIO index num should be 0--25(max) !n");

goto failed;

}

//fprintf(stdout,"The MaskBit is 0x%un",MaskBit);

break;

case 'c': /* The value to config the gpio_config_reg */

Function = strtoul(optarg, NULL, 0);

if( Function < 0 || Function > 3){

fprintf(stderr, "[Error]: Please input correct 'Config_reg' value, the value should be 0x00--0x03 !n");

goto failed;

}

if(Bank_num>0)

{

s3c2440_gpio_cfgpin(GpioBase,Addr_offset,MaskBit*2,Function);

fprintf(stdout,"...Writing the 'Config_reg' to %s...n",GPIOConStatus[Function]);

}

else

{

s3c2440_gpio_cfgpin(GpioBase,Addr_offset,MaskBit,Function);

fprintf(stdout,"...Writing the 'Config_reg' to %s...n",GPIOConStatus[Function+1]);

}

break;

case 'w': /* The value to write to the gpio_data_reg*/

to = strtoul(optarg, NULL, 0);

if( to < 0 || to > 1){

fprintf(stderr, "[Error]: Please input correct 'Data_reg' value, the value should be 0x00--0x01 !n");

goto failed;

}

s3c2440_gpio_setpin(GpioBase, Addr_offset+4, MaskBit, to);

fprintf(stdout,"...Writing the 'Data_reg' to %s...n",GPIODataStatus[to]);

break;

case 'p': /* The value to write to the gpio_data_reg*/

pullup = strtoul(optarg, NULL, 0);

if( pullup < 0 || pullup > 1){

fprintf(stderr, "[Error]: Please input correct 'Pullup_reg' value, the value should be 0x00--0x01 !n");

goto failed;

}

if(Bank_num>0)

{

s3c2440_gpio_pullup(GpioBase, Addr_offset+8, MaskBit, pullup);

fprintf(stdout,"...Writing the 'Pullup_reg' to %s...n",GPIOPullupStatus[pullup]);

}

else fprintf(stderr,"[Error]: Can't set Pullup for GPIO Bank A%sn");

break;

case 'r': /* Read the value of the gpio_data_reg*/

fprintf(stdout,"The 'Data_reg' value is--> %sn",GPIODataStatus[s3c2440_gpio_getpin(GpioBase, Addr_offset+4, MaskBit)]);

break;

case 's': /* Show the value of the gpio_configure_reg*/

if(Bank_num>0)

fprintf(stdout,"The 'Config_reg' value is--> %sn",GPIOConStatus[s3c2440_gpio_getcfg(GpioBase, Addr_offset, MaskBit*2)]);

else

fprintf(stdout,"The 'Config_reg' value is-->%sn",GPIOConStatus[s3c2440_gpio_getcfg(GpioBase, Addr_offset, MaskBit)+1]);

break;

case 'd': /* Display the value of the pullup_reg*/

if(Bank_num>0)

fprintf(stdout,"The 'Pullup_reg' value is--> %sn",GPIOPullupStatus[s3c2440_gpio_getpull(GpioBase, Addr_offset+8, MaskBit)]);

else

fprintf(stderr,"[Error]: Can't get pullup status for GPIO Bank An");

break;

case 'h': /* help information */

print_usage();

goto failed;

default :

fprintf(stderr, "[Error]: Uncompleted/Unknown option: %cn", optopt);

print_usage();

goto failed;

}

}

}

else

{

fprintf(stderr, "[Error]: The format of the input options is not correct!n");

fprintf(stderr, "[Error]: The quantity of the input options is not correct!n");

fprintf(stderr, "[Error]: Please use '%s -h' to get the help information!n", APP_NAME);

print_usage();

exit(1);

}

munmap(GpioBase,(GPIO_EndAddr-GPIO_StartAddr));

munmap(CLKBASE,(CLKREG_EndAddr-CLKREG_StartAddr));

close(fd);

exit(0);

failed:

opt =-1;

Bank_num = -1;

Addr_offset = -1;

MaskBit = -1;

Function = -1,

to = -1;

pullup = -1;

munmap(GpioBase,(GPIO_EndAddr-GPIO_StartAddr));

munmap(CLKBASE,(CLKREG_EndAddr-CLKREG_StartAddr));

close(fd);

GpioBase = NULL;

CLKBASE = NULL;

exit(1);

}

最后

以上就是轻松咖啡为你收集整理的linux用户层gpio使用,Linux用户态控制GPIO的全部内容,希望文章能够帮你解决linux用户层gpio使用,Linux用户态控制GPIO所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部