spiService and gpioService are not starting within an Application

Hi,
I want to start the gpioService and the spiService together with my application, but both are never started. Here is my .adef:

sandboxed: false

executables:
{
	spiMultiTest = ( spiMultiTest )
	spiService = ( $LEGATO_ROOT/components/spiService )
	gpioService = ( $LEGATO_ROOT/components/sysfsGpio )
}

processes:
{
	priority: rt32
	run:
	{
		( spiService )
		( gpioService )
		( spiMultiTest )
	}

    watchdogTimeout: never
}

So why is the spiMultiTest starting, but the spiService and gpioService are not started?

Regards,
Simon

They are already included in the platform services application

For example, you should use IPC to communicate with gpioService

Hi,

I’m aware that they are already included in the platform services.

To give you a bigger picture of what I’m trying to achieve:

  1. A GPIO triggers reading from SPI via interrupt
  2. The latency between the trigger from GPIO and the SPI chip select is around 3-4 ms, which is way to long for our use-case.
  3. We need at least 1ms latency to have enough time to read all of the SPI data

So what I thought:

  1. In the docs, IPC is listed to be a function call when components are packed together instead of a socket call.
  2. I wanted to test if the function call is way faster than the socket, this is why I wanted to start gpioService, spiService and my own app together.

Is there a better way to do that? How can I get the lowest latency?

Thanks,
Simon

have you tried to implement this in kernel driver module?

Here is an example on using GPIO interrupt on kernel driver module:
gpio_interrupt.rar (81.8 KB)

Or you can do the following to directly open the SPI port (/dev/spidev1.0) inside your application instead of calling spiService :

root@swi-mdm9x28-wp:~# insmod /mnt/legato/system/modules/spisvc.ko
root@swi-mdm9x28-wp:~# ls /dev/spidev1.0
/dev/spidev1.0

You can see here as example:
https://www.programmersought.com/article/45661779830/

No, I haven’t tried a kernel module yet, but that would be the next thing I’d try.

What do you think is the bottleneck for my use-case? IPC, SPI or GPIO?
Do you know how much latency is caused by the IPC?

Thanks,
Simon

I do not have the exact statistic on the timing on these SPI,GPIO, IPC module.

But I can share my experience with you in this aspect.

I tried to write a legato application to toogle the GPIO state every 250 usec in order to generate a PWM signal of 2000Hz with IPC to GPIO service.
However, the result is that it can just generate about 950 Hz signal.
Not even meeting half of the requirement…

Later I tried to implement the PWM signal by kernel driver module with hardware kernel timer.
The performance is quite good that it can achieve 1.8KHz.

So to reduce latency, I would suggest you making a try on kernel driver module.

Hi,
I want to try a kernel module and I’m using the code in gpio_interrupt.rar.

In the code is a comment that says “LED is 42, mdm_GPIO=79”

Can you tell me where I can find the pin mapping for mangoYellow? Especially for IOT0 connector?

Regards,
Simon

You can check in dmesg to know the mdm gpio number when you export the gpio

Hi,
I build the code from gpio_interrupt.rar but it is crashing the module (WP7607) and I can’t retrieve any logs why it crashed.

The problem seems to be the call of the function request_irq().

Do you have any idea why?

Which gpio are you using?
Did you check in product technical specification if this gpio can be set to interrupt?

I haven’t changed anything from your code. The GPIO is 79, which should be le_gpio42, right?
I also already used it in my test code with the gpioService and was able to get an interrupt.

I just found out, that the request_irq doesn’t seem to be the problem. It’s crashing when I change the GPIO level. So something in calling ebbgpio_irq_handler seems to cause the problem

You can clear the code inside the handler and see what happens

That’s what I did :slight_smile: Now it’s working.

The problem seems to be in these lines:

	struct task_struct* t;
	/* find the task with that pid */
	t = pid_task(find_pid_ns(TargetPID, &init_pid_ns), PIDTYPE_PID);
	send_sig(SIGINT, t, 0);

One of these functions crashed the module. Since I don’t need them, I don’t care, but maybe you can fix that before sending it to the next guy that also will waste time on that.

Regards,
Simon

oh yes, you need to delete it.

That part is originally used to wake up a legato application (e.g. hello2)


1. run the following command to find out the pid of hello2
ps aux | grep hello2
root 1899 0.0 0.5 2932 996 ? S 05:37 0:00 hello2 


2. echo 1899 > /sys/module/helloworld/parameters/TargetPID