HAL database transplantation of learning records of Royal happiness μ COSIII

preface

Real time operating system (RTOS) refers to an operating system that can accept and process external events or data quickly enough, and its processing results can control the production process or make rapid response to the processing system within the specified time, and control the coordinated operation of all real-time tasks. Providing timely response and high reliability are its main characteristics.
Real time operating system is an operating system that ensures to complete specific functions within a certain time limit. Real time operating system can be divided into hard real time and soft real time. Hard real time requires that the operation must be completed within the specified time, which is guaranteed in the design of operating system; Soft real-time can complete the operation as soon as possible according to the priority of the task. The operating system we usually use can become a real-time operating system after certain changes.

I μ Introduction to COS

1. Introduction

uC/OS-III (Micro C OS Three) is an upgradeable, curable, priority based real-time kernel. It has no limit on the number of tasks. uC/OS-III is a third generation system kernel, which supports most of the functions expected by modern real-time kernel. For example, resource management, synchronization, communication between tasks, and so on.

2. Features

1) Priority
μ COS-III is a multitasking kernel that can be preempted. It always runs the most important tasks entering the ready state. μ C/OS-III supports an unlimited number of tasks and allows tasks to monitor stack growth at run time. It also supports an unlimited number of priorities. However, in general, 32 to 256 different priorities are sufficient for most applications.
2) Multitasking
uCOS-III allows any number of tasks, semaphores, mutually exclusive semaphores, event flags, message queues, timers and memory partitions (limited only to the RAM size available to the processor).
3) Very fast interruption
μ C/OS-III provides near zero interrupt deactivation time. μ C/OS-III has some internal data structures and variables that require atomic access (which cannot be interrupted). The protection of these critical areas is achieved by lock scheduling, not by disabling interrupts. The clock cycle in which interrupts are disabled is almost zero, ensuring that the real-time operating system will be able to respond to some of the fastest interrupt sources.

2, STM32F103C8T6 transplantation uCOS

1.uCOS Download

STM32F107uCOS sample download
After downloading, the files are as follows:

2. File import

1) Project creation
Create an empty project using stm32subemx
2) Project management
1. Create a new folder UCOSIII in the new project

2. Move UC CPU, UC lib and UCOS III in the sample files on the official website to the new folder UCOSIII, and create new folders UCOS BSP and UCOS config files

3) File add

New Groups: UCOS BSP, UCOS CPU, UCOS lib, UCOS core, UCOS port, UCOS config
1. Add files to UCOS BSP

After completion, it is as follows:

2. Adding files to UCOS CPU


After completion, it is as follows:

3. Add files to UCOS Lib


After completion, it is as follows:

4. Add files to UCOS core

Total 20 documents
5. Add files to UCOS port

After completion, it is as follows:

6. Add files to UCOS config

7. keil general file directory


4) Header file path addition

3. Document modification

1. Startup file

DCD     PendSV_Handler             ; PendSV Handler
DCD     SysTick_Handler            ; SysTick Handler

Change to

PendSV_Handler  PROC
                EXPORT  PendSV_Handler             [WEAK]
                B       .
                ENDP
SysTick_Handler PROC
                EXPORT  SysTick_Handler            [WEAK]
                B       .
                ENDP

Change to

2,app_cfg.h

#define APP_CFG_SERIAL_EN DEF_ENABLED
Change to
#define APP_CFG_SERIAL_EN DEF_DISABLED

#define APP_TRACE BSP_Ser_Printf
Change to
#define APP_TRACE (void)

3,includes.h

The first modification: add the relevant header file
#include <bsp.h>
Change to
#include <bsp.h>
#include "gpio.h"
#include "app_cfg.h"
#include "app.h"

The second modification: add HAL Library
#include <stm32f10x_lib.h>
Change to
#include "stm32f1xx_hal.h"

4. bsp.c and bsp.h

//bsp.c
#include "includes.h"

#define  DWT_CR      *(CPU_REG32 *)0xE0001000
#define  DWT_CYCCNT  *(CPU_REG32 *)0xE0001004
#define  DEM_CR      *(CPU_REG32 *)0xE000EDFC
#define  DBGMCU_CR   *(CPU_REG32 *)0xE0042004

