FreeRTOS和UCOS操作系统使用笔记

FreeRTOS使用示例

UCOS使用示例

信号量使用

信号量访问共享资源区/
OS_SEMMY_SEM; //定义一个信号量,用于访问共享资源

OSSemCreate ((OS_SEM* )&MY_SEM, //创建信号量,指向信号量
			 (CPU_CHAR* )"MY_SEM", //信号量名字
			 (OS_SEM_CTR )1,       //信号量值为1,可以理解开始有个任务就可以请求到信号量
			 (OS_ERR* )&err);//错误码
 
void task1_task(void *p_arg)
{
	OS_ERR err;
	u8 task1_str[]="First task Running!";
	//请求信号量,参数2:0为死等;参数3:表示信号量无效任务挂起等待信号量;参数4:时间戳
	OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err);
	memcpy(share_resource,task1_str,sizeof(task1_str));//向共享资源区拷贝数据
	delay_ms(200);
	printf("%s\r\n",share_resource);       //串口输出共享资源区数据
	OSSemPost(&MY_SEM,OS_OPT_POST_1,&err); //发送信号量
}
void task2_task(void *p_arg)
{
	OS_ERR err;
	u8 task2_str[]="Second task Running!";
	OSSemPend(&MY_SEM,0,OS_OPT_PEND_BLOCKING,0,&err);  //请求信号量(3)
	memcpy(share_resource,task2_str,sizeof(task2_str));//向共享资源区拷贝数据
	delay_ms(200);
	printf("%s\r\n",share_resource);        //串口输出共享资源区数据
	//OS_OPT_POST_1表示向信号量优先级高的任务发送信号量
	OSSemPost(&MY_SEM,OS_OPT_POST_1,&err);//发送信号量 
}
/信号量用于任务同步实验
OS_SEM SYNC_SEM; //定义一个信号量,用于任务同步
OSSemCreate ((OS_SEM* )&SYNC_SEM,//创建信号量,指向信号量
			 (CPU_CHAR* )"SYNC_SEM",//信号量名字
			 (OS_SEM_CTR )0,        //信号量值为0
			 (OS_ERR* )&err);       //错误码

void task1_task(void *p_arg)
{
	OS_ERR err;
	if(KEY_Scan(0)==WKUP_PRES){
		OSSemPost(&SYNC_SEM,OS_OPT_POST_1,&err);//发送信号量
		LCD_ShowxNum(150,111,SYNC_SEM.Ctr,3,16,0); //显示信号量值 
	}
}

void task2_task(void *p_arg)
{
	OS_ERR err;
    //OS_OPT_PEND_BLOCKING:表示信号量无效任务挂起等待信号量
	//如是OS_OPT_POST_ALL 向等待该信号量的所有任务发送信号量。
	OSSemPend(&SYNC_SEM,0,OS_OPT_PEND_BLOCKING,0,&err); //请求信号量
	LCD_ShowxNum(150,111,SYNC_SEM.Ctr,3,16,0); //显示信号量值
	OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err);//延时1s
}

 内建信号量

//内建信号量///
void task1_task(void *p_arg)
{
	OS_ERR err;
	if(KEY_Scan(0) == WKUP_PRES){
		//OS_OPT_POST_NONE:不指定特定的选项
		OSTaskSemPost(&Task2_TaskTCB,OS_OPT_POST_NONE,&err);//使用系统内建信号量向任务task2发送信号量
		LCD_ShowxNum(150,111,Task2_TaskTCB.SemCtr,3,16,0); //显示信号量值
	}
}

void task2_task(void *p_arg)
{
	OS_ERR err; 
	//参数1:超时时间,0为一直等待信号量;2:信号量被占用则挂起等待;3:时间戳
	OSTaskSemPend(0,OS_OPT_PEND_BLOCKING, 0,&err);//请求任务内建的信号量
	LCD_ShowxNum(150,111,Task2_TaskTCB.SemCtr,3,16,0);//显示任务内建信号量值
}

消息传递

消息队列相关函数

消息队列//
#define KEYMSG_Q_NUM 1 //按键消息队列的数量
#define DATAMSG_Q_NUM 4 //发送数据的消息队列的数量
OS_Q KEY_Msg; //定义一个消息队列,用于按键消息传递,模拟消息邮箱
OS_Q DATA_Msg; //定义一个消息队列,用于发送数据

