历史上的今天
返回首页

历史上的今天

今天是:2025年02月15日(星期六)

2019年02月15日 | ARM开发之用linux通用GPIO接口宏函数操作IO口

2019-02-15 来源:eefocus

ARM开发板:S5PV210




驱动步骤:


1.定义一个cdev设备结构体变量


2.给cdev申请设备号


3.定义一个文件操作集


4.设备初始化


5.注册设备进内核


6.申请GPIO口




GPIO相关函数接口:


1.gpio_request(引脚,给引脚的名字)   ----申请GPIO口


第一个参数:


在内核代码 \arch\arm\mach-s5pv210\include\mach\gpio.h 中有定义,如下图(部分)

如GPJ2寄存器的第一个引脚,就是 S5PV210_GPJ2(0)




第二个参数:


为管脚起一个名字而已。


例如:


申请GPJ2CON的第一个管脚,并取名为GPJ2_0:


gpio_request(S5PV210_GPJ2(0),"GPJ2_0");;





2.gpio_free(引脚)  ----释放引脚


既然有 gpio_request来申请引脚,那用完了就要释放掉。释放引脚用函数 gpio_free


例如:


释放GPJ2_0引脚:gpio_free(S5PV210_GPJ2(0));




3.gpio_direction_output(引脚,0/1)   ----给引脚置0或1,并把引脚设置为输出模式


例如:


给引脚GPJ2_0设置为输出模式,并置1:gpio_direction_output(S5PV210_GPJ2(0),1);


返回值:失败返回负值






4.gpio_direction_intput(引脚)   ----给引脚设置成输入模式


例如:


给GPJ2_0 设置成输入模式:gpio_direction_input(SPPV210_GPJ2(0));





5.gpio_set_value(引脚,0/1)   ----给引脚置0或1


例如:


给引脚GPJ2_0设置为1(高电平):gpio_set_value(S5PV210_GPJ2(0),1);


返回值:失败返回负值






6.gpio_get_value(引脚)   ----获取引脚的电平。看是0还是1


例如:


获取GPJ2_0 的电平: int  ret;ret = gpio_get_value(S5PV210_GPJ2(0));






下面给出驱动代码和应用程序代码:(实现Led灯轮流闪烁)


#include

#include

#include

#include

#include

#include

#include

#include

#include

 

/*1.定义设备结构体*/

static struct cdev led_cdev;

static dev_t dev_num;

static char *gpio_name[]={"GPJ20","GPJ21","GPJ22","GPJ23"};

static struct class *led_class = NULL;

static struct device *led_device = NULL;

static char wbuf[1]={0};

 

 

static int led_open(struct inode *inode, struct file *f)

{

int i;

printk("led open\n");

for(i=0;i<4;i++)

{

gpio_direction_output(S5PV210_GPJ2(i),1);

}

return 0;

}

 

void led_up(char i)

{

char j;

int k = i-'0';

printk("GET[%c]\n",i);

printk("GET[%d]\n",k);

for(j=0;j<4;j++)

{

gpio_set_value(S5PV210_GPJ2(j),1);

}

gpio_set_value(S5PV210_GPJ2(k),0);

}

 

static ssize_t led_write(struct file *f, const char __user*buf,

size_t len, loff_t *t)

{

copy_from_user(wbuf,buf,len);

if(wbuf[0]=='0')

{

led_up(wbuf[0]);

}

 

if(wbuf[0]=='1')

{

led_up(wbuf[0]);

}

 

if(wbuf[0]=='2')

{

led_up(wbuf[0]);

}

 

if(wbuf[0]=='3')

{

led_up(wbuf[0]);

}

return 0;

}

 

/*3.定义文件操作集*/

static const struct file_operations fops={

.owner = THIS_MODULE,

.open = led_open,

.write = led_write,

};

 

 

static int __init led_init(void)

