M-Arch (13) is compatible with FreeRTOS: let FreeRTOS run first

Posted by sleepingdanny on Tue, 04 Jan 2022 17:00:23 +0100

preface

Review the previous chapters: we have realized the compatibility of cortex-M series architecture based on a simple timer OS, and implemented many examples based on the basic resources of single chip microcomputer.

Starting from this chapter, we port FreeRTOS and consider compatibility.

In this paper, we will introduce how to transplant FreeRTOS and realize a basic example: serial port timing printing data.

Keywords: FreeRTOS, STM32, GD32

Introduction to FreeRTOS

Why use a real-time operating system?

There are only two kinds of data interaction in the software, one is polling and the other is notification.

The so-called polling is that you go downstairs every five minutes to see if the express has arrived. During this period, you can do nothing but wait.

The so-called notice is that the express brother sends you a text message, "express downstairs, come and pick it up". Go down after the notice. What should you do during the waiting period.

The purpose of using real-time operating system is to make more efficient use of CPU resources.

**In addition, * * besides, now that the Internet of things is so popular, how can we do without a real-time operating system?

Why FreeRTOS?

Open source is free (conscience), simple enough (just a few c files) and stable enough (everyone is using it).

μ COS wants money - RT thread wants money- μ Clinux is a little difficult - NuttX is a little difficult - eCOS uses less - QNX X86

FreeRTOS migration

download

Go directly to the official website: FreeRTOS official website [1]

The next LTS Version (long-term support version) is about this:

FreeRTOSvyyyymm.xx-LTS.zip

FreeRTOS kernel directory structure

Briefly describe this directory as follows:

  • [blue] include: header file
  • [yellow] * c: Several core header files
  • [green] portable: migration related

The portable directory has special instructions. The manual has direct mapping

FreeRTOS kernel directory structure

MemMang is the memory management interface, and heap is generally used_ 4. The specific meaning is written in the manual, which is not detailed here.

In addition, keil is used to migrate M4 kernel, and the corresponding portable folder is portable\RVDS\ARM_CM4F.

We add the necessary documents to our project as follows:

FreeRTOS migration directory structure

Among them, freertosconfig H is the configuration header file, several c is the core document.

FreeRTOS also has other extensions, including http, json, mqtt and other network support. You can download their extension packages as needed.

FreeRTOSConfig.h has many configuration items. The official reference is FreeRTOSConfig[2], but there are too many contents in it. You can copy an existing one from the demo.

Download the demo on github: FreeRTOS DEMO[3]

The directory is FreeRTOS\Demo

Refer to: FreeRTOS\Demo\CORTEX_STM32F103_Keil

compile

First get out the simplest program: debug serial port printout.

The code is as follows (1000ms cycle printing):

