A20GPIO中斷類型差別結果迥異的問題思考
?
最近在使用全志A20做開發時,發現在處理中斷的時候,用電平觸發模式,報中斷比較亂,用邊沿觸發則很穩定,不會亂報。筆者感到比較困惑,筆者用電平觸發寫的code如下:
?
reverseHandle = sw_gpio_irq_request(gReverseCar_gpio_hdle.gpio, TRIG_LEVL_HIGH, \&sw_reverseCar_irq_Handle, &privateData);if (!reverseHandle) {printk("Failed to get gpio irq for reverse car detection\n");}privateData.trigtype = TRIG_LEVL_HIGH;static int sw_reverseCar_irq_Handle(void *para){printk("IRQ sw_reverseCar_irq: %d ", privateData.trigtype);printk("IO:%d, value:%d\n",gReverseCar_gpio_hdle.gpio, \__gpio_get_value(gReverseCar_gpio_hdle.gpio));sw_gpio_eint_set_enable(gReverseCar_gpio_hdle.gpio, 0);sw_gpio_eint_clr_irqpd_sta(gReverseCar_gpio_hdle.gpio);//TRIG_LEVL_LOW TRIG_LEVL_HIGH TRIG_EDGE_POSITIVE TRIG_EDGE_NEGATIVEif(privateData.trigtype == TRIG_LEVL_HIGH) {if(0 == sw_gpio_eint_set_trigtype(gReverseCar_gpio_hdle.gpio,TRIG_LEVL_LOW))privateData.trigtype = TRIG_LEVL_LOW;} else if(privateData.trigtype == TRIG_LEVL_LOW) {if(0 == sw_gpio_eint_set_trigtype(gReverseCar_gpio_hdle.gpio,TRIG_LEVL_HIGH))privateData.trigtype = TRIG_LEVL_HIGH;}sw_gpio_eint_set_enable(gReverseCar_gpio_hdle.gpio, 1);return 0;
}
?
中斷類型設置成DEBO中斷打印信息有問題,具體如下:
?
root@android:/ # [ 519.018955] IRQ sw_reverseCar_irq: 2 IO:188, value:1
[ 519.024773] IRQ sw_reverseCar_irq: 3 IO:188, value:1
[ 519.030576] IRQ sw_reverseCar_irq: 2 IO:188, value:1
[ 519.036378] IRQ sw_reverseCar_irq: 3 IO:188, value:1
[ 519.042169] IRQ sw_reverseCar_irq: 2 IO:188, value:1[ 520.898643] IRQ sw_reverseCar_irq: 3 IO:188, value:0
[ 520.904456] IRQ sw_reverseCar_irq: 2 IO:188, value:0
[ 520.910363] IRQ sw_reverseCar_irq: 3 IO:188, value:0
[ 520.916215] IRQ sw_reverseCar_irq: 2 IO:188, value:0
[ 520.921995] IRQ sw_reverseCar_irq: 3 IO:188, value:0
[ 520.927832] IRQ sw_reverseCar_irq: 2 IO:188, value:0
[ 520.933612] IRQ sw_reverseCar_irq: 3 IO:188, value:0
[ 520.939432] IRQ sw_reverseCar_irq: 2 IO:188, value:0
[ 520.945317] IRQ sw_reverseCar_irq: 3 IO:188, value:0
?
? ? ? ? ? 用邊沿觸發寫的code如下,
?
gPrivData.trigtype = TRIG_EDGE_POSITIVE;gPrivData.irqReqHandle = sw_gpio_irq_request(gPrivData.gpio_hdle.gpio, TRIG_EDGE_POSITIVE, \(peint_handle)&sw_reverseCar_irq_Handle, (void *)&gPrivData);
static int sw_reverseCar_irq_Handle(void *para){//printk("IRQ sw_reverseCar_irq: %d ", gPrivData.trigtype);gPrivData.CarStatus = __gpio_get_value(gPrivData.gpio_hdle.gpio);//printk("io:%d, value:%d\n",gPrivData.gpio_hdle.gpio, gPrivData.CarStatus);/*if app has no capacity for handle reverse event, system need reboot*/if(1 == gPrivData.needRebootFlag) {printk("Reboot for handle reverse in boot now!\n");*(volatile __u32 *)(0xf1c20c94) = 0x3; }up(&gPrivData.sem_lock);sw_gpio_eint_set_enable(gPrivData.gpio_hdle.gpio, 0);sw_gpio_eint_clr_irqpd_sta(gPrivData.gpio_hdle.gpio);if(gPrivData.trigtype == TRIG_EDGE_POSITIVE) {if(0 == sw_gpio_eint_set_trigtype(gPrivData.gpio_hdle.gpio,TRIG_EDGE_NEGATIVE))gPrivData.trigtype = TRIG_EDGE_NEGATIVE;} else if(gPrivData.trigtype == TRIG_EDGE_NEGATIVE) {if(0 == sw_gpio_eint_set_trigtype(gPrivData.gpio_hdle.gpio,TRIG_EDGE_POSITIVE))gPrivData.trigtype = TRIG_EDGE_POSITIVE;}sw_gpio_eint_set_enable(gPrivData.gpio_hdle.gpio, 1);return 0;
}
?
?? EDGE時還可以設置中斷類型為TRIG_EDGE_DOUBLE,筆者暫時沒有采用,中斷打印信息正常,如下:
?
root@android:/ # [ 517.116361] IRQ sw_reverseCar_irq: 0 io:188, value:1
[ 518.103095] IRQ sw_reverseCar_irq: 1 io:188, value:0root@android:/ # [ 520.918512] IRQ sw_reverseCar_irq: 0 io:188, value:1
[ 521.876038] IRQ sw_reverseCar_irq: 1 io:188, value:0
[ 527.796107] IRQ sw_reverseCar_irq: 0 io:188, value:1
[ 528.843397] IRQ sw_reverseCar_irq: 1 io:188, value:0
[ 531.335858] IRQ sw_reverseCar_irq: 0 io:188, value:1
[ 532.306660] IRQ sw_reverseCar_irq: 1 io:188, value:0
[ 534.552011] IRQ sw_reverseCar_irq: 0 io:188, value:1
[ 535.101586] IRQ sw_reverseCar_irq: 1 io:188, value:0
?
? ? ? ? ?筆者不清楚原因,懷疑是芯片驅動的問題,但是驅動也就那樣寫了啊,難道是芯片設計的問題,當然這種也就是在剛有中斷時會有亂irq上來,如果用delaywork延時一下處理也是可以繞過去的。望哪位大俠清楚的解釋一下。
?