{

int ret;

int i;

/*2.申请设备号*/

ret = alloc_chrdev_region(&dev_num,0,1,"led");

if(ret<0)

{

printk("failed to register dev num\n");

goto failed_register;

}

 

/*4.字符设备的初始化*/

cdev_init(&led_cdev,&fops);

/*5.注册设备*/

ret = cdev_add(&led_cdev,dev_num,1);

if(ret<0)

{

printk("failed to add cdev\n");

goto failed_add;

}

 

/*6.申请IO口*/

for(i=0;i<4;i++)

{

ret = gpio_request(S5PV210_GPJ2(i),gpio_name[i]);

if(ret<0)

{

printk("failed to request GPIO\n");

goto failed_request_IO;

}

}

/*7.创建设备类*/

led_class = class_create(THIS_MODULE,"led_class");

if(led_class == NULL)

{

printk("failed to create class\n");

goto failed_create_class;

}

/*创建设备文件结点*/

led_device = device_create(led_class,NULL,dev_num,NULL,"led_dev");

if(led_device == NULL)

{

printk("failed to create device\n");

goto failed_create_device;

}

printk("init completed\n");

return 0;

 

failed_create_device:

class_destroy(led_class);

failed_create_class:

failed_request_IO:

while(i--)

{gpio_free(S5PV210_GPJ2(i));}

cdev_del(&led_cdev);

failed_add:

unregister_chrdev_region(dev_num,1);

failed_register:

return -1;

}

 

static void __exit led_exit(void)

{

device_destroy(led_class,dev_num);

class_destroy(led_class);


gpio_free(S5PV210_GPJ2(3));

gpio_free(S5PV210_GPJ2(2));

gpio_free(S5PV210_GPJ2(1));

gpio_free(S5PV210_GPJ2(0));

 

cdev_del(&led_cdev);

unregister_chrdev_region(dev_num,1);

printk("led uninstall!\n");

}

 

module_init(led_init);

module_exit(led_exit);

MODULE_LICENSE("GPL");


应用程序:

#include

#include

 

int main()

{

char buf[1];

char i;

 

int fd = open("/dev/led_dev",O_WRONLY);

if(fd<0)

{

perror("failed to open");

return -1;

}

while(1)

{

for(i='0';i<'4';i++)

{

buf[0]=i;

write(fd,buf,1);

sleep(1);

}

}

return 0;

}



推荐阅读

史海拾趣

台湾三礼(3L)公司的发展小趣事

1991年,三礼公司正式成立了美国分公司(3LU),此举标志着公司开始进军北美市场,将其作为货物管理中心,并与G-TEP合作组建了3L Global Co.(3LG),共同开拓和发展所有北美业务。这一战略决策为三礼公司打开了新的增长通道,使得公司能够更好地服务全球客户,提升品牌影响力。

Codeco Corporation Of Vermont公司的发展小趣事

在国内市场取得成功后,Codeco开始将目光投向国际市场。他们积极拓展海外业务,与多家国际知名企业建立合作关系。通过参加国际展会、设立海外分支机构等方式,Codeco的产品逐渐打入国际市场,赢得了广泛的认可。这一过程中,Codeco不仅提升了品牌知名度,也积累了丰富的国际化运营经验。

Cyrix Corp公司的发展小趣事

1999年,Cyrix再次被威盛电子(VIA)收购。这次收购后,Cyrix所生产的CPU产品上开始出现了两个商标:VIA和Cyrix。这种双标现象反映了Cyrix在被收购后的地位变化。随着时间的推移,Cyrix的商标逐渐淡出市场,最终被彻底放弃。

Bridgelux公司的发展小趣事

Bridgelux公司成立于XXXX年,由一群富有远见和创新精神的工程师创立。他们看到了LED照明技术的巨大潜力,并致力于将其商业化。公司初期面临资金和技术双重挑战,但他们凭借坚定的信念和不懈的努力,成功开发出了一系列高质量的LED照明产品,并逐渐获得了市场的认可。

