0

I'm working on a FreeRTOS project in C/C++ that has about 10 tasks for gpios, displays, wifi, and so on.

These tasks are only triggered by events. For example, the user chooses an option on the menu "connect" and this will trigger an event to the respective task.

What I would like to know is, what is the best way to handle flags around the code?

For example I have some flags: "wifi_check_status", "mqtt_connect", "button_pressed" and so on.

Currently, I'm using a global struct that stores all these flags. Then, the respetive tasks just reads the flag it needs and updates its value.

I have a lot of flags, and 10 tasks that need to read them. Should I be using mutex everytime a task wants to read these flags? or is there an easier method I'm not seeing?

I don't have any problem with the current architecure, but I would like to know if this is the best approach.

Thanks a lot in advance

EDIT

I'm using direct-to-task notifications for communication between different tasks. That helped separate a lot of modules which is great. Nevertheless, I have those flags that are used by different modules and I'm trying to avoid using hundreds of mutex, is there any way?

For example, the wifi task has an event to check the wifi status and reconnect if needed. I trigger this event from a timer. Once the event is done, I update the "wifi_check_status" flag to false inside the task. What other patterns can I use to do this? Similarly, there's another task that reads this flag to decide if it needs to do anything

Another example, is the encoder tasks update a current_menu_option variable based on the number of options in a menu. If the menu has 3 options, the current_menu_option will move between 0 and 2. When the user presses the button, it will trigger the UI task. The UI task prints the menu in the display and resets current_menu_option to 0, because the user starts scrolling always at position 0. Thats why I'm using a global variable in this case, it's very convenient.

How could I do that without a global variable?

1
  • Some options you may consider: 1. Use a cooperative scheduler (configUSE_PREEMPTION=0), provided the OS runs on single core 2. Use few global mutexes, each mutex protect a group of related variables. Separate read/write of globals from bussiness logic as much as possible, for example first read globals into locals, then run business logic without accessing any globals, then write locals back to globals. 3. Use atomic (not correct if multiple variables should be updated as a whole) Can you provide more background, what other tasks use wifi_check_status and current_menu_option? Commented Sep 11, 2024 at 6:36

1 Answer 1

0

I don't have any problem with the current architecure, but I would like to know if this is the best approach.

It is an example of how to not program using freeRTOS. It is a terrible practice. Use queues, direct to task notifications or event groups (the very worst option) to communicate between tasks

Using flags and task polling their values indicates that you need to learn IPC (inter process communication) before you start developing freeRTOS applications

These tasks are only triggered by events. For example, the user chooses an option on the menu "connect" and this will trigger an event to the respective task.

It has nothing in common with events and your app is not event-driven.

What I would like to know is, what is the best way to handle flags around the code?

The best way is to remove them and redesign the application.

How could I do that without a global variable?

Uses queues

Sign up to request clarification or add additional context in comments.

1 Comment

@Juan You should edit your question and post the code for this in a code block

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.