STM32_实现双线程控制LED交替闪烁(UCOS)

线程定义函数

void  OSTaskCreate (OS_TCB        *p_tcb,
                    CPU_CHAR      *p_name,
                    OS_TASK_PTR    p_task,
                    void          *p_arg,
                    OS_PRIO        prio,
                    CPU_STK       *p_stk_base,
                    CPU_STK_SIZE   stk_limit,
                    CPU_STK_SIZE   stk_size,
                    OS_MSG_QTY     q_size,
                    OS_TICK        time_quanta,
                    void          *p_ext,
                    OS_OPT         opt,
                    OS_ERR        *p_err)

OSTaskCreate 函数的这种形式看起来像是来自μC/OS-III实时操作系统。这个函数用于创建一个任务,并且提供了更多的配置选项。下面是对每个参数的解释:

  1. p_tcb:指向任务控制块(TCB)的指针。TCB是操作系统用来管理任务的所有信息的结构,包括任务的当前状态、优先级、栈指针等。

  2. p_name:任务的名称,通常是一个以null结尾的字符串,用于调试和识别任务。

  3. p_task:任务函数的指针,这是任务执行的入口点。

  4. p_arg:传递给任务函数的参数的指针。

  5. prio:任务的优先级。在μC/OS-III中,优先级越高,任务越先被执行。

  6. p_stk_base:指向任务栈底的指针。任务栈是任务执行时用于存储局部变量和上下文切换信息的一段内存。

  7. stk_limit:栈的限制大小,用于栈溢出检测。

  8. stk_size:栈的大小,指定了任务栈的容量。

  9. q_size:任务消息队列的大小,如果任务使用消息队列来接收消息,这个参数指定队列可以容纳的最大消息数。

  10. time_quanta:时间片大小,用于时间分片调度。在时间分片调度中,每个任务在被抢占之前可以执行的时间量。

  11. p_ext:指向任务扩展数据的指针,可以用于存储用户定义的数据。

  12. opt:创建任务的选项,可以是位字段,用于指定如何创建任务,例如是否立即启动任务等。

  13. p_err:指向错误码的指针,用于返回函数执行的结果。如果任务创建成功,错误码将为OS_ERR_NONE,否则将是一个错误代码,指示失败的原因。

将定义好的线程提交给内核

void  OSStart (OS_ERR  *p_err)

main.c文件

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "os.h"
/* USER CODE END Includes */

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

#define TASK_STACK_SIZE 1024
OS_ERR      p_err1;

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
//创建任务栈
static CPU_STK TasK1StK[TASK_STACK_SIZE];
static CPU_STK TasK2StK[TASK_STACK_SIZE];

//创建任务控制块
static OS_TCB Task1TCB;
static OS_TCB Task2TCB;
// 任务函数
void Task1(void *p_arg) {
    MX_GPIO_Init();
    while (1) {
        // 点亮LED1
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_3);
        // 延时
        OSTimeDlyHMSM(0, 0, 1, 0,OS_OPT_TIME_HMSM_STRICT,&p_err1);
		//HAL_Delay(500);
    }
}

void Task2(void *p_arg) {
    MX_GPIO_Init();
    while (1) {
        // 点亮LED2
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
        // 延时
        OSTimeDlyHMSM(0, 0, 0, 500,OS_OPT_TIME_HMSM_STRICT,&p_err1);
    }
}

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

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

/* USER CODE BEGIN PV */


