cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with integrating FreeRTOS into STM32 project

Quangvm
Visitor

Hello everyone, I am integrating FreeRTOS into a project with an LCD16x2. The issue is when I initialize the LCD handle in the main function and use it in a task, it doesn't print the correct character. However, if I initialize the LCD handle in the task itself, it works fine. I suspect the issue is with the LCD_Write_4bit function. When using HAL_Delay(), I get a hard fault error. Can anyone help me with this?

I'm using STM32F407 Discovery Board (STM32F407-DISC1) and STM32CubeIDE

 

 

 

static LCD_HandleTypeDef lcd;
int main(void)
{
  /* USER CODE BEGIN 1 */

	TaskHandle_t task1_handle;
	BaseType_t status;

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  LCD_PortType ports[] = { GPIOB, GPIOB, GPIOB, GPIOB };
  LCD_PinType pins[] = { GPIO_PIN_7, GPIO_PIN_5, GPIO_PIN_3, GPIO_PIN_9 };

  // Create the LCD instance with the defined ports and pins
  lcd = LCD_Define(ports, pins, GPIOD, GPIO_PIN_0, GPIOD, GPIO_PIN_2, LCD_4_BIT_MODE);
  // Initialize the LCD display
  LCD_Init(&lcd);

  vSemaphoreCreateBinary( xWork );

  //Enable the CYCCNT counter.
  DWT_CTRL |= ( 1 << 0);

  SEGGER_SYSVIEW_Conf();

  SEGGER_SYSVIEW_Start();


  status = xTaskCreate(print_handler, "print_task", 400, NULL, 3, &task1_handle);

  configASSERT(status == pdPASS);


  //start the freeRTOS scheduler
  vTaskStartScheduler();

  //if the control comes here, then the launch of the scheduler has failed due to
  //insufficient memory in heap

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

void print_handler(void *parameters)
{
	  //if using this code the task work fine
//	  LCD_PortType ports[] = { GPIOB, GPIOB, GPIOB, GPIOB };
//	  LCD_PinType pins[] = { GPIO_PIN_7, GPIO_PIN_5, GPIO_PIN_3, GPIO_PIN_9 };
//
//	  // Create the LCD instance with the defined ports and pins
//	  lcd = LCD_Define(ports, pins, GPIOD, GPIO_PIN_0, GPIOD, GPIO_PIN_2, LCD_4_BIT_MODE);
    while (1)
    {
        if (xSemaphoreTake(xWork, portMAX_DELAY) == pdTRUE)
        {
            LCD_Write_Data(&lcd, 0x45);
            LCD_Write_Data(&lcd, 0x31);
            HAL_GPIO_TogglePin(GPIOD, LED_GREEN_PIN);

            vTaskDelay(pdMS_TO_TICKS(500));
        }
    }
}

////////////////////////////////////////LCD_FUNCTION/////////////////////////////////
LCD_HandleTypeDef LCD_Define(
		LCD_PortType data_port[], LCD_PinType data_pin[],
		LCD_PortType rs_port, LCD_PinType rs_pin,
		LCD_PortType en_port, LCD_PinType en_pin, LCD_ModeTypeDef mode)
{
	LCD_HandleTypeDef lcd;
    lcd.mode = mode;
    lcd.data_port = data_port;
    lcd.data_pin = data_pin;
    lcd.en_port = en_port;
    lcd.en_pin = en_pin;
    lcd.rs_port = rs_port;
    lcd.rs_pin = rs_pin;

    return lcd;
}

void LCD_Write_Data(LCD_HandleTypeDef * lcd ,uint8_t data)
{
	HAL_GPIO_WritePin(lcd->rs_port, lcd->rs_pin, LCD_DATA_REG);

    if(lcd->mode == LCD_4_BIT_MODE)
    {
    	LCD_Write_4bit(lcd, data >> 4);  /*Higher nibble*/
    	LCD_Write_4bit(lcd, data & 0x0F); /*Lower nibble*/
    }else
    {
    	LCD_Write_8bit(lcd, data);
    }
}

static void LCD_Write_4bit(LCD_HandleTypeDef * lcd, uint8_t value)
{
	HAL_GPIO_WritePin(lcd->data_port[0],lcd->data_pin[0], ((value >> 0) & 0x1) );
	HAL_GPIO_WritePin(lcd->data_port[1],lcd->data_pin[1], ((value >> 1) & 0x1) );
	HAL_GPIO_WritePin(lcd->data_port[2],lcd->data_pin[2], ((value >> 2) & 0x1) );
	HAL_GPIO_WritePin(lcd->data_port[3],lcd->data_pin[3], ((value >> 3) & 0x1) );

	HAL_GPIO_WritePin(lcd->en_port, lcd->en_pin, GPIO_PIN_SET);				//figure 15, page 32 (rising edge & falling edge to)
//	HAL_Delay(1);
//	HAL_GPIO_WritePin(lcd->en_port, lcd->en_pin, GPIO_PIN_RESET);
//	HAL_Delay(1);

	if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
	{
		vTaskDelay(1 / portTICK_PERIOD_MS);
	}
	else
	{
		HAL_Delay(1);
	}

	HAL_GPIO_WritePin(lcd->en_port, lcd->en_pin, GPIO_PIN_RESET);

	if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
	{
		vTaskDelay(1 / portTICK_PERIOD_MS);
	}
	else
	{
		HAL_Delay(1);
	}
}

 

 

 

2 REPLIES 2
SofLit
ST Employee

Hello @Quangvm  and welcome to the community,

Please review tips on how to post a thread here.

Please read it and make the necessary changes: in the title, the code sharing (do not psot screen shots) and the used MCU part number.

Thank you for your understanding.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Quangvm
Visitor

Sorry for the carelessness, I will follow the tip. Thank you so much