element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Embedded and Microcontrollers
  • Technologies
  • More
Embedded and Microcontrollers
Blog STM32H7B3I - USB, freeRTOS ,Task Notifications and Interrupts
  • Blog
  • Forum
  • Documents
  • Quiz
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Embedded and Microcontrollers to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: Jan Cumps
  • Date Created: 7 Aug 2020 11:52 PM Date Created
  • Views 4615 views
  • Likes 1 like
  • Comments 2 comments
  • stm32h7b3i
  • rt
  • stm32h7b3i-dk
Related
Recommended

STM32H7B3I - USB, freeRTOS ,Task Notifications and Interrupts

Jan Cumps
Jan Cumps
7 Aug 2020

I'm selected for the STM32H7B3I-DK -  DISCOVERY KIT road test.

In this part of the review, I try to integrate a UART listener in freeRTOS.

 

  • listen to UART characters arriving from the USB port
  • interrupt driven, no constant polling
  • use HAL and freeRTOS
  • to prevent polling tasks, use task notification to wake up the UART task at interrupt
  • use the latest released versions of CubeIDE, HAL layer and CMSIS freeRTOS

image

 

Create a Project

 

In CubeIDE, create a new STM32 project

Select the board, STM32H7B3I-DK. I have added it to the favourites, so that each time I create a project, this one is in a shortlist.

Give it a name, select C , Executable, STMCude, then Finish

 

Configure Drivers and RTOS

 

With the MX configurator open, let's start defining the blocks.

First, in Middleware, enable freeRTOS, version CMSIS_V2.

In Tasks and Queues, add a task that will manage our UART:

image

The task is reviewed later in this post, when we write the content.

 

Then we configure timer 6 as the RTOS timer.

image

 

Last is USART1. I left the parameters: 115200, 8, N, 1.

Enabled the global interrupt in the NVIC tab,

 

In the SYS -> NVIC settings, I then enabled the USART global interrupt in the NVIC tab, Preemption priority 15.

In the Code Generation tab, I checked Generate IRQ handler and Call HAL handler

 

Then I saved and generated code.

 

Write the freeRTOS task, Task Notification and IRQ Handler

 

The mechanism that I'll use is:

  • a non-blocking read from the UART driver of 1 character.
  • this will prime the interrupt, that will fire later when a character arrives.
  • a blocking "wait for notification". This is freeRTOS lightweight method to make a task wait for an event. Similar to binary semaphores, but lighter.
  • the IRQ handler, that's called when the interrupt fires, will unblock that wait.

 

First the UART task:

 

TaskHandle_t xTaskToNotifyatUARTRx;

 

void TaskUARTListen(void *argument)
{
  /* USER CODE BEGIN TaskUARTListen */
  configASSERT( xTaskToNotifyatUARTRx == NULL );
  xTaskToNotifyatUARTRx = xTaskGetCurrentTaskHandle();
  uint8_t in[1];
  uint16_t buffersize = 1;

  /* Infinite loop */
  for(;;)
  {
    HAL_UART_Receive_IT(&huart1, in, buffersize);
    uint32_t ulNotificationValue = ulTaskNotifyTake( pdTRUE,
        portMAX_DELAY );
    if( ulNotificationValue == 1 )
    {
      /* The transmission ended as expected. */
      // todo here we handle the received character.
    }
    else
    {
      /* The call to ulTaskNotifyTake() timed out. */
    }
  }
  /* USER CODE END TaskUARTListen */
}

 

At the start of the task, we initialise the notification hook.

Then the task loops forever (it actually doesn't loop most of the time, hang on ...)

The UART Rx interrupt is primed.

Then we make the task go sleep until we receive a notification.

As indicated above, that notification will come from the interrupt handler.

Right after the wait is released, the character that arrived is available in our buffer.

 

Then we repeat to arm the interrupt and set the wait. The wait takes virtually no processor time. Much efficienter than a UART poll loop.

 

Then the Interrupt Handler

 

This one, just like the task, gets automatically invoked because we did the MX configuration.

The code is generated in stm32h7xx_it.c. We need to write the activities to release the hold of the UART task.

 

#include "cmsis_os.h"
extern TaskHandle_t xTaskToNotifyatUARTRx;

 

void USART1_IRQHandler(void)
{

  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  configASSERT( xTaskToNotifyatUARTRx != NULL );
  vTaskNotifyGiveFromISR( xTaskToNotifyatUARTRx, &xHigherPriorityTaskWoken );
//  xTaskToNotifyatUARTRx = NULL;
  portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
  /* USER CODE END USART1_IRQn 1 */
}

 

 

The first line is the HAL internal handler. It's called because we ask that in the configurator.

Then our code. Almost literally the same as the link to the freeRTOS instructions above.

You can clearly see that we notify the task, then yield back to freeRTOS.

In the background, the for() loop in TaskUARTListen() will run one turn, deal with the character that arrived over UART, then puts itself to sleep again.

 

That is it. To test it, check the COM port that's assigned to the USB of the development kit, and configure a serial terminal such as PuTTY or the Eclipse Terminal to 115200, 8, 1 N.

 

Set a breakpoint on this line

uint32_t ulNotificationValue = ulTaskNotifyTake( pdTRUE, portMAX_DELAY );

 

When the code reaches that line the first time, it'll stop.

Then use the Step Over function to execute that line only.

The debugger will not stop, because this line only returns if it receives a notification from the interrupt.

 

Type a character in the terminal, then see the debugger stop.

inspect the value of in[0]. It 'll be the character you typed in the terminal.

 

image

 

Resume the project and type another character, ...

 

Related Posts
First Experience with CubeIDE
Create a TouchGFX Project with support for the Designer, CubeIDE and Debugger - Pt 1: Screen Works
Create a TouchGFX Project with support for the Designer, CubeIDE and Debugger - Pt 2: Touch Works
TouchGFX Simple Example: react on a button click
USB, freeRTOS ,Task Notifications and Interrupts
the Development Kit STMod+ Connector and Using UART2
TouchGFX Application Framework: Model, View, Presentation, Message Queue
TouchGFX Application Framework: A Mock GUI - Show Statuses, Switch Screens
TouchGFX Application Framework: MVP and the ModelListener
Write a CubeIDE MX application: Hardware Cryptography with DMA
Attachments:
STD32H7B3I_DK-freertos_uart_20200807.zip
  • Sign in to reply
  • DAB
    DAB over 5 years ago

    Good update Jan.

     

    DAB

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Jan Cumps
    Jan Cumps over 5 years ago

    I've attached the CubeIDE project to the main post.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube