Reduce external interrupt latency
Reduce external interrupt latency
Hi,
we are doing some stuff with an external RF transceiver and need to respond to its interrupts as fast as (technically) possible. Writing into a queue in order to handle the interrupt in another task takes way too much time (about 13 us). Setting a bit and polling this bit in another task within an infinite loop is faster (2 us), but cannot be a real option, because this is waste of resources and prevents from deep sleep options. We would prefer to do some extensive stuff like SPI communication and printf's directly within the ISR, but this results in exceptions.
In Arduino, this is actually possible with a latency of 2-4 us. But we don't want to use Arduino...
What are our options?
Thank you very much in advance!
we are doing some stuff with an external RF transceiver and need to respond to its interrupts as fast as (technically) possible. Writing into a queue in order to handle the interrupt in another task takes way too much time (about 13 us). Setting a bit and polling this bit in another task within an infinite loop is faster (2 us), but cannot be a real option, because this is waste of resources and prevents from deep sleep options. We would prefer to do some extensive stuff like SPI communication and printf's directly within the ISR, but this results in exceptions.
In Arduino, this is actually possible with a latency of 2-4 us. But we don't want to use Arduino...
What are our options?
Thank you very much in advance!
Last edited by pathob on Thu Oct 19, 2017 9:03 am, edited 1 time in total.
Re: Reduce interrupt latency
Hi Pathob,
Can you please post a simplified version of the (slow) code you have.
Angus
Can you please post a simplified version of the (slow) code you have.
Angus
Re: Reduce interrupt latency
Hi Angus,
it is basically the GPIO example. I did a measurement again, the exact delay is 16 us.
We also tried it with binary semaphors, but the latency was even worse.
it is basically the GPIO example. I did a measurement again, the exact delay is 16 us.
Code: Select all
#include "esp_log.h"
#include "esp_intr_alloc.h"
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#define GPIO_IN GPIO_NUM_17
#define GPIO_OUT GPIO_NUM_16
static const char *TAG = "APP";
static QueueHandle_t intr_queue = NULL;
static void IRAM_ATTR isr_handler(void* args) {
gpio_num_t gpio_num = (gpio_num_t) args;
xQueueSendFromISR(intr_queue, &gpio_num, NULL);
}
static void IRAM_ATTR isr_task(void* pvParams) {
gpio_num_t gpio_num;
int gpio_level = 0;
while(1) {
xQueueReceive(intr_queue, &gpio_num, portMAX_DELAY);
gpio_level = gpio_get_level(gpio_num);
gpio_set_level(GPIO_OUT, gpio_level);
// ESP_LOGD(TAG, "GPIO[%d] intr, val: %d", gpio_num, gpio_level);
}
}
static void IRAM_ATTR main_task(void* pvParams) {
gpio_config_t gpio_conf;
/*
* Input pin
*/
gpio_conf.intr_type = GPIO_PIN_INTR_ANYEDGE;
gpio_conf.pin_bit_mask = BIT(GPIO_IN);
gpio_conf.mode = GPIO_MODE_INPUT;
gpio_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
gpio_config(&gpio_conf);
/*
* Output pin, "echos" input on interrupt
*/
gpio_conf.intr_type = GPIO_PIN_INTR_DISABLE;
gpio_conf.pin_bit_mask = BIT(GPIO_OUT);
gpio_conf.mode = GPIO_MODE_OUTPUT;
gpio_conf.pull_up_en = GPIO_PULLUP_DISABLE;
gpio_conf.pull_down_en = GPIO_PULLUP_DISABLE;
gpio_config(&gpio_conf);
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_IN, isr_handler, (void*) GPIO_IN);
intr_queue = xQueueCreate(10, sizeof(gpio_num_t));
xTaskCreatePinnedToCore(isr_task, "isr_task", 2048, NULL, 10, NULL, 1);
while (1) {}
}
void app_main() {
xTaskCreatePinnedToCore(main_task, "main_task", 8192, NULL, 1, NULL, 0);
}
Last edited by pathob on Thu Oct 19, 2017 9:00 am, edited 1 time in total.
Re: Reduce interrupt latency
Did you try adding a yieldfromisr
Re: Reduce interrupt latency
I tried it a while ago and caused an exception.
Re: Reduce external interrupt latency
So, today I had access to the oscilloscope again and this time I added "portYIELD_FROM_ISR" to my ISR handler so that I got the following:
The other code is equal to what I posted above.
Probably due to a release change of esp-idf (currently I'm on v2.1) the external interrupt latency without portYIELD_FROM_ISR was 18 us now. When I added portYIELD_FROM_ISR, the latency didn't get any better, but now it rarely ranges until 29 us!
We can do handling of external interrupts on an STM32Fx significantly less than 1 us (I don't have any concrete measurement right now), so please help me to improve these bad latency.
Code: Select all
static void IRAM_ATTR isr_handler(void* args) {
gpio_num_t gpio_num = (gpio_num_t) args;
xQueueSendFromISR(intr_queue, &gpio_num, NULL);
portYIELD_FROM_ISR();
}
Probably due to a release change of esp-idf (currently I'm on v2.1) the external interrupt latency without portYIELD_FROM_ISR was 18 us now. When I added portYIELD_FROM_ISR, the latency didn't get any better, but now it rarely ranges until 29 us!
We can do handling of external interrupts on an STM32Fx significantly less than 1 us (I don't have any concrete measurement right now), so please help me to improve these bad latency.
Re: Reduce external interrupt latency
It's likely too late, but you have 3 options, depending on what are your latency expectations:
- If more than 10µs is acceptable and you still want to use a FreeRTOS task, use xTaskNotifyFromISR() in place of a queue, it's much faster. BTW, don't call portYieldFromISR unconditionally. You need to use the last parameter (it's a bool) from the XXXFromISR version, and only if it's true, call portYieldFromISR. Else, you'll end up scheduling away the task that should catch the event, lowering your latency.
- If you can live with 2µs latency, move reaction code into the interrupt (got ~2µs this way, not always feasible, BTW).
- If you want less, you'll have to learn/copy from the Xtensa assembly file found in esp32 folder (dport_panic_highint_hdl.S), and write a ASM version of the xt_highint5 version. For such a simple example, you might get a huge gain, but as soon as it becomes more complex, it's much much harder to do... and maintain.
Re: Reduce external interrupt latency
It is a waste of processor time but is fast:
1) Start a task "Test" on core 1. In Test disable interrupts. All other tasks run on core 0 - where interrupts are allowed.
2) In program "Test" do an endless loop (which is never interrupted by a tick), which reads one (or more) pins.
Use the gpio- registers directly.
Watchdog for core 1 should be disabled. (menuconfig)
3) Echo the level of the tested pin to an output pin.
I tested a delay of 160ns. I think, this value is hard to beat with an interrupt routine. And the best: no assembler needed.
1) Start a task "Test" on core 1. In Test disable interrupts. All other tasks run on core 0 - where interrupts are allowed.
2) In program "Test" do an endless loop (which is never interrupted by a tick), which reads one (or more) pins.
Use the gpio- registers directly.
Watchdog for core 1 should be disabled. (menuconfig)
3) Echo the level of the tested pin to an output pin.
I tested a delay of 160ns. I think, this value is hard to beat with an interrupt routine. And the best: no assembler needed.
Fast is not fast enough
Re: Reduce external interrupt latency to 160 nanos
/*
* FastIRQ
*
* Copyright (c) 2019, Dipl. Phys. Helmut Weber.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Helmut Weber ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the CoopOS library.
*
* Author: Helmut Weber <Dph.HelmutWeber@web.de>
*
* $Id: Task.h,v 1.1 2019/04/02 helmut Exp $
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/portmacro.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "esp_task_wdt.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "rom/uart.h"
#include "driver/touch_pad.h"
#include "driver/gpio.h"
// Dimensions the buffer that the task being created will use as its stack.
// NOTE: This is the number of bytes the stack will hold, not the number of
// words as found in vanilla FreeRTOS.
#define STACK_SIZE 4096
// Structure that will hold the TCB of the task being created.
StaticTask_t xTaskBuffer;
// Buffer that the task being created will use as its stack. Note this is
// an array of StackType_t variables. The size of StackType_t is dependent on
// the RTOS port.
StackType_t xStack[ STACK_SIZE ];
#define PinA GPIO_NUM_18 // output shortcut > _____
#define PinB GPIO_NUM_19 // input < _____|----- scope
TaskHandle_t xHandle1 = NULL;
TaskHandle_t xHandle2 = NULL;
inline uint32_t IRAM_ATTR micros()
{
uint32_t ccount;
asm volatile ( "rsr %0, ccount" : "=a" (ccount) );
return ccount;
}
void IRAM_ATTR delayMicroseconds(uint32_t us)
{
if(us){
uint32_t m = micros();
while( (micros() - m ) < us ){
asm(" nop");
}
}
}
void Core1( void* p) {
gpio_set_direction(PinA, GPIO_MODE_OUTPUT);
gpio_set_direction(PinB, GPIO_MODE_INPUT );
printf("Start Core 1\n");
vTaskDelay(1000);
// I do not want an RTOS-Tick here
portDISABLE_INTERRUPTS(); // YEAH
while(1) {
register int level;
level=REG_READ(GPIO_IN_REG) & (1<< PinB );
if (level) {
// set the pinA (set in RTOS_2) to LOW as fast as possible
REG_WRITE(0x3ff4400c, 1<<PinA);// Low at 160 ns
REG_WRITE(0x3ff44008, 1<<PinA);// HIGH ~70ns
REG_WRITE(0x3ff4400c, 1<<PinA);// Low
}
}
}
// Function that creates a task to be pinned at Core 1
void StartCore1( void )
{
TaskHandle_t xHandle = NULL;
xHandle = xTaskCreateStaticPinnedToCore(
Core1, // Function that implements the task.
"Core1", // Text name for the task.
STACK_SIZE, // Stack size in bytes, not words.
( void * ) 1, // Parameter passed into the task.
//tskIDLE_PRIORITY,// Priority at which the task is created.
tskIDLE_PRIORITY+20,
xStack, // Array to use as the task's stack.
&xTaskBuffer, // Variable to hold the task's data structure.
1); // Core 1
}
void RTOS_1(void *p) {
while(1) {
printf("RTOS-1\n"); // demo for full function
vTaskDelay(1000);
}
}
void RTOS_2(void *p) {
while(1) {
//printf("RTOS-2\n");
gpio_set_level(PinA, 1);
vTaskDelay(1);
gpio_set_level(PinA, 0); // should not happen - Core1 should do it much faster !
vTaskDelay(10);
}
}
void app_main(void)
{
gpio_set_direction(PinA, GPIO_MODE_OUTPUT);
gpio_set_direction(PinB, GPIO_MODE_INPUT );
xTaskCreate(
RTOS_1, // Function that implements the task.
"RTOS-1", // Text name for the task.
STACK_SIZE, // Stack size in bytes, not words.
( void * ) 1, // Parameter passed into the task.
tskIDLE_PRIORITY+2,
&xHandle1); // Variable to hold the task's data structure.
xTaskCreate(
RTOS_2, // Function that implements the task.
"RTOS-2", // Text name for the task.
STACK_SIZE, // Stack size in bytes, not words.
( void * ) 1, // Parameter passed into the task.
tskIDLE_PRIORITY+2,
&xHandle2); // Variable to hold the task's data structure.
StartCore1();
while(1) {
vTaskDelay(10000);
}
}
* FastIRQ
*
* Copyright (c) 2019, Dipl. Phys. Helmut Weber.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Helmut Weber ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the CoopOS library.
*
* Author: Helmut Weber <Dph.HelmutWeber@web.de>
*
* $Id: Task.h,v 1.1 2019/04/02 helmut Exp $
*/
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/portmacro.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "esp_task_wdt.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "driver/uart.h"
#include "rom/uart.h"
#include "driver/touch_pad.h"
#include "driver/gpio.h"
// Dimensions the buffer that the task being created will use as its stack.
// NOTE: This is the number of bytes the stack will hold, not the number of
// words as found in vanilla FreeRTOS.
#define STACK_SIZE 4096
// Structure that will hold the TCB of the task being created.
StaticTask_t xTaskBuffer;
// Buffer that the task being created will use as its stack. Note this is
// an array of StackType_t variables. The size of StackType_t is dependent on
// the RTOS port.
StackType_t xStack[ STACK_SIZE ];
#define PinA GPIO_NUM_18 // output shortcut > _____
#define PinB GPIO_NUM_19 // input < _____|----- scope
TaskHandle_t xHandle1 = NULL;
TaskHandle_t xHandle2 = NULL;
inline uint32_t IRAM_ATTR micros()
{
uint32_t ccount;
asm volatile ( "rsr %0, ccount" : "=a" (ccount) );
return ccount;
}
void IRAM_ATTR delayMicroseconds(uint32_t us)
{
if(us){
uint32_t m = micros();
while( (micros() - m ) < us ){
asm(" nop");
}
}
}
void Core1( void* p) {
gpio_set_direction(PinA, GPIO_MODE_OUTPUT);
gpio_set_direction(PinB, GPIO_MODE_INPUT );
printf("Start Core 1\n");
vTaskDelay(1000);
// I do not want an RTOS-Tick here
portDISABLE_INTERRUPTS(); // YEAH
while(1) {
register int level;
level=REG_READ(GPIO_IN_REG) & (1<< PinB );
if (level) {
// set the pinA (set in RTOS_2) to LOW as fast as possible
REG_WRITE(0x3ff4400c, 1<<PinA);// Low at 160 ns
REG_WRITE(0x3ff44008, 1<<PinA);// HIGH ~70ns
REG_WRITE(0x3ff4400c, 1<<PinA);// Low
}
}
}
// Function that creates a task to be pinned at Core 1
void StartCore1( void )
{
TaskHandle_t xHandle = NULL;
xHandle = xTaskCreateStaticPinnedToCore(
Core1, // Function that implements the task.
"Core1", // Text name for the task.
STACK_SIZE, // Stack size in bytes, not words.
( void * ) 1, // Parameter passed into the task.
//tskIDLE_PRIORITY,// Priority at which the task is created.
tskIDLE_PRIORITY+20,
xStack, // Array to use as the task's stack.
&xTaskBuffer, // Variable to hold the task's data structure.
1); // Core 1
}
void RTOS_1(void *p) {
while(1) {
printf("RTOS-1\n"); // demo for full function
vTaskDelay(1000);
}
}
void RTOS_2(void *p) {
while(1) {
//printf("RTOS-2\n");
gpio_set_level(PinA, 1);
vTaskDelay(1);
gpio_set_level(PinA, 0); // should not happen - Core1 should do it much faster !
vTaskDelay(10);
}
}
void app_main(void)
{
gpio_set_direction(PinA, GPIO_MODE_OUTPUT);
gpio_set_direction(PinB, GPIO_MODE_INPUT );
xTaskCreate(
RTOS_1, // Function that implements the task.
"RTOS-1", // Text name for the task.
STACK_SIZE, // Stack size in bytes, not words.
( void * ) 1, // Parameter passed into the task.
tskIDLE_PRIORITY+2,
&xHandle1); // Variable to hold the task's data structure.
xTaskCreate(
RTOS_2, // Function that implements the task.
"RTOS-2", // Text name for the task.
STACK_SIZE, // Stack size in bytes, not words.
( void * ) 1, // Parameter passed into the task.
tskIDLE_PRIORITY+2,
&xHandle2); // Variable to hold the task's data structure.
StartCore1();
while(1) {
vTaskDelay(10000);
}
}
Fast is not fast enough
Re: Reduce external interrupt latency
Someone may ask "What the hell should this has it to do with interrupts?"
Here is a code, where we use
(core 1)
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
and
(core 0)
if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE ) {
// ... do something
}
The core 0 task does not know that the signal is not comming from a real interrupt.
The latency is 2µs
Here is a code, where we use
(core 1)
xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
and
(core 0)
if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE ) {
// ... do something
}
The core 0 task does not know that the signal is not comming from a real interrupt.
The latency is 2µs
- /*
- * FastIRQSemaphore
- *
- * Copyright (c) 2019, Dipl. Phys. Helmut Weber.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Helmut Weber ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This file is part of the CoopOS library.
- *
- * Author: Helmut Weber <Dph.HelmutWeber@web.de>
- *
- * $Id: Task.h,v 1.1 2019/04/02 helmut Exp $
- */
- //#pragma GCC optimize ("O2")
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/portmacro.h"
- #include "esp_wifi.h"
- #include "esp_system.h"
- #include "esp_event.h"
- #include "esp_event_loop.h"
- #include "esp_task_wdt.h"
- #include "nvs_flash.h"
- #include "driver/gpio.h"
- #include "driver/uart.h"
- #include "rom/uart.h"
- #include "driver/touch_pad.h"
- #include "driver/gpio.h"
- #include "soc/gpio_periph.h"
- #include "freertos/semphr.h"
- // Dimensions the buffer that the task being created will use as its stack.
- // NOTE: This is the number of bytes the stack will hold, not the number of
- // words as found in vanilla FreeRTOS.
- #define STACK_SIZE 4096
- // Structure that will hold the TCB of the task being created.
- StaticTask_t xTaskBuffer;
- // Buffer that the task being created will use as its stack. Note this is
- // an array of StackType_t variables. The size of StackType_t is dependent on
- // the RTOS port.
- StackType_t xStack[ STACK_SIZE ];
- #define PinA GPIO_NUM_18 // output shortcut > _____
- #define PinB GPIO_NUM_19 // input < _____|----- scope
- TaskHandle_t xHandle1 = NULL;
- TaskHandle_t xHandle2 = NULL;
- volatile int IsLow=0;
- SemaphoreHandle_t xSemaphore = NULL;
- #define LONG_TIME 0xffff
- inline uint32_t IRAM_ATTR micros()
- {
- uint32_t ccount;
- asm volatile ( "rsr %0, ccount" : "=a" (ccount) );
- return ccount;
- }
- void IRAM_ATTR delayMicroseconds(uint32_t us)
- {
- if(us){
- uint32_t m = micros();
- while( (micros() - m ) < us ){
- asm(" nop");
- }
- }
- }
- void Core1( void* p) {
- //static signed BaseType_t xHigherPriorityTaskWoken;
- static int xHigherPriorityTaskWoken =(int)pdTRUE;
- gpio_set_direction(PinA, GPIO_MODE_OUTPUT);
- gpio_set_direction(PinB, GPIO_MODE_INPUT );
- printf("Start Core 1\n");
- vTaskDelay(1000);
- // I do not want an RTOS-Tick here
- portDISABLE_INTERRUPTS(); // YEAH
- while(1) {
- register int level;
- level=REG_READ(GPIO_IN_REG) & (1<< PinB );
- if (level) {
- REG_WRITE(0x3ff4400c, 1<<PinA);// Low at 160 ns
- xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
- }
- }
- }
- // Function that creates a task to be pinned at Core 1
- void StartCore1( void )
- {
- TaskHandle_t xHandle = NULL;
- xHandle = xTaskCreateStaticPinnedToCore(
- Core1, // Function that implements the task.
- "Core1", // Text name for the task.
- STACK_SIZE, // Stack size in bytes, not words.
- ( void * ) 1, // Parameter passed into the task.
- tskIDLE_PRIORITY+2,
- xStack, // Array to use as the task's stack.
- &xTaskBuffer, // Variable to hold the task's data structure.
- 1); // Core 1
- }
- void RTOS_1(void *p) {
- while(1) {
- printf("RTOS-1\n"); // demo for full function
- vTaskDelay(1000);
- }
- }
- void RTOS_2(void *p) {
- while(1) {
- REG_WRITE(0x3ff44008, 1<<PinA);// High
- if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE ) {
- // ... do something
- }
- //while(IsLow==0);
- }
- }
- void app_main(void)
- {
- gpio_set_direction(PinA, GPIO_MODE_OUTPUT);
- gpio_set_direction(PinB, GPIO_MODE_INPUT );
- xSemaphore = xSemaphoreCreateBinary();
- xTaskCreate(
- RTOS_1, // Function that implements the task.
- "RTOS-1", // Text name for the task.
- STACK_SIZE, // Stack size in bytes, not words.
- ( void * ) 1, // Parameter passed into the task.
- tskIDLE_PRIORITY+2,
- &xHandle1); // Variable to hold the task's data structure.
- xTaskCreate(
- RTOS_2, // Function that implements the task.
- "RTOS-2", // Text name for the task.
- STACK_SIZE, // Stack size in bytes, not words.
- ( void * ) 1, // Parameter passed into the task.
- tskIDLE_PRIORITY+20,
- &xHandle2); // Variable to hold the task's data structure.
- StartCore1();
- while(1) {
- vTaskDelay(10000);
- }
- }
Fast is not fast enough
Who is online
Users browsing this forum: dzungpv, Google [Bot], Google Adsense [Bot], Majestic-12 [Bot] and 78 guests