#define  DEM_CR_TRCENA                   (1 << 24)
#define  DWT_CR_CYCCNTENA                (1 <<  0)

CPU_INT32U  BSP_CPU_ClkFreq (void)
{
    return HAL_RCC_GetHCLKFreq();
}

void BSP_Tick_Init(void)
{
	CPU_INT32U cpu_clk_freq;
	CPU_INT32U cnts;
	cpu_clk_freq = BSP_CPU_ClkFreq();
	
	#if(OS_VERSION>=3000u)
		cnts = cpu_clk_freq/(CPU_INT32U)OSCfg_TickRate_Hz;
	#else
		cnts = cpu_clk_freq/(CPU_INT32U)OS_TICKS_PER_SEC;
	#endif
	OS_CPU_SysTickInit(cnts);
}



void BSP_Init(void)
{
	BSP_Tick_Init();

}


#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
void  CPU_TS_TmrInit (void)
{
    CPU_INT32U  cpu_clk_freq_hz;


    DEM_CR         |= (CPU_INT32U)DEM_CR_TRCENA;                /* Enable Cortex-M3's DWT CYCCNT reg.                   */
    DWT_CYCCNT      = (CPU_INT32U)0u;
    DWT_CR         |= (CPU_INT32U)DWT_CR_CYCCNTENA;

    cpu_clk_freq_hz = BSP_CPU_ClkFreq();
    CPU_TS_TmrFreqSet(cpu_clk_freq_hz);
}
#endif


#if (CPU_CFG_TS_TMR_EN == DEF_ENABLED)
CPU_TS_TMR  CPU_TS_TmrRd (void)
{
    return ((CPU_TS_TMR)DWT_CYCCNT);
}
#endif


#if (CPU_CFG_TS_32_EN == DEF_ENABLED)
CPU_INT64U  CPU_TS32_to_uSec (CPU_TS32  ts_cnts)
{
	CPU_INT64U  ts_us;
  CPU_INT64U  fclk_freq;

 
  fclk_freq = BSP_CPU_ClkFreq();
  ts_us     = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC);

  return (ts_us);
}
#endif
 
 
#if (CPU_CFG_TS_64_EN == DEF_ENABLED)
CPU_INT64U  CPU_TS64_to_uSec (CPU_TS64  ts_cnts)
{
	CPU_INT64U  ts_us;
	CPU_INT64U  fclk_freq;


  fclk_freq = BSP_CPU_ClkFreq();
  ts_us     = ts_cnts / (fclk_freq / DEF_TIME_NBR_uS_PER_SEC);
	
  return (ts_us);
}
#endif
###################################################################
//bsp.h
#ifndef  __BSP_H__
#define  __BSP_H__

#include "stm32f1xx_hal.h"

void BSP_Init(void);

#endif                                                 /* End of module include.   

5,lib_cfg.h
There is a macro definition in this header file:
#define LIB_MEM_CFG_HEAP_SIZE 27u * 1024u
It means that the heap space is set to 27KB, but the total RAM of stm32f103c8t6 I use is only 20K, so I need to reduce the heap space to 10K
#define LIB_MEM_CFG_HEAP_SIZE 10u * 1024u
The modification here is not necessary for MCU with large RAM space, but it is necessary for MCU with small capacity.

3, Simple multitasking implementation

1,main.c

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include <includes.h>
#include <stdio.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
//Override printf function
int fputc(int ch,FILE *f)
 
{
    HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xFFFF);    
		//Wait for sending to end	
		while(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_TC)!=SET){
		}		

    return ch;
}


/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

//Task control block
static  OS_TCB   AppTaskStartTCB;
OS_TCB LEDPB6TaskTCB;//LEDPB6
OS_TCB LEDPB7TaskTCB;//LEDPB7
OS_TCB USART1TaskTCB;//Serial port 1

//task stack 
static  CPU_STK  AppTaskStartStk[APP_TASK_START_STK_SIZE];

/* Private function prototype--------------------------------------------------------------*/
static  void  AppTaskCreate(void);
static  void  AppObjCreate(void);
static  void  AppTaskStart(void *p_arg);

