You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mynewt.apache.org by WangJiacheng <ji...@icloud.com> on 2017/01/28 02:38:28 UTC

interrupt latency in mynewt

Hi,

I have an interrupt triggered  by GPIO input, and observed different interrupt latency from different CPU state. If all the tasks are sleep, the interrupt latency is about 20us-30us, if the CPU is in idle mode with simple calling “__WFI()”, the interrupt latency is about 10us-15us, and if the CPU is running, the interrupt latency can be within 8us.

I do the test as following, create a low priority task with 3 case:

1), the task loop is like
while (1){
   /* keep the task in sleep mode, the interrupt will be 20us-30us */
    os_time_delay(OS_TICKS_PER_SEC);
}

2). the task loop is like
while (1){
   /* put the CPU in idle mode by simple calling WFI, the interrupt will be 10us-150us */
    __WFI;
}

3). the task loop is like
while (1){
   /* keep the CPU always running, the interrupt will be within 8us */
   os_cputime_delay_usecs(1000000);
}

Any idea to reduce the interrupt latency from all tasks are in sleep mode? or there is a hard limitation of interrupt response time?

Thanks,

Jiacheng

Re: interrupt latency in mynewt

Posted by WangJiacheng <ji...@icloud.com>.
Hi Will,

Some details of my use case. the GPIO is a data I/O pin, by default the GPIO is in high state, if there are some data bytes output, each byte is started with an initial zero bit (GPIO low state), so I use GPIOTE of nRF52 to trigger the byte read event as:

	/* GPIOTE channel 2, phone DATA pin GPIOTE event */
	NRF_GPIOTE->CONFIG[2] =  (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos)
	                           | (PIN_DATA_PHONE << GPIOTE_CONFIG_PSEL_Pos)
	                           | (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);

	NRF_GPIOTE->INTENSET  |= GPIOTE_INTENSET_IN2_Set << GPIOTE_INTENSET_IN2_Pos;

The byte read is in ISR and tested with different interrupt priority (even with the highest interrupt priority 0 and modify the Radio priority to 2), the latency performance is the same. I also tested that in the ISR only trigger a semaphore and the byte read is in a mynewt task, the result is the same.  

The interrupt latency is measured by a simple way, since each bit has 8us time duration, the latency is measured by counting how many bits I missed from the reading results. So if I get correct reading results (the case of CPU always running), I can only know the latency is within 8us and do not know the exactly interrupt response time.

I just noticed there were some discussions in Nordic’s developer zone https://devzone.nordicsemi.com/question/91596/interrupt-latency-when-running-wfiwfe/ <https://devzone.nordicsemi.com/question/91596/interrupt-latency-when-running-wfiwfe/>, the interrupt latency from CPU running WFI( ) is about 12us, this is the same as my observation (10us -15us). When all the mynewt tasks are in sleep mode, it should take longer time than WFI( ) to response interrupt. 

Anyway, I have found another way to trigger the data output bytes reading event by 2 steps, the first step is by using clock signal to wake up CPU from idle model (clock signal is about 5ms-6ms earlier than data output bytes), the second step is as above, to use the initial bit to trigger byte reading.

Thanks,

Jiacheng



> 在 2017年1月29日,03:30,will sanfilippo <wi...@runtime.io> 写道:
> 
> Jiacheng:
> 
> How are you measuring the latency? I presume you have a scope on a GPIO input and maybe set a GPIO high when you are inside the ISR and measure the time between them? Or are you measuring the timing using a task? There is certainly some hard limitation on interrupt response time but I am not sure what that is for the nrf52 specifically. If you tell me exactly how you are measuring the timing, what tasks you have running and their respective priorities, I might be able to hazard a guess as to why there are differences. I would also like to know what interrupts are enabled and their priorities.
> 
> 
>> On Jan 27, 2017, at 6:38 PM, WangJiacheng <ji...@icloud.com> wrote:
>> 
>> Hi,
>> 
>> I have an interrupt triggered  by GPIO input, and observed different interrupt latency from different CPU state. If all the tasks are sleep, the interrupt latency is about 20us-30us, if the CPU is in idle mode with simple calling “__WFI()”, the interrupt latency is about 10us-15us, and if the CPU is running, the interrupt latency can be within 8us.
>> 
>> I do the test as following, create a low priority task with 3 case:
>> 
>> 1), the task loop is like
>> while (1){
>>  /* keep the task in sleep mode, the interrupt will be 20us-30us */
>>   os_time_delay(OS_TICKS_PER_SEC);
>> }
>> 
>> 2). the task loop is like
>> while (1){
>>  /* put the CPU in idle mode by simple calling WFI, the interrupt will be 10us-150us */
>>   __WFI;
>> }
>> 
>> 3). the task loop is like
>> while (1){
>>  /* keep the CPU always running, the interrupt will be within 8us */
>>  os_cputime_delay_usecs(1000000);
>> }
>> 
>> Any idea to reduce the interrupt latency from all tasks are in sleep mode? or there is a hard limitation of interrupt response time?
>> 
>> Thanks,
>> 
>> Jiacheng
> 


Re: interrupt latency in mynewt

Posted by will sanfilippo <wi...@runtime.io>.
Jiacheng:

How are you measuring the latency? I presume you have a scope on a GPIO input and maybe set a GPIO high when you are inside the ISR and measure the time between them? Or are you measuring the timing using a task? There is certainly some hard limitation on interrupt response time but I am not sure what that is for the nrf52 specifically. If you tell me exactly how you are measuring the timing, what tasks you have running and their respective priorities, I might be able to hazard a guess as to why there are differences. I would also like to know what interrupts are enabled and their priorities.


> On Jan 27, 2017, at 6:38 PM, WangJiacheng <ji...@icloud.com> wrote:
> 
> Hi,
> 
> I have an interrupt triggered  by GPIO input, and observed different interrupt latency from different CPU state. If all the tasks are sleep, the interrupt latency is about 20us-30us, if the CPU is in idle mode with simple calling “__WFI()”, the interrupt latency is about 10us-15us, and if the CPU is running, the interrupt latency can be within 8us.
> 
> I do the test as following, create a low priority task with 3 case:
> 
> 1), the task loop is like
> while (1){
>   /* keep the task in sleep mode, the interrupt will be 20us-30us */
>    os_time_delay(OS_TICKS_PER_SEC);
> }
> 
> 2). the task loop is like
> while (1){
>   /* put the CPU in idle mode by simple calling WFI, the interrupt will be 10us-150us */
>    __WFI;
> }
> 
> 3). the task loop is like
> while (1){
>   /* keep the CPU always running, the interrupt will be within 8us */
>   os_cputime_delay_usecs(1000000);
> }
> 
> Any idea to reduce the interrupt latency from all tasks are in sleep mode? or there is a hard limitation of interrupt response time?
> 
> Thanks,
> 
> Jiacheng