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);
}
}
}
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);
}
}
}
相关文章推荐
- AM3359 gpio 应用程序调试记录,驱动代码后续给出
- GPU应用程序Attach调试记录
- STM32调试记录-JTAG接口当作普通GPIO使用
- GPU应用程序Attach调试记录
- GPU应用程序Attach调试记录
- MT6735平台GPIO中断调试记录
- 无法在web服务上启动调试,你不具备调试应用程序的权限
- ASP.NET调试应用程序的方法和技巧
- 调试opencv程序显示应用程序无法正常启动,0xc000007b
- 如何在真机上调试Android应用程序(图文详解)
- 【记录】调试千兆以太网PHY芯片DP83865的痛苦经历
- Android BCM4330 蓝牙BT驱动调试记录
- 和菜鸟一起学android4.0.3源码之touchscreen配置+调试记录
- C#应用程序调试-调试的必要性
- gdb(ddd,kdevelop等)调试ZeroIce开发的应用程序,中断信号引起的问题
- 使用 IntelliTrace(智能跟踪) 调试应用程序
- 用 Firebug 动态调试和优化应用程序
- ThinkPHP调试模式与日志记录概述
- global文件里Application_Error方法处理记录应用程序错误日志
- 基于WinCE 6.0模拟器的应用程序调试