As title
Situration:
1. Timer00
2. every 4us interrupt occur
result:
1. Enter Timer interrupt cost 700ns
2. Leave Timer interrupt cost 200ns
3. Totol cost: 1.04us
How to reduce inrerrupt cost from 1.04us to around 200ns?
Austin
As title
Situration:
1. Timer00
2. every 4us interrupt occur
result:
1. Enter Timer interrupt cost 700ns
2. Leave Timer interrupt cost 200ns
3. Totol cost: 1.04us
How to reduce inrerrupt cost from 1.04us to around 200ns?
Austin
This is a continuation of this thread here: https://devzone.nordicsemi.com/f/nordic-q-a/128563/nrf54l15-sb_config_bootloader_mcuboot-y-makes-main-gpio-toggle-stop.
How to reduce inrerrupt cost from 1.04us to around 200ns?
To reduce the overhead you can define your ISR as "direct" with no rescheduling on return: https://nrfconnectdocs.nordicsemi.com/ncs/latest/zephyr/kernel/services/interrupts.html#defining-a-direct-isr. Building with CONFIG_SPEED_OPTIMIZATIONS=y may also help shave off a few CPU cycles. But what I was trying to ask in the previous thread is whether you really need the timer interrupt to preempt your code. Given the short interval, it may make more sense to poll the TIMER counter register instead.
Hi Vidar
Yes, I really need the timer interrupt to preempt my code.
It is a real-time application. Because that, I have some calculate and response immidiatly.
I will try this " direct ISA". After I testing it , I will let you know the result.
Austin
Hi Vidar
I added "CONFIG_ZERO_LATENCY_IRQS=y".
And the code as below
nrfx_timer_t timer00_inst = NRFX_TIMER_INSTANCE(NRF_TIMER_INST_GET(TIMER00_IDX));
static void timer00_handler(nrf_timer_event_t event_type, void *p_context)
{
if (event_type == NRF_TIMER_EVENT_COMPARE0)
{
LED_R_toggle;
test_bit = GET_AD_IN_1_DATA;
}
}
ISR_DIRECT_DECLARE(timer00_direct_isr)
{
nrfx_timer_irq_handler(&timer00_inst);
return 0;
}
int8_t Timer00_init(void)
{
//pick 1 or 2 to test the difference
//1. use this
IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_TIMER_INST_GET(TIMER00_IDX)),
0,
nrfx_timer_irq_handler,
&timer00_inst,
0);
//2. or this
IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_TIMER_INST_GET(TIMER00_IDX)),
0,
timer00_direct_isr,
0);
uint32_t base_frequency = NRF_TIMER_BASE_FREQUENCY_GET(timer00_inst.p_reg);
nrfx_timer_config_t config = NRFX_TIMER_DEFAULT_CONFIG(base_frequency);
config.bit_width = NRF_TIMER_BIT_WIDTH_32;
config.p_context = "4us";
nrfx_timer_init(&timer00_inst, &config, timer00_handler);
nrfx_timer_clear(&timer00_inst);
uint32_t desired_ticks = nrfx_timer_us_to_ticks(&timer00_inst, TIME_TO_INT);
desired_ticks = desired_ticks + 8;
nrfx_timer_extended_compare(&timer00_inst, NRF_TIMER_CC_CHANNEL0, desired_ticks,
NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
nrfx_timer_enable(&timer00_inst);
printk("Timer status: %s\r\n",
nrfx_timer_is_enabled(&timer00_inst) ? "enabled" : "disabled");
return 0;
}
When using 1. and remark 2., the result as below. The Timer 00 cost 1.53us .

When using 2. remak 1., the result as below. The Timer 00 cost 1.595us .

Do you have better way to reduce the cost?
It seems zero latency for IRQs no work.
Austin
Hi Vidar
I added "CONFIG_ZERO_LATENCY_IRQS=y".
And the code as below
nrfx_timer_t timer00_inst = NRFX_TIMER_INSTANCE(NRF_TIMER_INST_GET(TIMER00_IDX));
static void timer00_handler(nrf_timer_event_t event_type, void *p_context)
{
if (event_type == NRF_TIMER_EVENT_COMPARE0)
{
LED_R_toggle;
test_bit = GET_AD_IN_1_DATA;
}
}
ISR_DIRECT_DECLARE(timer00_direct_isr)
{
nrfx_timer_irq_handler(&timer00_inst);
return 0;
}
int8_t Timer00_init(void)
{
//pick 1 or 2 to test the difference
//1. use this
IRQ_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_TIMER_INST_GET(TIMER00_IDX)),
0,
nrfx_timer_irq_handler,
&timer00_inst,
0);
//2. or this
IRQ_DIRECT_CONNECT(NRFX_IRQ_NUMBER_GET(NRF_TIMER_INST_GET(TIMER00_IDX)),
0,
timer00_direct_isr,
0);
uint32_t base_frequency = NRF_TIMER_BASE_FREQUENCY_GET(timer00_inst.p_reg);
nrfx_timer_config_t config = NRFX_TIMER_DEFAULT_CONFIG(base_frequency);
config.bit_width = NRF_TIMER_BIT_WIDTH_32;
config.p_context = "4us";
nrfx_timer_init(&timer00_inst, &config, timer00_handler);
nrfx_timer_clear(&timer00_inst);
uint32_t desired_ticks = nrfx_timer_us_to_ticks(&timer00_inst, TIME_TO_INT);
desired_ticks = desired_ticks + 8;
nrfx_timer_extended_compare(&timer00_inst, NRF_TIMER_CC_CHANNEL0, desired_ticks,
NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true);
nrfx_timer_enable(&timer00_inst);
printk("Timer status: %s\r\n",
nrfx_timer_is_enabled(&timer00_inst) ? "enabled" : "disabled");
return 0;
}
When using 1. and remark 2., the result as below. The Timer 00 cost 1.53us .

When using 2. remak 1., the result as below. The Timer 00 cost 1.595us .

Do you have better way to reduce the cost?
It seems zero latency for IRQs no work.
Austin