历史上的今天
返回首页

历史上的今天

今天是:2024年12月31日(星期二)

正在发生

2021年12月31日 | 4412 GPIO读 和 ioremap控制GPIO寄存器

2021-12-31 来源:eefocus

一、配置GPIO读

在视频14的基础上做

1.利用拨码开关来实现GPIO输入

所以AP_SLEEP对应GPC0_3,然后在drivers/gpio/gpio-exynos4.c中对应EXYNOS4_GPC0(0)

XEINT6→GPX0_6→EXYNOS4_GPX0(6)

读寄存器手册分析流程:

  1. 设置寄存器为输入  GPC0CON

  2. 读寄存器值     GPC0DAT

  3. 不上拉,不下拉   GPC0PUD

 

2.GPIO的输入需要哪些函数,从archarmplat-samsunggpio-config.c中找

  • 申请gpio_request

  • 读寄存器gpio_get_value

  • 设置GPIO为输入模式s3c_gpio_cfgpin  S3C_GPIO_INPUT

  • 设置上拉下拉s3c_gpio_setpull S3C_GPIO_PULL_NONE

  • 释放GPIO gpio_free

3.平台文件中设备注册

 在文件arch/arm/mach-exynos/mach-itop4412.c中:

    struct platform_device s3c_device_read_gpio_ctl = {
        .name   = "read_gpio_ctl",
        .id     = -1,
    };

  &s3c_device_read_gpio_ctl,

在init_lcd_type函数中request了GPIO。所以在get_lcd_type需要释放GPIO

    gpio_free(EXYNOS4_GPC0(3));
    gpio_free(EXYNOS4_GPX0(6));

4.Makefile修改

Makefile

TARGET_NAME = read_gpio

APP_NAME = app_read_gpio

obj-m += $(TARGET_NAME).o


KDIR := /home/topeet/chen/kernel-3.0/iTop4412_Kernel_3.0


PWD ?= $(shell pwd)


all:app

    make -C $(KDIR) M=$(PWD) modules


app:$(APP_NAME)

    arm-none-linux-gnueabi-gcc $(APP_NAME).c -o $(APP_NAME) -static


clean:

    rm -rf *.o *.ko *.mod.c *.symvers *.order

    .$(TARGET_NAME)* $(APP_NAME)


5.驱动的修改

read_gpio.c


#include

#include


/*驱动注册的头文件,包含驱动的结构体和注册和卸载的函数*/

#include

/*注册杂项设备头文件*/

#include

/*注册设备节点的文件结构体*/

#include


/*Linux中申请GPIO的头文件*/

#include

/*三星平台的GPIO配置函数头文件*/

/*三星平台EXYNOS系列平台,GPIO配置参数宏定义头文件*/

#include

#include

/*三星平台4412平台,GPIO宏定义头文件*/

#include


#define DRIVER_NAME "read_gpio_ctl"

#define DEVICE_NAME "read_gpio_ctl"



MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("TOPEET");


static long read_gpio_ioctl( struct file *files, unsigned int cmd, unsigned long arg)

{

    printk("cmd is %d,arg is %dn",cmd,arg);

    

    if(cmd > 1){

        printk(KERN_EMERG "cmd is 0 or 1n");

    }

    if(arg > 1){

        printk(KERN_EMERG "arg is only 1n");

    }


    //if cmd is 0, return GPC(3)>>switch3

    //if cmd is 1, return GPX(6)>>switch4

    if(cmd == 0) {

        return gpio_get_value(EXYNOS4_GPC0(3));

    }

    if(cmd == 1) {

        return gpio_get_value(EXYNOS4_GPX0(6));

    }

    

    return 0;

}


static int read_gpio_release(struct inode *inode, struct file *file)

{

    printk(KERN_EMERG "read_gpio releasen");

    return 0;

}


static int read_gpio_open(struct inode *inode, struct file *file)

{

    printk(KERN_EMERG "read_gpio openn");

    return 0;

}


static struct file_operations read_gpio_ops = {

    .owner = THIS_MODULE,

    .open = read_gpio_open,

    .release = read_gpio_release,

    .unlocked_ioctl = read_gpio_ioctl,

};


static  struct miscdevice read_gpio_dev = {

    .minor = MISC_DYNAMIC_MINOR,

    .name = DEVICE_NAME,

    .fops = &read_gpio_ops,

};



static int read_gpio_probe(struct platform_device *pdv)

{

    int ret;

    

    printk(KERN_EMERG "tinitializedn");

    

    ret = gpio_request(EXYNOS4_GPC0(3),"Switch3");

    if(ret < 0){

        printk(KERN_EMERG "gpio_request EXYNOS4_GPL2(0) failed!n");

        return ret;

    } else {

        s3c_gpio_cfgpin(EXYNOS4_GPC0(3), S3C_GPIO_INPUT);

        s3c_gpio_setpull(EXYNOS4_GPC0(3), S3C_GPIO_PULL_NONE);


    }

    

    ret = gpio_request(EXYNOS4_GPX0(6),"Switch4");

    if(ret < 0){

        printk(KERN_EMERG "gpio_request EXYNOS4_GPL2(0) failed!n");

        return ret;

    } else {

        s3c_gpio_cfgpin(EXYNOS4_GPX0(6), S3C_GPIO_INPUT);

        s3c_gpio_setpull(EXYNOS4_GPX0(6), S3C_GPIO_PULL_NONE);


    }

    

    misc_register(&read_gpio_dev);

    

    return 0;

}