//Task function
void LEDPB6_TASK(void *p_arg);
void LEDPB7_TASK(void *p_arg);
void USART1_TASK(void *p_arg);

//Task priority
#define LEDPB6_ TASK_ Prio 3 / / pb6 priority
#define LEDPB7_ TASK_ Prio 3 / / pb7 priority
#define USART1_TASK_PRIO 3 //USART1 priority

//Task stack size
#define LEDPB6_STK_SIZE 128 //PB6 stack size
#define LEDPB7_STK_SIZE 128 //PB7 stack size
#define USART1_STK_SIZE 128 / / serial port 1 stack size


CPU_STK LEDPB6_TASK_STK[LEDPB6_STK_SIZE];//PB6 task stack
CPU_STK LEDPB7_TASK_STK[LEDPB7_STK_SIZE];//PB7 task stack
CPU_STK USART1_TASK_STK[USART1_STK_SIZE];//Serial port task stack

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	
	OS_ERR  err;

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
	
	OSInit(&err);  

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  /* Create task */
	OSTaskCreate((OS_TCB     *)&AppTaskStartTCB,                /* Create the start task                                */
				 (CPU_CHAR   *)"App Task Start",
				 (OS_TASK_PTR ) AppTaskStart,
				 (void       *) 0,
				 (OS_PRIO     ) APP_TASK_START_PRIO,
				 (CPU_STK    *)&AppTaskStartStk[0],
				 (CPU_STK_SIZE) APP_TASK_START_STK_SIZE / 10,
				 (CPU_STK_SIZE) APP_TASK_START_STK_SIZE,
				 (OS_MSG_QTY  ) 0,
				 (OS_TICK     ) 0,
				 (void       *) 0,
				 (OS_OPT      )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
				 (OS_ERR     *)&err);
				 
	OSStart(&err);            /* Start multitasking (i.e. give control to uC/OS-III). */

//  while (1)
//  {
//    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
//  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/**
  * Function function: start the task function body.
  * Input parameter: p_arg is the formal parameter passed when the task was created
  * Return value: None
  * Description: None
  */
static  void  AppTaskStart (void *p_arg)
{
  OS_ERR      err;

  (void)p_arg;

  BSP_Init();                                                 /* Initialize BSP functions                             */
  CPU_Init();

  Mem_Init();                                                 /* Initialize Memory Management Module                  */

#if OS_CFG_STAT_TASK_EN > 0u
  OSStatTaskCPUUsageInit(&err);                               /* Compute CPU capacity with no task running            */
#endif

  CPU_IntDisMeasMaxCurReset();

  AppTaskCreate();                                            /* Create Application Tasks                             */

  AppObjCreate();                                             /* Create Application Objects                           */

	OSTaskCreate((OS_TCB 	* )&LEDPB6TaskTCB,		
				 (CPU_CHAR	* )"PB6 task", 		
				 (OS_TASK_PTR )LEDPB6_TASK, 			
				 (void		* )0,					
				 (OS_PRIO	  )LEDPB6_TASK_PRIO,     
				 (CPU_STK   * )&LEDPB6_TASK_STK[0],	
				 (CPU_STK_SIZE)LEDPB6_STK_SIZE/10,	
				 (CPU_STK_SIZE)LEDPB6_STK_SIZE,		
				 (OS_MSG_QTY  )0,					
				 (OS_TICK	  )0,					
				 (void   	* )0,					
				 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
				 (OS_ERR 	* )&err);	
				 
	OSTaskCreate((OS_TCB 	* )&LEDPB7TaskTCB,		
				 (CPU_CHAR	* )"PB7 task", 		
				 (OS_TASK_PTR )LEDPB7_TASK, 			
				 (void		* )0,					
				 (OS_PRIO	  )LEDPB7_TASK_PRIO,     
				 (CPU_STK   * )&LEDPB7_TASK_STK[0],	
				 (CPU_STK_SIZE)LEDPB7_STK_SIZE/10,	
				 (CPU_STK_SIZE)LEDPB7_STK_SIZE,		
				 (OS_MSG_QTY  )0,					
				 (OS_TICK	  )0,					
				 (void   	* )0,					
				 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
				 (OS_ERR 	* )&err);
				 
				 
	OSTaskCreate((OS_TCB 	* )&USART1TaskTCB,		
				 (CPU_CHAR	* )"usart1 task", 		
				 (OS_TASK_PTR )USART1_TASK, 			
				 (void		* )0,					
				 (OS_PRIO	  )USART1_TASK_PRIO,     
				 (CPU_STK   * )&USART1_TASK_STK[0],	
				 (CPU_STK_SIZE)USART1_STK_SIZE/10,	
				 (CPU_STK_SIZE)USART1_STK_SIZE,		
				 (OS_MSG_QTY  )0,					
				 (OS_TICK	  )0,					
				 (void   	* )0,					
				 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,
				 (OS_ERR 	* )&err);				 
				 
	OS_TaskSuspend((OS_TCB*)&AppTaskStartTCB,&err);
 
}


