This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Facing issues when running a simple Free rtos Button LED

I am a beginner to Free RTOS. so I have tried to build a simple button led project. When I press the button it should light up the LED.  I implemented this similar model in sequential programming. It is successful but in Free rtos I couldnt comprehend where I am going wrong. To check whether a scheduler is working or not, I have written a simple blinky led it is working.  How ever button,led tasks couldnt able to run.could some one please help me where I am going wrong?

#include <stdbool.h>
#include <stdint.h>
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "bsp.h"
#include "nordic_common.h"
#include "nrf_drv_clock.h"
#include "sdk_errors.h"
#include "app_error.h"
#include "nrf_gpio.h"

#define TASK_DELAY 200

#define led 13
#define button 11

TaskHandle_t  led_toggle_task_handle;

#define true 1
#define false 0

#define not_pressed false
#define pressed true

uint8_t button_status_flag=not_pressed;

static void setup_hardware(void)
{ 
nrf_gpio_cfg_output(led);
nrf_gpio_cfg_input(button,NRF_GPIO_PIN_PULLUP);
nrf_gpio_pin_set(led);

}

static void led_toggle_task_function (void * pvParameter)
{
    UNUSED_PARAMETER(pvParameter);
    while (true)
    {
        bsp_board_led_invert(BSP_BOARD_LED_2);

        /* Delay a task for a given number of ticks */
        vTaskDelay(TASK_DELAY);

        /* Tasks must be implemented to never return... */
    }
}

static void led_task_handler(void * params)
{
    while(1)
    {
      if(button_status_flag == pressed)
      {
      nrf_gpio_pin_clear(led);//lights LED.
      }
      else
      {
      nrf_gpio_pin_set(led);
      }
    }
}

static void button_task_handler(void * params)
{
    while(1)
    {
      if(nrf_gpio_pin_read(button))
      {
      button_status_flag=not_pressed; 
      }
      
      else
      {
      button_status_flag=pressed;
      }
    }
}

int main(void)
{
    ret_code_t err_code;

    /* Initialize clock driver for better time accuracy in FREERTOS */
    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);

    /* Configure LED-pins as outputs */
  //  bsp_board_init(BSP_INIT_LEDS);
    setup_hardware();
     bsp_board_init(BSP_INIT_LEDS);

     xTaskCreate(led_toggle_task_function, "LED2", configMINIMAL_STACK_SIZE + 200, NULL, 2, &led_toggle_task_handle);
    xTaskCreate(led_task_handler,"LED-TASK",configMINIMAL_STACK_SIZE,NULL,1,NULL);
     xTaskCreate(button_task_handler,"BUTTON-TASK",configMINIMAL_STACK_SIZE,NULL,1,NULL);
    /* Activate deep sleep mode */
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

    /* Start FreeRTOS scheduler. */
    vTaskStartScheduler();

    while (true)
    {
        /* FreeRTOS should not be here... FreeRTOS goes back to the start of stack
         * in vTaskStartScheduler function. */
    }
}


/**
 *@}
 **/

Parents
  • You are not initializing any button gpios to connect them to you button handler. Why do you have a while(1) in your button_task_handler? 

    Please look at the app_button library documentation and an example how to use it in nRF5_SDK_17.0.0_9d13099\examples\ble_peripheral\ble_app_tile\main.c

    Normally you initialize a button handler to a gpio as below

    static void button_event_handler(uint8_t pin_no, uint8_t button_action)
    {
    
    }
    
    /**@brief Function for initializing the button handler module.
     */
    static void buttons_init(void)
    {
        ret_code_t err_code;
    
        //The array must be static because a pointer to it will be saved in the button handler module.
        static app_button_cfg_t buttons[] =
        {
            {BUTTON, APP_BUTTON_ACTIVE_LOW, BUTTON_PULL, button_event_handler}
        };
    
        err_code = app_button_init(buttons, ARRAY_SIZE(buttons),
                                   BUTTON_DETECTION_DELAY);
        APP_ERROR_CHECK(err_code);
    }
    
    itn main()
    {
            buttons_init();
            uint32_t err_code = app_button_enable();
            APP_ERROR_CHECK(err_code);
    }

    You do not need to create a task for the button_handler as it should be a registered callback that should come from app_button library which is called when you press the button you registered.

Reply
  • You are not initializing any button gpios to connect them to you button handler. Why do you have a while(1) in your button_task_handler? 

    Please look at the app_button library documentation and an example how to use it in nRF5_SDK_17.0.0_9d13099\examples\ble_peripheral\ble_app_tile\main.c

    Normally you initialize a button handler to a gpio as below

    static void button_event_handler(uint8_t pin_no, uint8_t button_action)
    {
    
    }
    
    /**@brief Function for initializing the button handler module.
     */
    static void buttons_init(void)
    {
        ret_code_t err_code;
    
        //The array must be static because a pointer to it will be saved in the button handler module.
        static app_button_cfg_t buttons[] =
        {
            {BUTTON, APP_BUTTON_ACTIVE_LOW, BUTTON_PULL, button_event_handler}
        };
    
        err_code = app_button_init(buttons, ARRAY_SIZE(buttons),
                                   BUTTON_DETECTION_DELAY);
        APP_ERROR_CHECK(err_code);
    }
    
    itn main()
    {
            buttons_init();
            uint32_t err_code = app_button_enable();
            APP_ERROR_CHECK(err_code);
    }

    You do not need to create a task for the button_handler as it should be a registered callback that should come from app_button library which is called when you press the button you registered.

Children
  • Hi Susheel,, 

                            Thanks for your response. 

    Why do you have a while(1) in your button_task_handler? 

    I have kept a while(1) becuase I want to implement this logic in free rtos. I am with an impression that, every task in free rrtos needs to have a  while(1) loop. 

    I want to implement button , led as a two separate tasks running on freertos. so I tried to implement them as tasks!! 

  • Well, you have made no connection to the button/gpio handler to your task. I think instead of making this a task, you need to make this a button_callback handler that gets called from the button handler library when you press the button. 

    Please read mode about the button library in the link i mentioned in my previous reply and the code snippet to aid to understand it.

Related