static int read_gpio_remove(struct platform_device *pdv)

{    

    printk(KERN_EMERG "tremoven");

    gpio_free(EXYNOS4_GPC0(3));

    gpio_free(EXYNOS4_GPX0(6));

    misc_deregister(&read_gpio_dev);

    return 0;

}


static void read_gpio_shutdown(struct platform_device *pdv)

{

    

    ;

}


static int read_gpio_suspend(struct platform_device *pdv,pm_message_t pmt)

{

    

    return 0;

}


static int read_gpio_resume(struct platform_device *pdv)

{

    

    return 0;

}


struct platform_driver read_gpio_driver = {

    .probe = read_gpio_probe,

    .remove = read_gpio_remove,

    .shutdown = read_gpio_shutdown,

    .suspend = read_gpio_suspend,

    .resume = read_gpio_resume,

    .driver = {

        .name = DRIVER_NAME,

        .owner = THIS_MODULE,

    }

};



static int read_gpio_init(void)

{

    int DriverState;

    

    printk(KERN_EMERG "read_gpio enter!n");

    DriverState = platform_driver_register(&read_gpio_driver);

    

    printk(KERN_EMERG "tDriverState is %dn",DriverState);

    return 0;

}



static void read_gpio_exit(void)

{

    printk(KERN_EMERG "read_gpio exit!n");

    

    platform_driver_unregister(&read_gpio_driver);    

}


module_init(read_gpio_init);

module_exit(read_gpio_exit);


应用程序:

app_read_gpio


#include


#include

#include

#include

#include

#include


#include


#define GPIOS 32


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

{

        int fd, i, cmd = 2;

        char *read_gpio = "/dev/read_gpio_ctl";

        char *cmd0 = "0";

        char *cmd1 = "1";

        printf("argv[0] is %s;argv[1] is %s;n", argv[0], argv[1]);


        if(strcmp(argv[1], cmd0) == 0) {

                cmd = 0;

        }

        if(strcmp(argv[1], cmd1) == 0) {

                cmd = 1;

        }


        if((fd = open(read_gpio, O_RDWR|O_NDELAY)) < 0) {

                printf("APP open %s failedn", read_gpio);

        } else {

                printf("APP open %s success!n", read_gpio);

                printf("%d io value is %dn", cmd, ioctl(fd, cmd, 0));

        }


        close(fd);

}


测试结果:


[root@iTOP-4412]# ./app_read_gpio 1                                                                        

argv[0] is ./app_[  312.514145] read_gpio open

[  312.516876] cmd is 1,arg is 0

[  312.519870] read_gpio release

read_gpio;argv[1] is 1;

APP open /dev/read_gpio_ctl success!

1 io value is 0

[root@iTOP-4412]# ./app_read_gpio 0                                                                        

argv[0] is ./app_[  314.786489] read_gpio open

[  314.789131] cmd is 0,arg is 0

[  314.792307] read_gpio release

read_gpio;argv[1] is 0;

APP open /dev/read_gpio_ctl success!

0 io value is 0

[root@iTOP-4412]# ./app_read_gpio 1                                                                        

argv[0] is ./app_[  321.786146] read_gpio open

[  321.788790] cmd is 1,arg is 0

[  321.791899] read_gpio release

read_gpio;argv[1] is 1;

APP open /dev/read_gpio_ctl success!

1 io value is 1

[root@iTOP-4412]# ./app_read_gpio 0                                                                        

argv[0] is ./app_[  323.449833] read_gpio open

[  323.452526] cmd is 0,arg is 0

[  323.455489] read_gpio release

read_gpio;argv[1] is 0;

APP open /dev/read_gpio_ctl success!

0 io value is 1

二、ioremap控制GPIO寄存器

上面使用的是直接通过软件转换好了的,其实内核也是可以自己做转化的。

自己实现物理地址到虚拟地址的转化,iounmap和ioremap函数可以实现物理地址到虚拟地址的转化

1.硬件

  •  原理图部分

  • datasheet物理地址

  • GPL2CON = 0x1100 0000 + 0x0100 = 0x1100 0100

  • GPL2DAT = 0x1100 0000 + 0x0104 = 0x1100 0104

  • GPL2PUD = 0x1100 0000 + 0x0108 = 0x1100 0108

  • 寄存器不一定是32位的,也有16位或8位的

2.软件

ioremap_leds.c


#include

#include

#include


MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("Topeet");


//用于存放虚拟地址和物理地址

volatile unsigned long virt_addr, phys_addr;

推荐阅读

史海拾趣

Davicom公司的发展小趣事