/* 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 */
	
  /* 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 */
	
	//初始化ucos
	OSInit(&p_err1);
  /* USER CODE END SysInit */

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

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

		OSTaskCreate(
				(OS_TCB*)&Task1TCB,//任务块名称
				(CPU_CHAR*)"task 1",//任务名称:调试的时候有用
				(OS_TASK_PTR)Task1,//任务函数
				(void*)0,//传递给任务入口函数的参数的指针
				(OS_PRIO)5,//优先级:数字越低,优先级越高
				(CPU_STK*)&TasK1StK[0],//
				(CPU_STK_SIZE)TASK_STACK_SIZE/10,
				(CPU_STK_SIZE)TASK_STACK_SIZE,
				(OS_MSG_QTY)0,
				(OS_TICK)5,
				(void*)0,
				(OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
				(OS_ERR*)&p_err1//错误指针
				);
				
		OSTaskCreate(
				(OS_TCB*)&Task2TCB,//任务块名称
				(CPU_CHAR*)"task 2",//任务名称:调试的时候有用
				(OS_TASK_PTR)Task2,//任务函数
				(void*)0,//传递给任务入口函数的参数的指针
				(OS_PRIO)1,//优先级:数字越低,优先级越高
				(CPU_STK*)&TasK2StK[0],//
				(CPU_STK_SIZE)TASK_STACK_SIZE/10,
				(CPU_STK_SIZE)TASK_STACK_SIZE,
				(OS_MSG_QTY)0,
				(OS_TICK)5,
				(void*)0,
				(OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
				(OS_ERR*)&p_err1//错误指针
				);
					
				
		OSStart(&p_err1);//启动多任务调度
				
  
	  
    /* 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_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 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_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* 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 */

注意

设置内存大小根据主板而定,太小的化有可能个别线程不可运行

具体如何设置我暂时不清楚,有知道的大佬可以在评论区中讲一下吗

我是写一个值,程序能运行就不改了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/755566.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C# 实现websocket双向通信

🎈个人主页:靓仔很忙i 💻B 站主页:👉B站👈 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:C# 🤝希望本文对您有所裨益,如有不足之处&#xff…

关于新零售的一些思考

本文作为2024上半年大量输入之后的核心思考之一。工作到一定阶段之后,思考的重要性越来越高,后续会把自己的个人思考记录在这个新系列《施展爱思考》。背景是上半年面临业务转型从电商到新零售,本文是相关大量输入之后的思考,对新…

还在用 Jenkins?快来试试这款简而轻的自动化部署工具吧!

文章目录 项目介绍功能特性效果展示逻辑节点仓库信息构建列表SSH 管理 安装使用一键安装命令管理 Jpom 服务端防火墙配置 相关地址总结 🎉欢迎来到Java学习路线专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)o *☆嗨~我是IT陈寒🍹✨博客主页&#x…

Altium Designer的元件库 PCB库 3D库神器

元件库 PCB库 3D库神器 对于硬件工程师来说贸泽是一个器件选型相当方便的电子商城,虽然购买元器件比立创商城要慢和贵,但是,上面的物料种类、选型的便捷性要远远好于立创商城;而且,它上面的大多数元件都有自己的元件封装、PCB封装、3D模型,这就对实际的开发节省了好多绘…

LangChain E-Mails with LLM

题意:通过LangChain使用大型语言模型(LLM)处理电子邮件 问题背景: I am quite new to LangChain and Python as im mainly doing C# but i am interested in using AI on my own data. So i wrote some python code using langch…

springboot系列八: springboot静态资源访问,Rest风格请求处理, 接收参数相关注解

文章目录 WEB开发-静态资源访问官方文档基本介绍快速入门注意事项和细节 Rest风格请求处理基本介绍应用实例注意事项和细节思考题 接收参数相关注解基本介绍应用实例PathVariableRequestHeaderRequestParamCookieValueRequestBodyRequestAttributeSessionAttribute ⬅️ 上一篇…

智慧校园-医务管理系统总体概述

智慧校园医务管理系统,作为校园健康管理体系的智能化升级,深度融合信息技术与医疗服务,为师生构筑起一道全方位的健康守护网。医务管理系统以提升校园医疗服务水平、优化健康管理流程为核心目标,通过一系列创新功能,确…

SerDes介绍以及原语使用介绍(2)OSERDESE2原语仿真

文章目录 前言一、SDR模式1.1、设计代码1.2、testbench代码1.3、仿真分析 二、DDR模式下2.1、设计代码2.2、testbench代码2.3、仿真分析 三、OSERDES2级联3.1、设计代码3.2、testbench代码3.3、代码分析 前言 上文通过xilinx ug471手册对OSERDESE有了简单的了解,接…

Rabbit MQ安装详细记录

RabbitMQ是Erlang语言开发的,因此安装Erlang环境在进行安装RbbitMQ的操作,选择两者版本时一定要参考版本的兼容性。 查看RabbitMQ和Erlang版本对应关系:https://www.rabbitmq.com/which-erlang.html 一、下载地址 下载Erlang地址 : https:…

【RT摩拳擦掌】RT云端测试之百度天工物接入构建(设备型)

【RT摩拳擦掌】RT云端测试之百度天工物接入构建(设备型) 一, 文档介绍二, 物接入IOT Hub物影子构建2.1 创建设备型项目2.2 创建物模型2.3 创建物影子 三, MQTT fx客户端连接云端3.1 MQTT fx配置3.2 MQTT fx订阅3.3 MQT…

SpringBoot学习05-[SpringBoot的嵌入式Servlet容器]

SpringBoot的嵌入式Servlet容器 嵌入式Servlet容器servlet容器-嵌入式servlet容器配置修改通过全局配置文件修改修改添加实现了WebServerFactoryCustomizer接口的bean来进行修改 servlet容器-注册servlet三大组件 嵌入式Servlet容器 SpringBoot包含对嵌入式Tomcat、Jetty、Und…

Nvidia Jetson/RK3588+AI双目立体相机,适合各种割草机器人、扫地机器人、AGV等应用

双目立体视觉是基于视差原理,依据成像设备从不同位置获取的被测物体的图像,匹配对应点的位置偏移,得到视差数据,进而计算物体的空间三维信息。为您带来高图像质量的双目立体相机,具有高分辨率、低功耗、远距离等优点&a…

DIYGW UniApp低代码可视化平台:高效、灵活、安全的应用开发新途径

一、引言 在数字化快速发展的今天,企业对于快速构建多端应用的需求日益增长。然而,传统的应用开发方式往往面临周期长、成本高、技术门槛高等问题。为了解决这些问题,DIYGW UniApp低代码可视化平台应运而生,它以高效率、多端使用…

动态人物抠图换背景 MediaPipe

pip下载 MediaPipe pip install mediapipe -i 手部特征点模型包包含一个手掌检测模型和一个手部特征点检测模型。手掌检测模型在输入图片中定位手部,手部特征点检测模型可识别手掌检测模型定义的被剪裁手掌图片上的特定手部特征点。 由于运行手掌检测模型非常耗时&…

面试突击:HashMap 源码详解

本文已收录于:https://github.com/danmuking/all-in-one(持续更新) 数据结构 JDK1.8 之前 JDK1.8 之前 HashMap 采用 数组和链表 结合的数据结构。如下图: HashMap 将 key 的 hashCode 经过扰动函数处理过后得到 hash 值&#…

用C/C++写一个客户端和服务器之间进行TCP通信的DEMO

目录 一、Visual Sudio 2022 二、配置 三、说明 四、客户端 五、服务端 六、演示 一、Visual Sudio 2022 Visual Studio 2022是微软公司推出的一款集成开发环境(IDE),旨在为开发人员提供全面的工具集,支持从Windows到MacOS…

【算法专题--链表】两数相加 -- 高频面试题(图文详解,小白一看就懂!!)

目录 一、前言 二、题目描述 三、解题方法 ⭐双指针 -- 模拟进位 (使用哨兵位头节点) 🥝 什么是哨兵位头节点? 🍇思路解析 🍍案例图解 四、总结与提炼 五、共勉 一、前言 两数相加 这道题,可以说是--…

Linux Swap

Swap: 页面换出:就是在 Swap 机制下,当内存资源紧张时,内核就会把不经常使用的这些匿名页中的数据写入到 Swap 分区或者 Swap 文件中。从而释放这些数据所占用的内存空间。 页面换入:就是当进程再次访问那些被换出的数据时&…

如何修复Power BI【View usage metrics report】指标报表数据源更新问题?

故事背景 有朋友留言询问:通过我之前写的 想知道Power BI用户访问报告的次数?快来学习! 这篇文章,了解了如何查看Power BI用户访问报告的详情。 但是最近由于创建【View usage metrics report】指标报表的小伙伴离职了&#x…

【数据可视化技术】1、如何使用Matplotlib和Seaborn库在Python中绘制热力图

热力图是一种数据可视化技术,可以显示变量之间的相关性。这个代码段是数据分析和可视化的常用方法,特别适合于展示变量之间的相关性,对于数据科学和机器学习项目非常有帮助。 1、 导入必要的库 首先,确保你已经安装了matplotlib…