您的位置:首页 > 运维架构 > Linux

xiliinx_wiki中的gpio应用程序调试记录

2018-03-23 09:55 465 查看
本文根据http://www.wiki.xilinx.com/Linux%20GPIO%20Driver中提到的内容以及操作步骤,在zedboard上进行了实验。具体过程如下:
    1. 使用 gpio-polled 驱动程序,添加设备树,更改内核配置,重新编译等等一系列操作,按照wiki上写的步骤搞下来就可以。有区别的地方就是可能因为使用 内核版本的不同,在 make menuconfig 阶段有些配置条目出现的位置与 wiki 上写的有那么一点点的不同,但是都可以找得到。细心翻一翻内核配置和界面就可以。

    2. 修改设备树文件,我使用的是第三个 EMIO ,所以配置为:(zynqPS有54个mio编号为0-53,EMIO要从编号54开始,第三个EMIO的编号就为53+3=56,)设备树中的各种属性的说明见 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/input/gpio-keys-polled.txt  文档。

     gpio_keys_polled {
compatible = "gpio-keys-polled";
poll-interval = <100>;
autorepeat;

button21 {
label = "GPIO-center";
linux,code = <103>;
gpios = <&gpio0 56 1>;
};

};
    3.  更新镜像文件后,运行在板子上。将下列程序编译后在板子上运行。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <pthread.h>
#include <linux/input.h>
 
#define LED_BRIGHTNESS    "/sys/class/leds/ld2:red/brightness"    //对LED的操作,和wiki-gpio上的放法一样
#define    LED_TRIGGER    "/sys/class/leds/ld2:red/trigger"              //对LED的操作,和wiki-gpio上的方法一样
#define    INPUT_EVENT    "/dev/event0"           //这个路径具体要看实际情况,wiki上的是/dev/input/event0.
#define    LED_MAX_SPEED    10
#define    PERIOD_COEFF    16000
 
unsigned int led_speed;
pthread_mutex_t lock;
 
/* Blink LED */
static void *LEDMod(void *dummy)
{
    unsigned int led_period;
    int tmp;
    tmp = open(LED_BRIGHTNESS, O_WRONLY);
    if (tmp < 0)
        exit(1);
    while (1) {
        pthread_mutex_lock(&lock);            //在线程中,通过互斥锁mutex对LED持续点亮时间进行更改
        led_period = (LED_MAX_SPEED - led_speed) * PERIOD_COEFF;
        pthread_mutex_unlock(&lock);
 
        write(tmp, "1", 2);                            //点亮LED灯
        usleep(led_period);
        write(tmp, "0", 2);                            //熄灭LED灯
        usleep(led_period);        
    }
}
 
int main()
{
    pthread_t pth;
    struct input_event ev;                    //输入事件数据结构,包括value,type,code等。
    int tmp;                                          //有按键输入时,value为1,当检测为键盘输入时,type为1,code返回按键对应的数值
    int key_code;
    int size = sizeof(ev);
 
    /* Configure LED */
    led_speed = 5;
    tmp = open(LED_TRIGGER, O_WRONLY);
    if (tmp < 0)
        return 1;
    if (write(tmp, "default-on", 10) != 10) {
        printf("Error writing trigger");
        return 1;
    }
    close(tmp);
    printf("Configured LED for use\n");
 
    /* Create thread */
    pthread_mutex_init(&lock, NULL);
    pthread_create(&pth, NULL, LEDMod, "Blinking LED...");
 
    /* Read event0 */
    tmp = open(INPUT_EVENT, O_RDONLY);
    if (tmp < 0) {
        printf("\nOpen " INPUT_EVENT " failed!\n");
        return 1;
    }
    /* Read and parse event, update global variable */
    while (1) {

        if (read(tmp, &ev, size) < size) {    //采用polled方式,所以在没有按键时,是不会继续往下执行程序的
                                                               //只用在read函数返回数值后,才会继续执行。
            printf("\nReading from " INPUT_EVENT " failed!\n");
            return 1;

        }
/*       printf("value: %d ; type : %d \n" , ev.value, ev.type);    //我尝试在此处加入这个函数,想知道如果一直按着BTN不放,会输出什么值,结果显示 value 与 type 的值不断的从0到2循环改变,但是 value==1,type==1的情况只出现了一次。使我们一次按键只执行一次对应的程序。
*/
            if (ev.value == 1 && ev.type == 1) {    /* Down press only */
            key_code = ev.code;
            if (key_code == KEY_DOWN) {    /* lower speed */
                /* Protect from concurrent read/write */
                pthread_mutex_lock(&lock);
                if (led_speed > 0)
                    led_speed -= 1;
                pthread_mutex_unlock(&lock);
            } else if (key_code == KEY_UP) {    /* raise speed */
                pthread_mutex_lock(&lock);
                if (led_speed < 9)
                    led_speed += 1;
                pthread_mutex_unlock(&lock);
            }
            printf("Speed: %i\n", led_speed);
            usleep(1000);
        }
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux zedboard gpio