Page 1 of 1

Multi thread behaviour

Posted: Sun Jan 15, 2023 12:05 pm
by rebel88
Hello all,
I'm trying to build a RGB LED Lamp using WS2812 leds.
Everything work well untill I decided to create multiple scenario to run led light driven by external push button.
My Idea was :
  • 0) Project with THREAD_MAIN to initialize everithing and start the THREAD_LED;
    1) Power on the lamp with predefinite light scenario running on THREAD_LED defined by variable scenario_var=0;
    2) push external button to change light scenario actions:
    • - first : delete ongoing THREAD_LED
      - second : UPDATE scenario_var to change the next scenario to start
      - third : start again THREAD_LED with updated passed variable
But as you can imagine, this is not what it is appening in my code, it is restaring everitime i push the push button because I think I'm doing something wrong inside ISR.

I think I need better knowledge of :
-1 ISR
- multi thread behaviour
- multi thread behaviour in ESP32
- suggestions.

This is my code :

Code: Select all



#include <stdio.h>

#include "driver/gpio.h"            //useful to use GPIO pin
#include "freertos/FreeRTOS.h"      //to use the FreeRTOS system
#include "freertos/task.h"          //to call task functions
#include "freertos/semphr.h"        //to use semaphores
#include "esp_heap_caps_init.h"
#include "esp_log.h"

#define TAG "MAIN"

#define STACK_SIZE 2048

#define ESP_INTR_FLAG_DEFAULT 0
#define CONFIG_BUTTON_PIN GPIO_NUM_0
#define CONFIG_LED_PIN GPIO_NUM_2


SemaphoreHandle_t xSemaphore = NULL;    //Allocate semaphore variable
bool led_status = false;                //create LED Flag


//----------------------------------------------------------------------
// task that will react to button clicks
void button_task(void* arg) {

	// infinite loop
	for(;;) {

		// wait for the notification from the ISR
		if(xSemaphoreTake(xSemaphore,portMAX_DELAY) == pdTRUE) {
			printf("Button pressed!\n");
			led_status = !led_status;
			gpio_set_level(CONFIG_LED_PIN, led_status);
            ESP_LOGI("ISR_TASK","free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
		}
	}
}

void second_task (void * pvParameter)
{
	
	uint16_t counter = 0;
	uint8_t passed_parameter = *((uint8_t*)pvParameter);
	printf("received parameter value is %d\n",passed_parameter);
	ESP_LOGI("SECOND_TASK","free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
	while(1)
	{

		counter++;
		printf("Counter Value %d\n",counter);
		vTaskDelay(300);
	}
}

//----------------------------------------------------------------------
// interrupt service routine, called when the button is pressed
//Interrupt handlers must be placed into IRAM Memory
void IRAM_ATTR button_isr_handler(void* arg) {
	static uint8_t version=0;
	
	TaskHandle_t xHandle = NULL;
	xHandle = *((TaskHandle_t*)arg);

	vTaskDelete( xHandle );
	version++;
	xTaskCreate( second_task, "actions_task", STACK_SIZE, (void *)&version, 10, &arg);
    // notify the button task
	//xSemaphoreGiveFromISR(xSemaphore, NULL);
}

void app_main(void)
{
    ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));

	uint8_t mode_value=0;
	static uint8_t ucParameterToPass=0; // parameter to be passed to the second task
	TaskHandle_t xHandle = NULL;

    xSemaphore = xSemaphoreCreateBinary();  //create the binary semaphore
    ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));

// configure button and led pins as GPIO pins
	gpio_pad_select_gpio(CONFIG_BUTTON_PIN);
	gpio_pad_select_gpio(CONFIG_LED_PIN);
    ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));

// set the correct direction
	gpio_set_direction(CONFIG_BUTTON_PIN, GPIO_MODE_INPUT);
    gpio_set_direction(CONFIG_LED_PIN, GPIO_MODE_OUTPUT);
    ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));

// // enable interrupt on falling (1->0) edge for button pin
 	gpio_set_intr_type(CONFIG_BUTTON_PIN, GPIO_INTR_NEGEDGE);
//     ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));

// // start the task that will handle the button
 	xTaskCreate(button_task, "button_task", 2048, (void *)&xHandle, 10, NULL);
//     ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));

// install ISR service with default configuration
	gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
//     ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));

// // attach the interrupt service routine
 	 gpio_isr_handler_add(CONFIG_BUTTON_PIN, button_isr_handler, xHandle);

//     ESP_LOGI(TAG,"free DRAM %u IRAM %u",esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_32BIT));
	xTaskCreate( second_task, "actions_task", STACK_SIZE, (void *)&ucParameterToPass, 10, &xHandle);
    configASSERT( xHandle );

}