Hi,
Can you please help me to get IRQ number for VF61 module on linux Platform
Can you please provide some more details? What is image version on the module? What exactly is your requirement? IRQ information for different peripherals can be found in Section 3.2.4 of Vybrid Techincal Reference Manual.
Dear Sanchayan, We want to implement interrupt on toradex Colibri VF61. We followed following link to implement interrupt. How to use Interrupt library | Toradex Developer Center There they explained everything for Windows CE platform. We are looking for Linux Plateform and they have given following steps to implement the interrupt, Procedure
The sequential process followed in the demo is:
Set SODIMM_101 (connected to SW5) and SODIMM_135 (connected to LED1) as GPIO input and GPIO output respectively.
****Get Interrupt number for GPIO number (for SODIMM_101).****
Configure interrupt to detect rising edge.
Create an event or check for an existing event for which the system will wait.
Get the corresponding System Interrupt number for the Interrupt number obtained in step 2.
Link the event created in step 4 with System Interrupt obtained in step 5.
If the event occurs, the system asks if it should continue waiting. On choosing "Yes" it changes the status of LED (ON or OFF).
Else on choosing "No", interrupt is de-initialized.
How to get the interrupt number for GPIO and how to implement this in C code. Kindly PLease help me on this.
I am looking for your reply.
Linux being a monolithic kernel does not allow handling interrupts directly in user space. poll or select can be used, see the documentation here.
There are also two other approaches using gpio-keys and uio. Also please refer our developer article on GPIO.
Dear Sanchayan,
I wrote the following C code to implement Interrupt(not going to handle)
#include
#include
#include
#include
#include
#include
int main()
{
printf("Code Starts here \n");
int fd = open("/dev/uio0", O_RDWR);
printf("file is opened %d \n", fd);
if (fd < 0)
{
printf("Error in opening file");
return (-1);
}
while (1)
{
uint32_t info = 1; // unmask /
ssize_t nb = write(fd, &info, sizeof(info));
//printf("Unmasking is done %d %d\n", nb,sizeof(info));
if (nb < sizeof(info))
{
printf("Error in file writing");
close(fd);
return (-1);
}
//Wait for interrupt
//printf("waiting for interrupt\n");
nb = read(fd, &info, sizeof(info));
printf("Value of nb %d \n", nb);
if (nb == sizeof(info))
{
// Do something in response to the interrupt.
printf("Interrupt #%u!\n", info);
}
}
close(fd);
//exit(EXIT_SUCCESS);
return 0;
}
following condition is not satisfying
if (nb == sizeof(info))
nb value is always -1 it is not become 4.
then I tried to see the IRQ number in /proc/interrupts but it is not showing my IRQ(UIO) number.
at the same time i enabled UIO driver in kernel and it is appeared in /dev/uio as well as /sys/class/uio.
Please help me on this.
As far as I understand UIO requires device tree changes, did you applied changes to the device tree?
I would recommend to start with the first method Sanchayan suggested. The sysfs GPIO method is well tested and does not require a device tree change for most GPIO’s. This example shows how to use the sysfs approach.
Ya I changed device tree file also
I am using PB17-GPIO39 which is in GPIO Bank1
dts-v1/;
#include
#include "vf610-colibri.dtsi"
#include "vf-colibri-eval-v3.dtsi"
/ {
model = "Toradex Colibri VF61 on Colibri Evaluation Board";
compatible = "toradex,vf610-colibri_vf61-on-eval", "toradex,vf610-colibri_vf61", "fsl,vf610";
uio_pdrv_genirq
{
compatible = "uio_pdrv_genirq";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_portExpndrB>;
interrupt-parent = <&gpio1>;
debounce-interval = <50>;
interrupts = <39 IRQ_TYPE_EDGE_FALLING>;
};
};
&iomuxc
{
vf610-colibri
{
pinctrl_portExpndrB: userInterrupt
{
fsl,pins = < VF610_PAD_PTB17__GPIO_39 0x21ad>;
};
};
};
this is my device tree changes and i configured following line in colibri_vf_defconfig file
CONFIG_UIO=y
CONFIG_UIO_PDRV_GENIRQ=y
Please let me know that above changes are correct.
Meanwhile I will work with your code also.
Dear Stefan,
I would like to ask one more Question,
Will IRQ number and interrupt name (like UIO0) be appeared in /proc/interrupts.
My UIO interrupt is not showing here. Is it wrong. Kindly let me know
CPU0
16: 8743 GIC 27 Edge gt
17: 43332 vf610-gpc 8 Edge eDMA tx
18: 0 vf610-gpc 9 Edge eDMA err
19: 0 vf610-gpc 4 Edge SEMA4
20: 1196 vf610-gpc 61 Edge fsl-lpuart
23: 0 vf610-gpc 68 Edge 4002d000.dspi1
27: 1 vf610-gpc 53 Edge 4003b000.adc
36: 0 vf610-gpc 30 Edge fsl-dcu-fb
37: 31 vf610-gpc 71 Edge 40066000.i2c
38: 0 vf610-gpc 92 Edge wkpu-vf610
39: 0 vf610-gpc 75 Edge 40034000.usb
41: 0 vf610-gpc 100 Edge rtc alarm
42: 1 vf610-gpc 54 Edge 400bb000.adc
43: 0 vf610-gpc 28 Edge mmc0
44: 32 vf610-gpc 76 Edge 400b4000.usb
45: 1883 vf610-gpc 79 Edge 400d1000.ethernet
46: 11896 vf610-gpc 83 Edge vf610_nfc
89: 0 gpio-vf610 9 Edge Wake-Up
90: 0 gpio-vf610 10 Edge 400b2000.esdhc cd
150: 0 gpio-vf610 6 Edge usbc_det
Please use 4 spaces in front of every line for console output/device tree listings, it makes them much more readable.
I never used UIO so I can’t really tell. According to the link Sanchayan provided you need to specifiy the compatible string also when using modeprobe.
Anyway, I still recommend the GPIO sysfs approach. When setting the edge
for a GPIO it should show up in the interrupt list.
Dear Stefan,
I tested your GPIO sysfs approach and it is working but how to handle the interrupts which means in the code how to transfer my control to interrupt handler. Is it possible through sysfs approach. Kindly let me know.
As already mentioned it is not possible to have a strict traditional interrupt handler based approach like in microcontrollers. One can create a separate thread to poll on the file descriptor or multiple file descriptors on the opened GPIO sysfs path and then do the necessary operation via. that thread. The main thread or other threads can handle rest of application. Even with the uio based approach you need to resort to polling.