void vTask(void *pvParameters)
{
    while(1)
    {
#ifdef STM32
        printf("[STM32] hello, this is freertos!\r\n");
#endif
#ifdef GD32
        printf("[ GD32] hello, this is freertos!\r\n");
#endif
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

In the main function (create a task and start scheduling):

    /* 3. app */
#ifndef USING_FREE_RTOS

    virtual_timer_init();
    while(1)
    {
        timer0_task();
    }

#else

    xTaskCreate(vTask, "Task1", 50, NULL, 1, NULL);
    vTaskStartScheduler();

#endif

Compile one, OK.

Of course, the most important thing is that we also have freertosconfig Find out the key configurations in H.

FreeRTOSConfig.h

/*
 * FreeRTOS V202111.00
 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * http://www.FreeRTOS.org
 * http://aws.amazon.com/freertos
 *
 * 1 tab == 4 spaces!
 */

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/*-----------------------------------------------------------
 * Application specific definitions.
 *
 * These definitions should be adjusted for your particular hardware and
 * application requirements.
 *
 * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
 * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
 *
 * See http://www.freertos.org/a00110.html
 *----------------------------------------------------------*/

#include "io.h"

#define configUSE_PREEMPTION  1
#define configUSE_IDLE_HOOK   0
#define configUSE_TICK_HOOK   0
#define configCPU_CLOCK_HZ   (SystemCoreClock)
#define configTICK_RATE_HZ   ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES  ( 5 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE  ( ( size_t ) ( 17 * 1024 ) )
#define configMAX_TASK_NAME_LEN  ( 16 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS  0
#define configIDLE_SHOULD_YIELD  1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES   0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

/* Software timer definitions. */
#define configUSE_TIMERS    1
#define configTIMER_TASK_PRIORITY  ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH  5
#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */

#define INCLUDE_vTaskPrioritySet  1
#define INCLUDE_uxTaskPriorityGet  1
#define INCLUDE_vTaskDelete    1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend   1
#define INCLUDE_vTaskDelayUntil   1
#define INCLUDE_vTaskDelay    1

/* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
(lowest) to 0 (1?) (highest). */
#define configKERNEL_INTERRUPT_PRIORITY   255
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY  191 /* equivalent to 0xb0, or priority 11. */

#ifdef USING_FREE_RTOS
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler
#endif

#endif /* FREERTOS_CONFIG_H */

stack allocation

Example:

#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE  ( ( size_t ) ( 17 * 1024 ) )
#define configMAX_TASK_NAME_LEN  ( 16 )
configMINIMAL_STACK_SIZE

Stack size configuration for idle tasks.

configTOTAL_HEAP_SIZE

Total size of FreeRTOS stack configuration.

You need to configure the size according to the actual project.

configMAX_TASK_NAME_LEN

Maximum length limit for task names.

tick configuration

#define configCPU_CLOCK_HZ   ( ( unsigned long ) 72000000 )
#define configTICK_RATE_HZ   ( ( TickType_t ) 1000 )

As the name suggests, configCPU_CLOCK_HZ is the CPU frequency, which can be replaced by the system global variable:

#define configCPU_CLOCK_HZ   (SystemCoreClock)

configTICK_RATE_HZ is the frequency of tick, and 1000 corresponds to 1ms cycle.

Another configuration is: configssystick_ CLOCK_ Hz, usually with configcpu_ CLOCK_ Just like Hz. We can ignore it in port C describes:

#ifndef configSYSTICK_CLOCK_HZ
    #define configSYSTICK_CLOCK_HZ      configCPU_CLOCK_HZ
    /* Ensure the SysTick is clocked at the same frequency as the core. */
    #define portNVIC_SYSTICK_CLK_BIT    ( 1UL << 2UL )
#else

/* The way the SysTick is clocked is not modified in case it is not the same
 * as the core. */
    #define portNVIC_SYSTICK_CLK_BIT    ( 0 )
#endif

It should be noted that:

Consider replacing the original tick interrupt function of the system with the tick interrupt of freeRTOS, specifically:

#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler

SysTick_Handler is a tick interrupt, and the other two are exception interrupts.

Considering the compatibility design, the parts of the original framework involving systemTick need to be closed.

Priority configuration

First, we need to understand the basic knowledge of NVIC.

The full name of NVIC is nested vector interrupt control, that is, nested vector interrupt controller. In the MCU of Cortex M3 and M4 cores, the priority of each interrupt is represented by an 8-bit register.

However, in fact, manufacturers generally use only 4 bit s (the corresponding configuration macro is _NVIC_PRIO_BITS. You can see how this macro is used in the code), that is, 16 priorities; These 16 priorities are divided into 2-bit preemptive priority and 2-bit sub priority.

Preemptive priority is higher than sub priority; The smaller the number, the higher the priority.

Q: why do you say this priority? A: FreeRTOS needs to take over (part of) priority in order to do things well.

To facilitate priority management, we can configure all 4-bit priorities as preemptive priorities:

STM32 : NVIC_PriorityGroup_4
GD32 : NVIC_PRIGROUP_PRE4_SUB0

Let's take a closer look at the priority configuration involved in FreeRTOS:

configKERNEL_INTERRUPT_PRIORITY

This configuration defines the priority of Systick and PendSV interrupts used by FreeRTOS. It must be configured as the lowest priority, that is:

#define configKERNEL_INTERRUPT_PRIORITY   255

If not defined, in M3 port Mandatory definition in C (not in M4):

#ifndef configKERNEL_INTERRUPT_PRIORITY
    #define configKERNEL_INTERRUPT_PRIORITY    255
#endif
configMAX_SYSCALL_INTERRUPT_PRIORITY

This configuration defines the highest priority interrupt managed by FreeRTOS.

What do you mean?

When the off interrupt of FreeRTOS is called, all interrupts with lower priority than this definition will be closed.

Therefore, this value cannot be set to 0 in port Check in C:

#if configMAX_SYSCALL_INTERRUPT_PRIORITY == 0
    #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.  See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
#endif

For example:

#define configMAX_SYSCALL_INTERRUPT_PRIORITY  191

hex(191)='0xbf 'indicates that priorities lower than 11 are managed by FreeRTOS.

configMAX_PRIORITIES

Extended reading: faultmask, primask and basepri

Interrupt mask register.

primask: mask all exceptions and interrupts except NMI and HardFalut. faultmask: mask all exceptions and interrupts except NMI. Basepri: Mask interrupts whose priority is lower than basepri. When it is 0, stop the function of shielding interrupts.

FreeRTOS adopts basepri mode, μ COS adopts primask mode.

API functions contain configuration

Its form is: INCLUDE_ Function name

For example, to use the vTaskDelay function, the definition is as follows:

#define INCLUDE_vTaskDelay    1

Result display

Of course, this is just a hello world example of FreeRTOS. It also involves compatibility design. The usage of FreeRTOS task scheduling, delay method, semaphore and queue will be discussed later.

reference material

[1]FreeRTOS official website: https://www.freertos.org/

[2]FreeRTOSConfig: https://www.freertos.org/a00110.html

[3]FreeRTOS DEMO: https://github.com/FreeRTOS/FreeRTOS