Chip Supply Micro Devices公司的发展小趣事

在微电子器件领域,Chip Supply Micro Devices凭借一项创新技术,成功打破了市场格局。公司研发出了一种新型低功耗芯片,不仅提高了电子设备的性能,还降低了能源消耗。这一技术突破使得Chip Supply Micro Devices迅速获得了市场的认可,产品销量激增。公司借此机会扩大生产规模,加大研发投入,进一步巩固了其在微电子器件市场的地位。

Electro-Mech Components Inc公司的发展小趣事

随着公司业务的不断发展壮大,EMC开始积极实施全球化战略。公司在全球范围内寻找合适的合作伙伴和销售渠道,努力将其产品推向更广阔的市场。通过与国际知名品牌的合作和交流,EMC不断提升自身的品牌形象和市场影响力。同时,公司还加强了对海外市场的调研和分析工作,以便更好地满足不同地区客户的需求和期望。

请注意,以上故事是基于已知信息构建的框架性内容,具体细节和情节需要根据实际情况进行填充和完善。

问答坊 | AI 解惑

2009国赛比赛实施过程及比赛守则(官网上下的)

本帖最后由 paulhyde 于 2014-9-15 09:44 编辑  …

查看全部问答>

大家使用lpc2132注意的一点

关于__irq 的使用 __irq为一个标识,用来表示一个函数是否为中断函数。对于不同的编译器,__irq在函数名中的位置不一样,例如: ADS编译器中 : void __irq IRQ_Eint0(void); Keil编译器中 : void IRQ_Eint0(void) __irq; 但是其意义一 ...…

查看全部问答>

再次迷茫了

前些时间一直在搞linux,但是linux这玩意儿真的很烦人啊,所以又去搞win ce,在学api,感觉win ce 入门确实比linux简单很多,但是最近又发现在win ce上做应用的基本上都是 .net,偶尔有mfc的,c语言无用武之地啊。这样就觉得现在学的一点用都没有, ...…

查看全部问答>

请教这个IC是个什么东西

请教一下我手头有个电路板上有个IC,5脚封装,上面两脚下面三脚,特小的封装,上面的字符貌似是CO-60Y又或者是CO-GOY,字太小看不清楚,搜索这两个都找不到相关资料。通过测量得知它的功能大概是这样:电源从3脚输入1脚输出,1脚跟5脚是通路,4脚输 ...…

查看全部问答>

寻大虾合作开发机顶盒

http://topic.eeworld.net/u/20071201/18/a2aaf09f-7fa2-419c-93c1-77b51f9713d8.html?seed=1107526537…

查看全部问答>

iar环境下,uCosII在stm32下的运行机理是怎样的?

编译器的iar EWARM,uCosII 通过初始化下面的向量表,在程序复位时将程序定位到__program_start(void)函数,但该函数是个空函数呀,程序到底是怎么进行到正常状态的呢?请大虾们指点。另外,向量表__vector_table[] 的第一行{ ...…

查看全部问答>

STM32之TFT遇到麻烦了,求高手指教

经由Image2lcd处理后的图片最大只能到119288,显示出来的图片还不到1/3屏,正常是153600。如何处理才能使之显示满屏?…

查看全部问答>

在公司看个书怎么就违法了!!!(吐槽完了,封贴吧)

活不多的时候闲着看个书怎么就不对了? 而且我看的还是《编程匠艺》《uCos 操作系统》…… 怎么这就惹领导不高兴了?虽然工作上分配给我的是硬件,但看个代码就不对了? 就叫软件不软硬件不硬了??? 什么制度,做事就是给领导看,什么领导看到你 ...…

查看全部问答>

EEWORLD大学堂----WEBENCH FPGA Architect功能导览

WEBENCH FPGA Architect功能导览:https://training.eeworld.com.cn/course/165…

查看全部问答>