随着产品技术的不断成熟和市场竞争的加剧,Davicom开始积极拓展市场,加强品牌建设。公司加大市场推广力度,积极参加国内外各类展会和论坛,与潜在客户建立联系。同时,Davicom还注重提高产品质量和服务水平,赢得了客户的信任和好评。

Grand Halo Technology Co Ltd公司的发展小趣事

面对不断变化的市场环境和客户需求,Davicom始终保持创新精神,不断寻求新的发展机遇。公司紧跟行业趋势,积极投入研发资源,推出了一系列具有创新性的产品。这些新产品不仅提升了公司的市场竞争力,也为公司的持续发展注入了新的动力。

HALO Electronics公司的发展小趣事

面对不断变化的市场环境和客户需求,Davicom始终保持创新精神,不断寻求新的发展机遇。公司紧跟行业趋势,积极投入研发资源,推出了一系列具有创新性的产品。这些新产品不仅提升了公司的市场竞争力,也为公司的持续发展注入了新的动力。

泽耀科技(Ashining)公司的发展小趣事

在国内市场取得一定成绩后,泽耀科技(Ashining)开始积极拓展国际市场。公司参加了多个国际电子展会,与国际知名企业建立了合作关系,成功将产品打入国际市场。同时,泽耀科技还积极寻求与国际先进技术的交流与合作,不断提升自身的技术水平和产品质量。

地博电子(DIBO)公司的发展小趣事

近年来,地博电子积极响应行业发展趋势,不断推进数字化转型和精益生产。在2022年,公司导入了精益生产系统,通过优化生产流程、降低库存和浪费等措施,进一步提高了生产效率和产品质量。同时,在2023年,地博电子还导入了OA/SAP信息化系统,开启了数字化转型之路。这些举措使得地博电子在电子材料行业中保持了领先地位,并为公司的未来发展奠定了坚实基础。

请注意,以上故事概要仅为地博电子(DIBO)公司发展历程中的部分关键事实,更多详细信息和数据可参考公司官方资料。

Greenliant公司的发展小趣事

在光伏产业快速发展的背景下,GPS于2020年进军光伏逆变器市场。公司凭借其深厚的技术积累和创新能力,开发出了一系列高效、可靠的光伏逆变器产品。这些产品不仅转换效率高,而且具备智能监控和远程控制功能,大大提升了光伏电站的运行效率和安全性。GPS的光伏逆变器产品迅速获得市场认可,成为众多光伏项目的首选设备。

问答坊 | AI 解惑

nrf905无线模块测试程序

本帖最后由 paulhyde 于 2014-9-15 03:01 编辑 nrf905无线模块测试程序 大赛可能用到,我就卖2个币意思一下!~!~!~    …

查看全部问答>

摄像头编程类+类调用+例子

本帖最后由 paulhyde 于 2014-9-15 09:18 编辑 using System; using System.Runtime.InteropServices; using System.Drawing.Imaging; using System.Windows.Forms; using System.Drawing; namespace YHhotel.YHhotelWindows //注意这里要 ...…

查看全部问答>

51单片机=====74hc573(锁存器)

51单片机=====74hc573(锁存器) BY: 飞龙  QQ: 9086074    希望认识更多的单片机开发朋友一起交流   第一次做教程不好多多见谅 BLOG: http://hi.baidu.com/alalmn 1.        烧写程序 2.&n ...…

查看全部问答>

怎样对USB设备的其中一个pipe进行读写操作?谢谢!(VB)

我需要与蓝牙设备通信,通过SetupDiGetClassDevs (Guid由注册表找到),SetupDiEnumDeviceInterfaces ,SetupDiGetDeviceInterfaceDetail 函数查找到DevicePath。但是createfile失败。 我需要对这个设备的其中一个pipe读写。在Path后加上“\\PIPE ...…

查看全部问答>

AfxMessage,在线等

环境是evc++    SP4   afxmessage里面的参数想用1句话加一个变量来做, 例如,我买个5本书,这里的5就是变化的。 用了一下几种方式都不可以,请教高人帮忙来做, AfxMessageBox(\"我买了\"+CString(number)+\"本书\"); ...…

查看全部问答>

SIM300C简单三线串口连接服务器注意事项!

使用简单的三线串口,没有流控,没有数据准备好,也没有终端准备好! 请问怎样解决下面的问题:        SIM300C和服务器同时发送数据,SIM300C串口输出的数据是AT命令反馈数据和服务器发送数据夹杂在一起的     ...…

查看全部问答>

EE_FPGA V1.0 器件代购总表

注意事项: 1. 红外接口芯片TFDU4100没买到 2. 有源晶振提供一个   交易总价:125元 + 20元(快递费) 淘宝地址:   http://item.taobao.com/auction/item_detail.htm?item_num_id=8252057915   详细清单如下:   ...…

查看全部问答>

请教数位滤波功能

各位先进,大家好,能否提供或说明其数位滤波在MSP430G2452上的可行性? 最近老师要我制作这个功能於2452身上,方法为输入一波形进入2452的PIN脚,再由滤波後输出至PC端显示其滤波效果,实在快昏头ㄌ。 希望能有先进能帮帮忙,或是提点开释一下, ...…

查看全部问答>