我正在使用 i.mx6quad 和 debian jessie (3.14.60-fslc-imx6-sr)。
我想将 ov5642 摄像头模块与 PARALLEL 8BIT 接口共同连接(使用 8gpios 用于数据,3 用于控制信号)。我编写了一个 linux 内核模块来服务来自控制信号的中断。来自 VSYNC 和 HREF 信号的中断得到了正确处理,但是当我连接一个比 HREF 或 VSYNC 快得多的 PCLK(大约 8MHz)信号时,我的 linux 会挂起,直到我断开与 PCLK 的电线(一切都卡住了)。要连接 PCLK,我使用 GPIO90 (DISP1_DATA22),但我也尝试使用其他 gpios。
现在我的问题是我应该使用哪个 GPIO 来正确地服务像 PCLK 这样的快速信号,或者我可以做些什么来避免 linux 挂断?
我包含了一个我使用的 linux 内核模块代码。
#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/gpio.h>
#include<linux/interrupt.h>
static unsigned int VSYNC_gpio_number=79;
static unsigned int HREF_gpio_number=76;
static unsigned int PCLK_gpio_number=90;
static unsigned int VSYNC_irqNumber;
static unsigned int HREF_irqNumber;
static unsigned int PCLK_irqNumber;
static irq_handler_t VSYNC_gpio_irq_handler(unsigned int irq,void *dev_id,struct pt_regs *regs);
static irq_handler_t HREF_gpio_irq_handler(unsigned int irq,void *dev_id,struct pt_regs *regs);
static irq_handler_t PCLK_gpio_irq_handler(unsigned int irq,void *dev_id,struct pt_regs *regs);
int __init camera_module_test_init(void){//init_module()
int result=0;
printk(KERN_INFO "GPIO_TEST: Initializing the GPIO_TEST LKM\n");
//VSYNC init
if(!gpio_is_valid(VSYNC_gpio_number)){
printk(KERN_INFO "GPIO TEST: invalid VSYNC GPIO\n");
return -ENODEV;
}
//HREF init
if(!gpio_is_valid(HREF_gpio_number)){
printk(KERN_INFO "GPIO TEST: INVALID HREF GPIO\n");
return -ENODEV;
}
//PCLK init
if(!gpio_is_valid(PCLK_gpio_number)){
printk(KERN_INFO "GPIO TEST: INVALID PCLK GPIO\n");
return -ENODEV;
}
//ledOn=true;
//VSYNC
gpio_request(VSYNC_gpio_number,"sysfs");
gpio_direction_input(VSYNC_gpio_number);
gpio_export(VSYNC_gpio_number,false); // causes gpioX to appear in sysfs /sys/class/gpio/
//HREF
gpio_request(HREF_gpio_number,"sysfs");
gpio_direction_input(HREF_gpio_number);
gpio_export(HREF_gpio_number,false);
//PCLK
gpio_request(PCLK_gpio_number,"sysfs");
gpio_direction_input(PCLK_gpio_number);
gpio_export(PCLK_gpio_number,false);
// GPIO numbers and IRQ numbers are not the same
//MAPPING GPIO NUMBERS TO IRQ NUMBERS
//---------
VSYNC_irqNumber = gpio_to_irq(VSYNC_gpio_number);
printk(KERN_INFO "GPIO_TEST: VSYNC signal is mapped to IRQ: %d\n",VSYNC_irqNumber);
//
HREF_irqNumber=gpio_to_irq(HREF_gpio_number);
printk(KERN_INFO "GPIO TEST: HREF signal is mapped to IRQ: %d\n",HREF_irqNumber);
//
PCLK_irqNumber=gpio_to_irq(PCLK_gpio_number);
printk(KERN_INFO "GPIO TEST: PCLK signal is mapped to IRQ: %d\n",PCLK_irqNumber);
//requests an interrupt line
//VSYNC
result=request_irq(VSYNC_irqNumber,(irq_handler_t)VSYNC_gpio_irq_handler,IRQF_TRIGGER_RISING,"VSYNC_gpio_handler",NULL);
if(result==0){ //if success
printk(KERN_INFO "GPIO_TEST: The VSYNC interrupt request result is: %d\n",result);
}
else{
printk(KERN_INFO "GPIO_TEST: The VSYNC interrupt request FAIL !!! (%d)\n",result);
return result;
}
//HREF
result=request_irq(HREF_irqNumber,(irq_handler_t)HREF_gpio_irq_handler,IRQF_TRIGGER_RISING,"HREF_gpio_handler",NULL);
if(result==0){ //if success
printk(KERN_INFO "GPIO_TEST: The HREF interrupt request result is: %d\n",result);
}
else{
printk(KERN_INFO "GPIO_TEST: The HREF interrupt request FAIL !!! (%d)\n",result);
return result;
}
//PCLK
result=request_irq(PCLK_irqNumber,(irq_handler_t)PCLK_gpio_irq_handler,IRQF_TRIGGER_RISING,"PCLK_gpio_handler",NULL);
if(result==0){// if success
printk(KERN_INFO "GPIO_TEST: The PCLK interrupt request result is: %d\n",result);
}
else{
printk(KERN_INFO "GPIO_TEST: The PCLK interrupt request FAIL !!! (%d)\n",result);
return result;
}
printk(KERN_INFO "MODULE LOADED.... WAITING FOR INTERRUPTION\n");
return result;
}
static void __exit camera_module_test_exit(void){ //cleanup_module(void){
printk(KERN_INFO "EXITING CAMERA_LKM_MODULE_TEST\n");
//unexporting GPIOs
gpio_unexport(VSYNC_gpio_number);
gpio_unexport(HREF_gpio_number);
gpio_unexport(PCLK_gpio_number);
//freeing IRQs
free_irq(VSYNC_irqNumber,NULL);
free_irq(HREF_irqNumber,NULL);
free_irq(PCLK_irqNumber,NULL);
//freeing memory
gpio_free(VSYNC_gpio_number);
gpio_free(HREF_gpio_number);
gpio_free(PCLK_gpio_number);
printk(KERN_INFO "GOODBYE world - MODULE CLOSED\n");
}
static irq_handler_t VSYNC_gpio_irq_handler(unsigned int irq,void *dev_id,struct pt_regs *regs){
printk(KERN_INFO "* VSYNC Interrupt on rising! *\n");
return (irq_handler_t)IRQ_HANDLED;
}
static irq_handler_t HREF_gpio_irq_handler(unsigned int irq,void *dev_id,struct pt_regs *regs){
printk(KERN_INFO "-- HREF interrupt! on rising --\n");
return (irq_handler_t)IRQ_HANDLED;
}
static irq_handler_t PCLK_gpio_irq_handler(unsigned int irq,void *dev_id,struct pt_regs *regs){
printk(KERN_INFO "// PCLK interrupt! on rising //\n");
return (irq_handler_t)IRQ_HANDLED;
}
module_init(camera_module_test_init);
module_exit(camera_module_test_exit);
MODULE_LICENSE("GPL");
我可以补充一点,我正在使用带有可用 gpios 的蜂板门,如附图所示。