将uc/OS移植到stm32F103上
将uc/OS移植到stm32F103上
- 一、嵌入式实时操作系统(RTOS)
- 1.定义
- 2.实时任务
- 3.特征
- 二、使用CubeMX建立STM32F103C8T6HAL库
- 三、移植uC/OS-III
- 四、总结
一、嵌入式实时操作系统(RTOS)
1.定义
实时操作系统是保证在一定时间限制内完成特定功能的操作系统。实时操作系统有硬实时和软实时之分,硬实时要求在规定的时间内必须完成操作,这是在操作系统设计时保证的;软实时则只要按照任务的优先级,尽可能快地完成操作即可。我们通常使用的操作系统在经过一定改变之后就可以变成实时操作系统。
2.实时任务
在实时系统中必然存在着若干个实时任务,这些任务通常与某些个外部设备相关,能反应或控制相应的外部设备,因而带有某种程度的紧迫性。可从不同的角度对实时任务加以分类。
按任务执行时是否呈现周期性变化来划分:
①周期性实时任务
外部设备周期性地发出激励信号给计算机,要求它按照指定周期循环执行,以便周期性的控制某种外部设备。
②非周期性实时任务
外部设备所发出的激励信号并无明显的周期性,但都必须联系着一个截止时间。 它又可分为开始截止时间(任务在某时间以前必须开始执行)和完成截止时间(任务在某时间以前必须完成)两部分。
根据对截至时间的要求来划分:
①硬实时任务
②软实时任务
3.特征
1)高精度计时系统
计时精度是影响实时性的一个重要因素。在实时应用系统中,经常需要精确确定实时地操作某个设备或执行某个任务,或精确的计算一个时间函数。这些不仅依赖于一些硬件提供的时钟精度,也依赖于实时操作系统实现的高精度计时功能。
2)多级中断机制
一个实时应用系统通常需要处理多种外部信息或事件,但处理的紧迫程度有轻重缓急之分。有的必须立即作出反应,有的则可以延后处理。因此,需要建立多级中断嵌套处理机制,以确保对紧迫程度较高的实时事件进行及时响应和处理。
3)实时调度机制
实时操作系统不仅要及时响应实时事件中断,同时也要及时调度运行实时任务。但是,处理机调度并不能随心所欲的进行,因为涉及到两个进程之间的切换,只能在确保“安全切换”的时间点上进行,实时调度机制包括两个方面,一是在调度策略和算法上保证优先调度实时任务;二是建立更多“安全切换”时间点,保证及时调度实时任务。
二、使用CubeMX建立STM32F103C8T6HAL库
配置系统时钟为72M
将与LED相连的端口PC13配置为GPIO_Output
设置串口USART1
填写项目信息
打开项目,在main函数的while循环中添加
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);HAL_Delay(500);HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);HAL_Delay(500);
连接好电路后,编译烧录运行程序
三、移植uC/OS-III
1.从ucoslll官网中下载源码
http://micrium.com/downloadcenter/
2.新建uC-BSP和uC-CONFIG文件夹
3.为uC-BSP文件夹新建bsp.c和bsp.h文件
4.将uCOS相关文件复制到HAL工程的MDK-ARM文件夹下
5.将uCOS文件添加到项目
6.在keil中导入文件
7.CPU-Add选择uC-CPU下的
RealView下的
LIB-Add uC-LIB下的
RealView下的
PORT-Add RealView下的
SOURCE-Add Source下的
CONFIG-Add uc-CONFIG下的
BSP-Add uc-BSP下的
8.在path中添加
9.将启动文件的PendSV_Handler
和Systick_Handler
改为OS_CPU_PendSVHandler
和OS_CPU_SysTickHandler
10.app_cfg.h中的 #define APP_CFG_SERIAL_EN DEF_ENABLED
改为 #define APP_CFG_SERIAL_EN DEF_DISABLED
#define APP_TRACE BSP_Ser_Printf
改为 #define APP_TRACE (void)
11.includes.h
在#include <bsp.h> 后面加上
#include “gpio.h”#include “app_cfg.h”
将#include <stm32f10x_lib.h>
改为
#include “stm32f1xx_hal.h”
12.lib_cfg.h
#define LIB_MEM_CFG_HEAP_SIZE 5u * 1024u
改为
#define LIB_MEM_CFG_HEAP_SIZE 5u * 1024u
13.bsp.c文件代码
// 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;#elsecnts = cpu_clk_freq/(CPU_INT32U)OS_TICKS_PER_SEC;#endifOS_CPU_SysTickInit(cnts);
}
void BSP_Init(void)
{BSP_Tick_Init();MX_GPIO_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
14.bsp.h文件代码
// bsp.h
#ifndef __BSP_H__
#define __BSP_H__
#include "stm32f1xx_hal.h"
void BSP_Init(void);
#endif
15.main.c函数代码
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"
#include "usart.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <includes.h>
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* 任务优先级 */
#define START_TASK_PRIO 3
#define LED0_TASK_PRIO 4
#define LED1_TASK_PRIO 5
#define FLOAT_TASK_PRIO 6/* 任务堆栈大小 */
#define START_STK_SIZE 256
#define LED0_STK_SIZE 128
#define LED1_STK_SIZE 128
#define FLOAT_STK_SIZE 128
/* 任务栈 */
CPU_STK START_TASK_STK[START_STK_SIZE];
CPU_STK LED0_TASK_STK[LED0_STK_SIZE];
CPU_STK LED1_TASK_STK[LED1_STK_SIZE];
/* 任务控制块 */
OS_TCB StartTaskTCB;
OS_TCB Led0TaskTCB;
OS_TCB Led1TaskTCB;
OS_TCB FloatTaskTCB;
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
/* 任务函数定义 */
void start_task(void *p_arg);
static void AppTaskCreate(void);
static void AppObjCreate(void);
static void led_pc13(void *p_arg);
static void send_msg(void *p_arg);
/* 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 */
/*** @brief System Clock Configuration* @retval None*/void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/**Initializes the CPU, AHB and APB busses clocks */RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/**Initializes the CPU, AHB and APB busses 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_2) != HAL_OK){Error_Handler();}
}
/* USER CODE END 0 */
/*** @brief The application entry point.* @retval int*/
int main(void)
{OS_ERR err;OSInit(&err);HAL_Init();SystemClock_Config();//MX_GPIO_Init(); 这个在BSP的初始化里也会初始化
MX_USART1_UART_Init(); /* 创建任务 */
OSTaskCreate((OS_TCB *)&StartTaskTCB, /* Create the start task */(CPU_CHAR *)"start task",(OS_TASK_PTR ) start_task,(void *) 0,(OS_PRIO ) START_TASK_PRIO,(CPU_STK *)&START_TASK_STK[0],(CPU_STK_SIZE) START_STK_SIZE/10,(CPU_STK_SIZE) 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);/* 启动多任务系统,控制权交给uC/OS-III */OSStart(&err); /* Start multitasking (i.e. give control to uC/OS-III). */}
void start_task(void *p_arg)
{OS_ERR err;CPU_SR_ALLOC();p_arg = p_arg;
/* YangJie add 2021.05.20*/BSP_Init(); /* Initialize BSP functions *///CPU_Init();//Mem_Init(); /* Initialize Memory Management Module */
#if OS_CFG_STAT_TASK_EN > 0uOSStatTaskCPUUsageInit(&err); //统计任务
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN //如果使能了测量中断关闭时间CPU_IntDisMeasMaxCurReset();
#endif#if OS_CFG_SCHED_ROUND_ROBIN_EN //当使用时间片轮转的时候//使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5msOSSchedRoundRobinCfg(DEF_ENABLED,1,&err);
#endif
OS_CRITICAL_ENTER(); //进入临界区/* 创建LED0任务 */OSTaskCreate((OS_TCB * )&Led0TaskTCB, (CPU_CHAR * )"led_pc13", (OS_TASK_PTR )led_pc13, (void * )0, (OS_PRIO )LED0_TASK_PRIO, (CPU_STK * )&LED0_TASK_STK[0], (CPU_STK_SIZE)LED0_STK_SIZE/10, (CPU_STK_SIZE)LED0_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); /* 创建LED1任务 */OSTaskCreate((OS_TCB * )&Led1TaskTCB, (CPU_CHAR * )"led1 task", (OS_TASK_PTR )send_msg, (void * )0, (OS_PRIO )LED1_TASK_PRIO, (CPU_STK * )&LED1_TASK_STK[0], (CPU_STK_SIZE)LED1_STK_SIZE/10, (CPU_STK_SIZE)LED1_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*)&StartTaskTCB,&err); //挂起开始任务 OS_CRITICAL_EXIT(); //进入临界区}
17.需要在usart.c文件中添加以下代码完成printf重定向
int fputc(int ch,FILE *f){HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);return ch;
}
18.添加头文件
19.编译运行烧录调试
四、总结
参考链接
https://blog.csdn.net/weixin_43116606/article/details/105532222
https://www.cnblogs.com/dreamrj/p/14046598.html
https://blog.csdn.net/sunke9/article/details/104315486?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-2.highlightwordscore&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2defaultCTRLISTdefault-2.highlightwordscore
将uc/OS移植到stm32F103上相关推荐
- 将uc/OS-III移植到stm32F103上并创建多任务
一.准备uCOSIII源码 1.官网下载: 进入 Micrium 公司官网下载中心:http://micrium.com/downloadcenter/ 2.网盘下载: 链接:https://pan. ...
- uC/OS-III移植到STM32F103
**广西河池学院广西高校重点实验室培训基地系统控制与信息处理重点实验室本篇文章来自河池学院:OpenWRT无线路由组写作时间:2021年07月22日** uC/OS-III移植到STM32F103 4 ...
- uC/OS 的进程调度(上)
操作系统最重要的任务之一就是进程调度,它涉及三个主要方面: 何时进行调度 如何选择下一个活动进程 如何实现进程切换 每种操作系统差别很大,本文对uC/OS的进程调度机制进行一些细致分析. 何时进行调度 ...
- STM32F103C8T6移植uc/OS
STM32F103C8T6移植uc/OS STM32F103C8T6移植uc/OS STM32F103C8T6移植uc/OS 一.题目要求 二.使用STM32CubeMX建立HAL库 三.准备uCOS ...
- 基于STM32F103RC移植uc/OS系统
目录 一.获取uc/OS-III源码 二.使用CubeMX创建基础stm32框架 三.文件准备 四.路径添加 五.代码修改 六.成功展示 七.使用Keil仿真逻辑仪观察引脚电平变化 八.参考资料 本文 ...
- 基于STM32的uc/OS系统移植及用Saleae Logic 16抓取分析波形
文章目录 一.关于uc/OS系统 1.操作系统与裸机的区别 2.uc/OS运行流程 二.详细移植过程 1.STM32Cubex创建工程 2.为工程添加源码 3.添加头文件路径 4.添加代码 1)bsp ...
- 嵌入式系统开发16——嵌入式实时操作系统uC/OS的简介及简单应用
本文主要介绍嵌入式实时操作系统(RTOS),并且以uc/OS为例,将其移植到stm32F103C8T6上,构建3个任务:其中两个task分别以1s和3s周期对LED灯进行点亮-熄灭的控制:另外一个ta ...
- Lab 6:uC/OS II
为什么80%的码农都做不了架构师?>>> 目标: 移植uC/OS II到RPi上,实现两个任务的调度.这两个任务能轮流点亮LED,并通过串口发送消息表明自己正在运行 具体步骤: ...
- uc/OS-II操作系统移植:uc/OS-II移植到STM32流程(文章末尾附实例)
一.实验目的 1.掌握在STM32上移植嵌入式实时操作系统uC/OS-II的方法 2.掌握在STM32上移植uC/OS-II的基本步骤 3.掌握uC/OS-II的文件OS_CPU.H编写 4.掌握uC ...
最新文章
- wincc客户机打开服务器文件通讯不上,wincc客户机连不上服务器
- 程序员经验分享:Android高级工程师系列学习路线介绍,面试必备
- Pearson product-moment correlation coefficient
- 两个有序链表序列的合并编程
- Windows网络编程之(二)Socket通信非阻塞模式Select(TCP和UDP)
- 中国元宇宙企业有哪些?
- mysql置疑原因_数据库置疑的处理办法
- Rectangle矩形类
- 菜鸟学-业务流程图、数据流图、模块结构图
- 2019年保研夏令营时间经验汇总
- Latex将文中的某一行设置成左对齐、右对齐
- Android Studio 选项菜单和动画结合_安卓手机关于“开发者选项”你该知道的几件事...
- 拉伯杠杆平台|沪指上涨,大金融板块领涨,有股票连续5涨停!
- zxing集成到Android Studio中实现二维码扫一扫功能
- 为什么需要内网穿透技术?
- python计算机二级简单操作题
- Android高手进阶教程(一)-------Android常用名令集锦(图文并茂)!
- BoundingBox工具及其使用方法
- CentOS 7配置DNS和DHCP服务
- 判断两个物体之间是否有气其他Collider阻挡