How much is the toplimit frequency of GPIO catch the pluse by interrupt?

How much is the toplimit frequency of GPIO catch the pluse by interrupt? I test 3khz pluse as GPIO input in interrupt, catch the pluse edg and output pluse at another GPIO in interrupt handle,I find output pluse is less than input pluse.I alse try to patch PREEMPT_RT and make the system be real-time,but output pluse is also less than input pluse。I compare output pluse numbers and interrupts numbers in /proc/interrupt,it is same.It’s seem that sometimes it doesn’t get into the interrupt handle.And is there any way to make the gpio interrupt be real_time?

The sampling freq is up to 50Khz. Have you checked the output pulse signal quality?

I compare output pluse numbers and interrupts numbers in /proc/interrupt,it is same.It’s seem that sometimes it doesn’t get into the interrupt handle.

Have you checked the output pulse signal quality?


the blue pulse is input,red pulse is output,it seems the output pulse signal quality is good. And the pulse voltage is 3.3v,both input and output

hello 1346825367,

what’s your system configuration, are you using dedicate CPU for running this?
please also try configured as MaxN for testing, thanks

hello JerryChang,

It’s tested in MaxN.And i alse test on my Xavier NX,but it’s same

below settings are available for TX2 and Xavier series, please try configure axi_cbb to get better results.
for example,

# cd sys/kernel/debug/bpmp/debug/clk/axi_cbb
# cat rate
115200000
# echo 409600000 > rate  # or,  whatever is the max rate
# echo 1 > mrq_rate_locked

Is it make cpu overclock?and is 409600000 max rate for Xavier NX?by the way,what’s the means of " 1 > mrq_rate_locked"?

I check the file "max_rate"is 204000000,but the file “rate” is already 204000000.

hello JerryChang

I have followed your tip,but it doesn’t get better.Is there any other solution?

hello 1346825367,

may I know how your test this from software point-of-view, are you using kernel APIs?
for example, how can we repo the issue locally, thanks

Yes,I using kernel APIs for my driver,and here is a part of code:

#define GPIO_OP0 194 // 40-pin PIN15
#define GPIO_OP1 200 // 40-pin PIN31
#define GPIO_OP2 149 //40-pin PIN29

static bool val=false;
static irqreturn_t irq_callback (int irq,void *dev_id){
if(val)
{

	gpio_set_value(GPIO_OP1,0);
}
if(!val)
{
	
	gpio_set_value(GPIO_OP1,1);
}
val=(!val);

return IRQ_RETVAL(IRQ_HANDLED);

}

static int __init simple_init_module(void){

int rtn;
alloc_chrdev_region(&mydev.devid, 0, CNT,NAME);

printk("newcheled major=%d,minor=%d\r\n",mydev.major,mydev.minor);
mydev.cdev.owner=THIS_MODULE;
cdev_init(&mydev.cdev,&simple_fops);
cdev_add(&mydev.cdev,mydev.devid,CNT);
mydev.class=class_create(THIS_MODULE,NAME);
if(IS_ERR(mydev.class))
{
    return PTR_ERR(mydev.class);
}
mydev.device=device_create(mydev.class,NULL,mydev.devid,NULL,NAME);
if(IS_ERR(mydev.device))
{
    return PTR_ERR(mydev.device);
}


if (!gpio_is_valid(GPIO_OP0)) {                
    printk(KERN_INFO "GPIO0 fail\n");
    return -ENODEV;
}
if (!gpio_is_valid(GPIO_OP1)) {
    printk(KERN_INFO "GPIO1 fail\n");
    return -ENODEV;
}
if (!gpio_is_valid(GPIO_OP2)) {
    printk(KERN_INFO "GPIO2 fail\n");
    return -ENODEV;
}

rtn = gpio_request(GPIO_OP0, "my_irq");
if(rtn!=0){
    printk("my_irq request io failed.\n");
}
rtn = gpio_request(GPIO_OP1, "my_out");
if(rtn!=0){
    printk("my_out request io failed.\n");
}
rtn = gpio_request(GPIO_OP2, "my_in");
if(rtn!=0){
    printk("my_in request io failed.\n");
}

gpio_direction_output(GPIO_OP1,0);
gpio_direction_input(GPIO_OP0);
gpio_direction_input(GPIO_OP2);
irq_num = gpio_to_irq(GPIO_OP0);
rtn = request_irq(irq_num, irq_callback,IRQF_TRIGGER_RISING,"my_irq", NULL);//
if (rtn<0) {
    printk("my_irq request irq false\n");
} else {
    printk("my_irq request irq success: %d\n",irq_num);
}


return 0;

}

hello 1346825367,

had you tried nice or renice to configure higher priority of your test program?
please see-also https://www.ibm.com/docs/en/aix/7.2?topic=processes-changing-priority-running-process-renice-command

hello JerryChang

I need find the PID first,but how I get the gpio interrupt driver’s PID? I use the conmand"ps aux" to cat all PID,but I don’t know which one is my driver’s PID

Is there a user space program which is using or triggering the GPIO? If so, try increasing priority (a negative nice, perhaps -4 at most) of that program. The scheduler should consider that.

Example: sudo nice -n -4 someProgram

It’s a driver program in kernel space,not a user space program

Is there any user space software which is indirectly calling the driver (one which might have priority increased)? Is the driver tied to a specific CPU core? Is any part of the driver run through ksoftirqd (software IRQ versus hardware IRQ…GPIOs must use the AON cluster for hardware IRQ, but I am hoping some of this then spins off to ksoftirqd and is not entirely restricted to one core)?

No user space software,I out pulse in driver irq function,and I already have pasted my code here.my driver doesn’t specific CPU core,but I cat /proc/interrupts and find the gpio interrupts all in CPU0. And there is no ksoftirqd in driver ,just a hardware IRQ function.By the way ,what is the meaning of"AON cluster"?

Take a look at this for hardware interrupts:
grep -i aon /proc/interrupts
(or look at it in “less /proc/interrupts”, and then search via “/aon”)

Software interrupts can migrate across CPU cores with very little hardware. Basically they need the memory controller and timers for every core, but one which handles a hardware IRQ must have a wire physically routed to a core. GPIO share this to some extent, and the cluster goes to a given core (rather than individual GPIO pins). If it is possible to migrate to another core, then the entire cluster must migrate together.

I was hoping that perhaps the driver split some of the work to a software interrupt. If all this is doing is creating an event from the GPIO when used as an interrupt, then there isn’t much reason to also generate a software interrupt. If this interrupt also did significant work (example, a trigger of a checksum and memory copy), then it might be useful to separate the “non hardware” function (that not using a hardware IRQ wire) to a software interrupt. This would mean the core which services an actual wire-based IRQ uses the least amount of time locking that core (and thus competing with other hardware IRQs). The software IRQ is free to be scheduled anywhere. Despite every GPIO using the same core via the AON cluster, that core could be helped by offloading to another core not on the AON cluster’s core. Such interrupts are scheduled by ksoftirqd, and those can be seen in programs such as htop or ps aux. Possibly those can have priority increased. Priority increase of a hardware IRQ is questionable without special realtime modifications.