Now we want to expand it in order to have a code base that uses FreeRTOS and is capable to send and receive data in a more robust way. S file.FreeRTOS - Master-Slave UART using STM32
This time we use a different approach; the native FreeRTOS handlers are replaced with the CMSIS ones through defines, and prepending if it is the case the already defined handlers with the attribute weak. The main simply setup the clock, initialize the remote interface and eventually starts the scheduler. The remote interface main entry simply create a task that initialize two queues incoming and outgoing data and the USB connection. The task waits on the incoming data queue, staying idle until we receive external data.
A second task is defined, but not active at start up. Its responsibility is to sample the sensors data at regular intervals and to send the sampled data to the PC. This task is created and deleted on request, depending if the remote PC wants to see the sampled data or not.
The USB end point 3 receive data is responsible to detect a correct frame, and to dispatch it to the queue. This operation will woke up the parser task. If, for example, we receive a start command this task will create a sampling task. The protocol is the same that has been used in the rdk-stepper motor project from Texas Instruments ex Luminary. They have developed a general GUI and protocol for a different set of development boards, and the code is pretty well written and generic. It seems that Texas Instruments bets everything on their new Tiva series.
The new line of micro controllers from Texas looks promising, but they only offer LaunchPad Evaluation Kits and not a complete application demo like the rdks. The board status is a structure containing the data. The sampled data array is scanned and an array of bytes to be sent is filled.
Header, data length and check sum are added. Here we can see the data plotted on a PC. The plots are generated in Qt, using qcustomplot. Hello, this looks really amazing.
Thank you for this post! To be honest, it would be really nice to have possibility to have into whole source code. Dont you have it somewhere on GIT etc.? Hi, great work, can you post the source code? First you need to have a working usb-cdc communication try with my source codeit is the most difficult part. After that starting with FreeRTOS and a simple task is very easy, and you can find examples on the net. The sampling of the data comes from STM demo.
The dark mode beta is finally here. Change your preferences any time. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. So I use the interrupt routine to check each character received, but I somehow still cannot achieve what I want. When a command is processed, you can reset pRxBuffPtr and RxXferCount in the handle structure to their original values to start from the start of the buffer again.
Interrupt response and processing time is often critical in embedded applications, and the HAL just wastes a lot of that. If you have the complete HAL package installed, you could look at the examples for the L ow L evel interface. Since I stumbled over the problem today and could not find a good solution to it, I like to present a very simple one, using most of the HAL but avoiding the problems described The long version could be found in my post here You can make it work using HAL!
It may not be as elegant as other implementations but it is doable. In addition, I work with two buffers. While the Interrupt is filling one buffer the main loop is emptying the other. Learn more. Asked 2 years, 7 months ago. Active 1 month ago. Viewed 34k times. Bence Kaulics 3, 7 7 gold badges 23 23 silver badges 47 47 bronze badges. Do it bare registers or HAL not both. Anyway HAL for the simple peripheral like uart? What do you mean by dublicating the buffer implementation? I would like to achieve this in HAL, but I really found no solution yet.
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It only takes a minute to sign up. The thing is commands are with different priorities and some commands need to be executed in time. The latter shall stop sending values even if the 20 seconds are not reached. I think there are 2 ways to do so.
Which way is better in my case?
STM32 and FreeRTOS USB communication
Which way is easier to handle and guarantees the best performance? You did not specify your timing tolerances eg. If it is 1s, then it can easily be done "no matter what" unless something is very badly coded Is the RTOS really necessary?
You don't use RTOS just to make something "faster", but to make management of many parallel and interdependent tasks easier. Primitive and does not guarantee timings. There is an interrupt for every byte.
Interrupts with higher priorities can affect the timings. There is a single interrupt for the whole transfer.
Receiving serial data in STM32
Design everything as a time-triggered system. This method will give you the lowest jitter possible. It depends on the other specifications of your system.
You can do what you need using interruptions; the use of an RTOS will add some overhead that i dont think is justified only by the comunication interface of the system.
Sign up to join this community. The best answers are voted up and rise to the top. Home Questions Tags Users Unanswered. Asked 2 years, 1 month ago. Active 2 years, 1 month ago. Viewed 2k times. Pryda Pryda 1, 8 8 silver badges 21 21 bronze badges. Which is very broad. This is better suited for a forum. If the protocol say you have to stop after some bit times after receiving the abort command, I'd rely on interrupts.
Active Oldest Votes. Gaspar Santamarina Gaspar Santamarina 23 3 3 bronze badges. The Overflow Blog. Socializing with co-workers while social distancing. Podcast Programming tutorials can be a real drag. Featured on Meta.
I am new to STM32 and freertos.
I need to write a program to send and receive data from a module via UART port. I have to send Transmit a data to that module for eg. Then I would return to do some other tasks. How can I achieve this? You give it your buffer to which it'll read received data and number of bytes you want to receive.
It then starts receiving data. If I was to express my experiences related to working with HAL's UART module is that it's not the greatest one for generic use where you don't know the amount of data you expect to receive in advance. In the case of M66 modem you mention, this will happen all the time. In this task you implement protocol parsing. This is the approach I use personally. This will work, but will be potentially much slower than the first approach. I would rather suggest another approach.
You probably want to archive higher speeds lets say bods and the interrupt way is fat to slow for it. You need to implement the DMA transmition with the data end detection features.
You will have two events to serve. The first one is the DMA end of thransmition interrupt then you copy the data from the current tail pointer to the end of the buffer to avoid data override and USART IDLE interrupt - this will detect the end of the receive.A High-density line of STM32 microcontrollers has quite a bunch of features that can be used in your programs. However, the more features you add to the source, the more complicated the program becomes, and it may become challenging to keep up with all things.
Relying on the main loop and interrupts becomes a time-consuming task to manage. If you do not want to struggle while tuning things up manually, you can use one of the best free real-time operating systems RTOS. It is handy when you need many separate functions to run in parallel without missing a task. RTOS scheduler takes care of giving each task a required period to perform. There are many great RTOS systems around.
Many of them are free and open source. I love using FreeRTOSwhich has a long successful history and is flexible to fit multiple types of hardware. FreeRTOS is quite simple and easy to use.
FreeRTOS tutorial on STM32
It has practically all of the features may need for an RTOS. Some of the critical elements would include a preemptive, cooperative and hybrid scheduler, task and co-routine support, queues, semaphores, and mutexes for task synchronization and communication.
There are many demos, many ports about 35 microcontrollers to get started. We wrote some code using the main loop and interrupts for managing a few events. This is efficient and OK, while the program is simple.
However, when your application grows big, it is better to start building it using RTOS to keep it manageable until the end. They are used by the scheduler and have a bit different terminology. If you look at the port. There are lots of them, but most important are the following:. Just a quick overview of these. We are going to use preemption, so we set it to 1, then we select CPU clock rate which is 72MHz, also we configure tick timer what means that scheduler will run every 1ms.
Our code is going to use task priorities, so we set vTaskPrioritySet to 1. Also, we are going to use vTaskDelay utilities that help with task timing.
So we select them too. Many of them are self-explanatory but be sure to check their meaning before using as setting one or another may lead to a significant increase of ram or CPU usage. Each task normally is not directly related to other tasks and run within its context. Practically speaking, the task is a function with its own stack and runs a separate small program.
When multiple tasks are created, a scheduler switches between tasks according to assigned priorities. The task itself is a function with an endless loop, which never returns from it:. This is a basic routine which flashes LED every 1s.
This is how the tasks look like:. To set the timing, we are using the vTaskDelayUntil function. FreeRTOS counts ticks every time scheduler is called every 1ms by default. By setting frequency value to we are getting a 1s delay. Another task can be checking button state. To pass the button state, we do not need to use any global variables.GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
If nothing happens, download GitHub Desktop and try again. If nothing happens, download Xcode and try again. If nothing happens, download the GitHub extension for Visual Studio and try again. Application uses use default features to implement very efficient transmit system using DMA. While it is straight-forward for RX, this is not the case for receive operation. When implementing DMA receive, application would need to understand number of received bytes to process by DMA before finishing transfer.
This is especially true when UART is used for system communication where it has to react in short time after all bytes have been received. This is achieved using one of 2 available methods:. Both events can trigger an interrupt which is an essential feature to allow effective receive operation. When not available, examples concerning these features may not be used.
IDLE line event triggers an interrupt for application when line has been in idle state for 1 frame time in this case us after third byte has been received. After IDLE event is triggered, data are echoed back loopback mode :. For each mode, DMA requires number of elements to transfer before its events half-transfer complete, transfer complete are triggered.
As for the sake of this example, we use memory buffer array of 20 bytes. Listed are steps to begin. This configuration is important as we do not know length in advance. Application needs to assume it may be endless number of bytes received, therefore DMA must be operational endlessly. We have used 20 bytes long array for demonstration purposes.
Since I couldn't know the receive data size, I am planning to receive characters one by one. This is not the case. This function merely enables the UART peripheral and its receive interrupt. As far as I know there is no way for receiving elements indefinitely with this framework because once the transfer counter reaches zero the receive interrupt gets disabled automatically.
Learn more. Asked 11 months ago. Active 11 months ago. Viewed 1k times. Harikrishnan Harikrishnan 3, 2 2 gold badges 34 34 silver badges 63 63 bronze badges.
Active Oldest Votes. Vinci Vinci 5 5 silver badges 8 8 bronze badges. Sign up or log in Sign up using Google. Sign up using Facebook. Sign up using Email and Password. Post as a guest Name. Email Required, but never shown. The Overflow Blog. Socializing with co-workers while social distancing. Podcast Programming tutorials can be a real drag. Featured on Meta. Community and Moderator guidelines for escalating issues via new response…. Feedback on Q2 Community Roadmap.