void  LEDPB6_TASK (void *p_arg)
{
  OS_ERR      err;

  (void)p_arg;

  BSP_Init();                                                 /* Initialize BSP functions                             */
  CPU_Init();

  Mem_Init();                                                 /* Initialize Memory Management Module                  */

#if OS_CFG_STAT_TASK_EN > 0u
  OSStatTaskCPUUsageInit(&err);                               /* Compute CPU capacity with no task running            */
#endif

  CPU_IntDisMeasMaxCurReset();

  AppTaskCreate();                                            /* Create Application Tasks                             */

  AppObjCreate();                                             /* Create Application Objects                           */

  while (DEF_TRUE)
  {

		OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
		OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);

  }
}


void  LEDPB7_TASK (void *p_arg)
{
  OS_ERR      err;

  (void)p_arg;

  BSP_Init();                                                 /* Initialize BSP functions                             */
  CPU_Init();

  Mem_Init();                                                 /* Initialize Memory Management Module                  */

#if OS_CFG_STAT_TASK_EN > 0u
  OSStatTaskCPUUsageInit(&err);                               /* Compute CPU capacity with no task running            */
#endif

  CPU_IntDisMeasMaxCurReset();

  AppTaskCreate();                                            /* Create Application Tasks                             */

  AppObjCreate();                                             /* Create Application Objects                           */

  while (DEF_TRUE)
  {

		OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
		OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
		OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
		OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
		OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
		OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
		HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
  }
}



void  USART1_TASK (void *p_arg)
{
  OS_ERR      err;

  (void)p_arg;

  BSP_Init();                                                 /* Initialize BSP functions                             */
  CPU_Init();

  Mem_Init();                                                 /* Initialize Memory Management Module                  */

#if OS_CFG_STAT_TASK_EN > 0u
  OSStatTaskCPUUsageInit(&err);                               /* Compute CPU capacity with no task running            */
#endif

  CPU_IntDisMeasMaxCurReset();

  AppTaskCreate();                                            /* Create Application Tasks                             */

  AppObjCreate();                                             /* Create Application Objects                           */

  while (DEF_TRUE)
  {
		printf("hello uc/OS! Welcome to RTOS Multitasking environment!");
		OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
		OSTimeDly(1000, OS_OPT_TIME_DLY, &err);
  }
}

/**
  * Function function: create application task
  * Input parameter: p_arg is the formal parameter passed when the task was created
  * Return value: None
  * Description: None
  */
static  void  AppTaskCreate (void)
{

	  
}

/**
  * Function function: uCOSIII kernel object creation
  * Input parameters: None
  * Return value: None
  * Description: None
  */
static  void  AppObjCreate (void)
{
	
}

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

2. Operation results

3. Precautions

1) keil compilation error, insufficient memory
.\Objects\ucos-led.axf: Error: L6406E: No space in execution regions with .ANY selector matching os_cfg_app.o(.bss).
Reference solution:

Just enlarge the red box data
2) After rewriting the output function, you need to check Use MicroLIB

reference resources

https://blog.csdn.net/weixin_43116606/article/details/105532222

Tags: stm32 RTOS

Posted on Tue, 30 Nov 2021 08:42:30 -0500 by muitine