[英]how to detect a pin change of a GPIO on Linux board
我在基於ARM的linux板(imx233 CPU)上使用3.12內核。 我的目的是檢測GPIO的引腳變化(1到0)。
我可以不斷調用下面的函數讀取引腳值(在while(1)循環中)
int GPIO_read_value(int pin){
int gpio_value = 0;
char path[35] = {'\0'};
FILE *fp;
sprintf(path, "/sys/class/gpio/gpio%d/value", pin);
if ((fp = fopen(path,"rb+")) == NULL){ //echo in > direction
//error
}
fscanf(fp, "%d", &gpio_value);
fclose(fp);
return gpio_value;
}
但它會給CPU帶來太多負載。 我不使用usleep
或nanosleep
,因為引腳更改會在很短的時間內發生,這會導致我錯過事件。
據我所知,不可能使用poll()
。 是否有任何poll()
函數可用於檢測GPIO的引腳變化?
編輯:以防萬一,如果我做錯了,這是我的poll()
用法,不檢測引腳更改
struct pollfd pollfds;
int fd;
int nread, result;
pollfds.fd = open("/sys/class/gpio/gpio51/value", O_RDWR);
int timeout = 20000; /* Timeout in msec. */
char buffer[128];
if( pollfds.fd < 0 ){
printf(" failed to open gpio \n");
exit (1);
}
pollfds.events = POLLIN;
printf("fd opens..\n");
while (1)
{
result = poll (&pollfds, 0, timeout);
switch (result)
{
case 0:
printf ("timeout\n");
break;
case -1:
printf ("poll error \n");
exit (1);
default:
printf("something is happening..\n");
if (pollfds.revents & POLLIN)
{
nread = read (pollfds.fd, buffer, 8);
if (nread == 0) {
printf ("result:%d\n", nread);
exit (0);
} else {
buffer[nread] = 0;
printf ("read %d from gpio: %s", nread, buffer);
}
}
}
}
close(fd);
EDIT2: https : //developer.ridgerun.com/wiki/index.php/Gpio-int-test.c上的代碼與poll()
一起工作正常我需要定義中斷的上升沿/下降沿和一點點修復定義。 它解決了我的問題,然而,對我和其他一些人來說,聽聽/了解替代方法可能會有好處。
我之前從未見過這塊板,但是我覺得PIC完全實現了這塊板(通常就是這樣)但你必須在GPIO控制器中另外配置中斷(通常就是這樣)。 某些部分應該作為內核模塊完成,然后您必須將有關中斷的信息傳遞給您的應用程序。
這樣做的示例方法是將以下內容實現為內核模塊:
設置GPIO控制器以在特定端口和級別上啟用中斷(如何執行此操作,您可以在此處找到: http ://cache.freescale.com/files/dsp/doc/ref_manual/IMX23RM.pdf 37.2.3.3輸入中斷操作)
在PIC中啟用GPIO中斷(如何執行此操作: http : //lwn.net/images/pdf/LDD3/ch10.pdf第10章)
並在您的申請中休息:
從內核到應用程序傳遞有關中斷的信息的最簡單方法是在內核端通過信號量傳遞。 在模塊中,您可以實現一個睡眠直到中斷發生的ioctl。 所以應用程序將調用此ioctl,其線程將被阻塞,直到發生中斷。
在內部模塊中,中斷例程應檢查應用程序線程是否現在被阻止,如果是,則()信號量。
編輯*****
該CPU具有SSP,具有SPI工作模式。 為什么不使用它?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.