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.
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.
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.
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 = ; RCC_ClkInitTypeDef RCC_ClkInitStruct = ; /** 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
https://blog.csdn.net/weixin_43116606/article/details/105532222