void start_task(void *p_arg)
{//......
	OSQCreate ( (OS_Q* )&KEY_Msg,//指向一个消息队列
				(CPU_CHAR* )"KEY Msg",//消息队列名称
				(OS_MSG_QTY )KEYMSG_Q_NUM, //消息队列长度,这里设置为 1
				(OS_ERR* )&err); //错误码
//创建消息队列 DATA_Msg
	OSQCreate ( (OS_Q* )&DATA_Msg, //指向一个消息队列
				(CPU_CHAR* )"DATA Msg",//消息队列的名称
				(OS_MSG_QTY )DATAMSG_Q_NUM,//消息队列的个数这里是4
				(OS_ERR* )&err);//错误码
}

void tmr1_callback(void *p_tmr,void *p_arg)
{//......
	sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
	//发送消息
	OSQPost((OS_Q* )&DATA_Msg,//指向一个消息队列
			(void* )pbuf,     //指向要发送的内容void指针
			(OS_MSG_SIZE )10, //要发送的消息大小,单位字节
			(OS_OPT )OS_OPT_POST_FIFO,//发送消息操作类型,这里表示发送消息报错队列尾部
			(OS_ERR* )&err);  //错误码	
}

void main_task(void *p_arg)
{
	u8 key = KEY_Scan(0); //扫描按键

	//发送消息
	OSQPost((OS_Q* )&KEY_Msg,
			(void* )&key,
			(OS_MSG_SIZE )1,
			(OS_OPT )OS_OPT_POST_FIFO,
			(OS_ERR* &err);
    u8 msgq_remain_size = DATA_Msg.MsgQ.NbrEntriesSize-DATA_Msg.MsgQ.NbrEntries;//消息队列剩余大小
    sprintf((char*)p,"Total Size:%d",DATA_Msg.MsgQ.NbrEntriesSize);//显示 DATA_Msg 消息队列总的大小
}

void Keyprocess_task(void *p_arg)
{
	u8 num;
	u8 *key;
	OS_MSG_SIZE size;
	OS_ERR err;
	key=OSQPend((OS_Q* )&KEY_Msg, //指向一个消息队列,整个函数反回的是指针消息数据
				(OS_TICK )0,     //指定时间没有接收到数据任务就被唤醒,0一直等
				(OS_OPT )OS_OPT_PEND_BLOCKING,//一直等,直到接收到消息
				(OS_MSG_SIZE* )&size,//接收消息的字节长度
				(CPU_TS* )0,//指向一个时间戳
				(OS_ERR* )&err);//错误码
}
void msgdis_task(void *p_arg)
{
	u8 *p;
	OS_MSG_SIZE size;
	OS_ERR err; 
	p=OSQPend(  (OS_Q* )&DATA_Msg, 
				(OS_TICK )0,
				(OS_OPT )OS_OPT_PEND_BLOCKING,
				(OS_MSG_SIZE* )&size;
				(CPU_TS* )0,
				(OS_ERR* )&err);
    LCD_ShowString(5,270,100,16,16,p);
}

 任务内建消息队列

#define TASK_Q_NUM 4 //任务内建消息队列的长度

void tmr1_callback(void *p_tmr,void *p_arg)
{//......
	sprintf((char*)pbuf,"ALIENTEK %d",msg_num);
	OSTaskQPost((OS_TCB* )&Msgdis_TaskTCB, //向任务msgdis_task发送消息
				(void* )pbuf,      //指向要发送的内容void指针
				(OS_MSG_SIZE )10,  //指定要发送消息的大小
				(OS_OPT )OS_OPT_POST_FIFO,//发送消息报错在队列末尾
				(OS_ERR* )&err);//错误码
}

void msgdis_task(void *p_arg)
{//......
	u8 *p;
	OS_MSG_SIZE size;
	OS_ERR err; 
	p=OSTaskQPend((OS_TICK )0, //超时时间没有接收到数据任务就被唤醒
				(OS_OPT )OS_OPT_PEND_BLOCKING, //一直等待,直到接收到消息
				(OS_MSG_SIZE* )&size,  //消息的大小
				(CPU_TS* )0,  //时间戳
				(OS_ERR* )&err ); //错误码
	LCD_ShowString(40,270,100,16,16,p);//P为接收到的数据指针
}

事件标志组

事件标志组//
#define KEY0_FLAG 0x01
#define KEY1_FLAG 0x02
#define KEYFLAGS_VALUE 0X00
OS_FLAG_GRP EventFlags; //定义一个事件标志组

void start_task(void *p_arg)
{//......
	OSFlagCreate((OS_FLAG_GRP* )&EventFlags, //指向事件标志组
				(CPU_CHAR* )"Event Flags", //名字
				(OS_FLAGS )KEYFLAGS_VALUE, //事件标志组初始值
				(OS_ERR* )&err); //错误码
}

//向事件标志组 EventFlags 发送标志
void main_task(void *p_arg)
{//......
	//按下按键1发送
	flags_num=OSFlagPost((OS_FLAG_GRP*)&EventFlags,//指向事件标志组
					 (OS_FLAGS )KEY0_FLAG,//决定哪些位清零和置位
					 (OS_OPT )OS_OPT_POST_FLAG_SET,//对位进行置位操作,也可清零
					 (OS_ERR* )&err);//返回错误码
	//按下按键2发送
//向事件标志组 EventFlags 发送标志
	flags_num=OSFlagPost((OS_FLAG_GRP*)&EventFlags,
						(OS_FLAGS )KEY1_FLAG,
						(OS_OPT )OS_OPT_POST_FLAG_SET,
						(OS_ERR* )&err);				 
}
void flagsprocess_task(void *p_arg)
{//......
	OS_ERR err; 
	//等待事件标志组
	OSFlagPend((OS_FLAG_GRP* )&EventFlags, //指向事件标准组
				 (OS_FLAGS )KEY0_FLAG+KEY1_FLAG,//等待 bit0和bit1时,值就为 0X03。

				 (OS_TICK )0,//等待超时时间,为0则一直等待下去
				 (OS_OPT )OS_OPT_PEND_FLAG_SET_ALL+\//多种配置模式:当前配置为等待所有位
				  OS_OPT_PEND_FLAG_CONSUME,//保留事件标志的状态
				 (CPU_TS* )0,//时间戳
				 (OS_ERR* )&err);//返回错误码
    printf("事件标志组 EventFlags 的值:%d\r\n",EventFlags.Flags);
}

 

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

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

相关文章

STM32入门笔记(03): ADC(SPL库函数版)(2)

A/D转换的常用技术有逐次逼近式、双积分式、并行式和跟踪比较式等。目前用的较多的是前3种。 A/D转换器的主要技术指标 转换时间 分辨率 例如,8位A/D转换器的数字输出量的变化范围为0~255,当输入电压的满刻度为5V时,数字量每变化…

Google Play上架防关联,打包环境是关联因素之一还是无足轻重?

在Google Play上架应用,对于矩阵式上架或马甲包的开发者来说,防关联的处理技能是必须要精通的。想象一下,你辛辛苦苦开发的应用,因为一些看似微不足道的细节,比如打包环境的问题,就可能被谷歌无情下架或封号…

力扣双指针算法题目:移动零

1.题目 . - 力扣&#xff08;LeetCode&#xff09; 2.思路解析 这个题目的思路和“使用递归排序快速排序解决数组的排序问题”相同 class solution { public:void QuickSort(vector<int>& nums, int left, int right){if (left > right) return;int key left…

信息收集---端口服务信息收集

1. 什么是端口 是设备与外界通讯交流的出口。端口可分为虚拟端口和物理端口&#xff0c;其中虚拟端口指计算机内部或交换机路由器内的端口&#xff0c;不可见。例如计算机中的80端口、21端口、23端口等。物理端口又称为接口&#xff0c;是可见端口&#xff0c;计算机背板的RJ45…

我在高职教STM32——时钟系统与延时控制(2)

大家好&#xff0c;我是老耿&#xff0c;高职青椒一枚&#xff0c;一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次&#xff0c;同行应该都懂的&#xff0c;老师在课堂上教学几乎是没什么成就感的。正因如此&#xff0c;才有了借助 CSDN 平台寻求认同感和成就…

Http 实现请求body体和响应body体的双向压缩方案

目录 一、前言 二、方案一(和http header不进行关联) 二、方案二(和http header进行关联) 三、 客户端支持Accept-Encoding压缩方式,服务器就一定会进行压缩吗? 四、参考 一、前言 有时请求和响应的body体比较大,需要进行压缩,以减少传输的带宽。 二、方案一(和…

助力构建新型电力系统自主可控实时底座

近日&#xff0c;2024亚洲新型电力系统及储能展览会&#xff06;亚洲新型电力及储能论坛会在广州广交会展馆圆满落下帷幕&#xff01;科东软件携多款电力产品亮相展会,并在2024亚洲新型电力及储能论坛发表《“鸿道Intewell操作系统助力构建新型电力系统自主可控实时底座”》的主…

Unity之创建与导出PDF

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity之创建与导出PDF TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进取&#xff01; 助力快速…

2024-2025年本田维修电路图线路图接线图资料更新

此次更新了2024-2025年本田车系电路图资料&#xff0c;覆盖市面上99%车型&#xff0c;包括维修手册、电路图、新车特征、车身钣金维修数据、全车拆装、扭力、发动机大修、发动机正时、保养、电路图、针脚定义、模块传感器、保险丝盒图解对照表位置等等&#xff01; 汽修帮手汽…

日期和时区

日期 时区 修改时区可分为两步 删除系统自带的 localtime 文件 rm -f /etc/localtime 将系统中内置的 Shanghai 文件软连接到 /etc/localtime中 sudo ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

Unity3D中,AI角色Rigidbody旋转导致的动画问题

在制作一些AI角色的时候&#xff0c;可能会运用到Rigidbody组件来使AI角色拥有一些相关的物理属性&#xff0c;但是AI角色在受到一些物理碰撞或者惯性等原因&#xff0c;会发生旋转导致动画出现意料外的错误&#xff0c;比如在由动转静的时候&#xff0c;可能会发生向前翻转等一…

TP8/6 子域名绑定应用

原www.xxx.com/admin改为admincms.xxx.com config/app.php

【Linux】线程——线程的概念、线程的特点、线程的优点和缺点、线程和进程、线程函数的使用

文章目录 Linux线程1. 线程的概念1.1 什么是线程 2. 线程的特点2.1 线程的优点2.2 线程的缺点2.4 线程和进程 3. 线程函数的使用pthread_create() 创建线程pthread_self() 获取线程IDpthread_exit() 线程终止pthread_cancel() 线程取消pthread_join() 线程等待pthread_detach()…

Element-UI - el-table中自定义图片悬浮弹框 - 位置优化

该篇为前一篇“Element-UI - 解决el-table中图片悬浮被遮挡问题”的优化升级部分&#xff0c;解决当图片位于页面底部时&#xff0c;显示不全问题优化。 Vue.directive钩子函数已在上一篇中详细介绍&#xff0c;不清楚的朋友可以翻看上一篇&#xff0c; “Element-UI - 解决el-…

3.js - 色调映射(renderer.toneMapping)

// ts-nocheck// 引入three.js import * as THREE from three// 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls// 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js// 导入tween import * as TWEEN…

不同操作系统下的换行符

1. 关键字2. 换行符的比较3. ASCII码4. 修改换行符 4.1. VSCode 5. 参考文档 1. 关键字 CR LF CRLF 换行符 2. 换行符的比较 英文全称英文缩写中文含义转义字符ASCII码值操作系统Carriage ReturnCR回车\r13MacIntosh&#xff08;早期的Mac&#xff09;LinefeedLF换行/新行\…

Windows下载安装配置并使用Redis(保姆级教程)

文章目录 1、Redis的下载与安装 2、Redis的使用 3、Redis的图形界面客户端 4、Redis开机自启动 1、Redis的下载与安装 下载Redis&#xff1a;https://pan.baidu.com/s/1zBonkO2y6AZeqCdRe0W5ow?pwd9999 提取码: 9999 下载后直接解压就可以使用了 2、Redis的使用 我们…

全网最佳硕士研究生复试简历模板

硕士研究生复试简历模板 ✨ 简介 提供了一个适用于国内硕士研究生复试的个人简历模板。该模板通过统一的“样式”形成规范的Word格式&#xff0c;是目前研究生复试的最佳简历模板之一。模板使用“华文中宋”字体&#xff0c;如您的电脑中未安装此字体&#xff0c;请提前安装。…

软件测试与质量保证 | 云班课选择题库

目录 第1章课后习题 第2章课后习题 第3章课后习题 第4章课后习题 第5章课后习题 第6章课后习题 第7章课后习题 第8章课后习题 第9章课后习题 第10章课后习题 第11章课后习题 第12章课后习题 第13章 测试相关未分类习题 第1章课后习题 1. 与质量相关的概念包括 &a…

去中心化革命:探索区块链技术的前沿

随着信息技术的飞速发展&#xff0c;区块链技术作为一种新兴的去中心化解决方案&#xff0c;正逐渐改变着我们的经济、社会和技术格局。本文将从区块链的基本原理、当前的应用实例以及未来的发展趋势三个方面&#xff0c;深入探讨区块链技术在革命性变革中的角色和影响。 1. 区…