Skip to content

freertos serial monitor

Hampus Sandberg edited this page Jun 28, 2015 · 8 revisions

Index

Introduction

Tasks


Introduction

To keep the program easy to use and modify a Real-time operating system (RTOS) was chosen. This makes it possible to divide the program into smaller parts which are somewhat indepent from each other. There are many different kinds of RTOS available and for this project FreeRTOS was chosen as they had examples for STM32F4 MCUs and there's a lot of information available.


Tasks

Each channel has it's own task that is responsible to manage that channel and they are describe separately below.

Priorities

The priorities for the different tasks can be seen in the main file. For now they are set as follows from low to high priority:

  • Background task
  • LCD task
  • All channel tasks

As it's more important to collect data from the channels then to display it their priority should be larger then the LCD task's.

background_task

FILES: Source, Header
In this task we take care of things that aren't that important but still needs to be done. These are:

  • Blinking LED_0 to indicate that the program is actually running
  • Getting the temperature from the internal sensor and display it on the LCD
  • TODO: Read the time and display it on the LCD

LED Blink:
To make it easier under development to see if the software is stuck somewhere the background task blinks the LED_0 every 500ms. Note though that if it stops blinking it only means that the background task is prohibited from running for some reason, but I've found it still useful to have.

Internal Temperature Sensor:
The onboard MCP9808 temperature sensor is read in the background task and then the value is sent to the LCD task by a LCDEvent_TemperatureData message.

Time:
The background task should also take care of reading the real time clock (RTC) on the MCU. This is not implemented right now as I screwed up the PCB by placing the two crystal oscillators in the wrong place. A fix for this will be done in the next hardware revision so for now there's no clock.


lcd_task

FILES: Source, Header
The lcd_task is responsible of talking to the LCD and it should be the only task that does this. If some other task wants to display something on the LCD they have send a message to this task which in turn will take care of each message one after the other. By doing so we avoid multiple tasks trying to access the LCD data interface at the same time and we get a central point the program where all data to the display is going through.

Messages that can be sent to the lcd_task are described here.


can1_task, can2_task

FILES CAN1: Source, Header
FILES CAN2: Source, Header

Bit rate calculation: From this site you can find information and suggestions on how to setup the bit rate for the can peripheral. They also reference a document from Bosch found here with an in depth look at the timing.

TODO: Draw a figure and explain can bit rate calculation


uart1_task, uart2_task, rs232_task

FILES UART1: Source, Header
FILES UART2: Source, Header
FILES RS232: Source, Header
These three tasks have basically the same functionality.

Initialization:
The first thing that happens in these tasks is that they create all FreeRTOS elements that are used and then they initialize the relays and setup the GPIOs for the UART. As mentioned in the UART library the pins should be set as alternate function with pull-ups. The UART peripheral is not initialized here but instead whenever the user decides to connect the channel and when they disconnect the peripheral is deinitialized.
IMPORTANT NOTE: When setting up the UART make sure you are using the UART library not the USART library as I first did without noticing. They are two completely different modes you can run the UART in and if you by mistake choose the USART you might see some strange behavior when you actually want UART.

Input buffer:
When one byte of data is received from the outside world this is saved into one of two buffers. The reason for having two buffers is that when one is used for writing the other can be used for reading and by reading I mean reading and saving to SPI FLASH. Once the data is there it can be read by other task whenever they feel like it.

UART Input Buffer
UART Input Buffer

Transmitting data:
The transmit function is protected with a semaphore to make sure only one task can transmit at the same time. This is important as it would otherwise try to transmit different data and it would become a giant mess. When the semaphore is free and the task is allowed to transmit the library basically takes care of the rest after the HAL_UART_Transmit_IT function is called.


gpio0_task, gpio1_task

FILES GPIO0: Source, Header
FILES GPIO1: Source, Header

The two GPIO channels are identical in their behavior. There are three different modes the GPIO channel can be in:
Output: When set to output mode the user can select if the channel should be HIGH (3.3V) or LOW (~0V).
Input: In input mode the task will read the current logic level on the pin.
PWM: In PWM mode a pulse width modulated (Wikipedia) signal is output on the channel. At the moment the user can only change the duty cycle from 0% to 100% but the frequency will be adjustable soon as well.

Clone this wiki locally