当前位置: 首页 > news >正文

uCOSii信号量的作用

uCOSii中信号量的作用:

在创建信号量时,Sem_Event=OSSemCreate(1)用于分时复用共享资源;

Sem_Event=OSSemCreate(0)用于中断和任务间同步或任务之间的同步。

具体在使用时,需要灵活运用。在访问共享资源时,我喜欢用互斥信号量,爱好不同而已。

一、uCOSii信号量用于对共享资源的保护

1、举例如下:

任务1每隔1小时,将DATA1数据保存到EEPROM。

任务2每隔2小时,将DATA2数据保存到EEPROM。

可见,任务1和任务2都要使用公共资源“写EEPROM”。为了防止使用冲突,我们通过发送信号量和接收信号量来分时操作“写EEPROM”,保证写入正确。

当然也可以放在一个任务里去做,为了了解怎么使用共享资源,这里使用信号量来实现。

2、实现方法:

1)、声明事件指针

OS_EVENT *Sem_Event;//定义一个事件指针

2)、任务1

//函数功能:任务1每隔1小时,将DATA1数据保存到EEPROM。

void SaveDATA1_Task(void *pdata)

{

u16 SaveDATA1_Cnt;

u8 Sem_Err;

while(1)

{

OSTimeDlyHMSM(0,0,0,1000);//延时1秒

SaveDATA1_Cnt++;

if(SaveDATA1_Cnt >3600)//1小时时间到,保存DATA1

{

OSSemPend(Sem_Event,0,&Sem_Err);//等待一个信号量,实现资源保护

EEPROM_U8_Data_Write(DATA1, DATA1_address);

OSSemPost(Sem_Event);//发出一个信号量

SaveDATA1_Cnt =0;

}

}

}

3)、任务2

//函数功能:任务2每隔2小时,将DATA2数据保存到EEPROM。

void SaveDATA2_Task(void *pdata)

{

u16 SaveDATA2_Cnt;

u8 Sem_Err;

while(1)

{

OSTimeDlyHMSM(0,0,0,1000);//延时1秒

SaveDATA2_Cnt++;

if(SaveDATA2_Cnt >7200)//2小时时间到,保存DATA2

{

OSSemPend(Sem_Event,0,&Sem_Err);//等待一个信号量,实现资源保护

EEPROM_U8_Data_Write(DATA2, DATA2_address);

OSSemPost(Sem_Event);//发出一个信号量

SaveDATA2_Cnt =0;

}

}

}

4)、启动任务

void Start_Task(void *pdata)

{

OS_CPU_SR cpu_sr=0;

OS_ENTER_CRITICAL();

//进入临界区(无法被中断打断),需要定义cpu_sr变量

Sem_Event=OSSemCreate(1);

//创建信号量Sem_Event,设置计数器初始值设置为1,即发送了一个信号量。

OSTaskCreate(

SaveDATA1_Task,/* 函数指针*/

        (void *)0,/* 建立任务时,传递的参数*/

       (OS_STK*)&SaveDATA1_Task_STACK[SaveDATA1_Task_STACK_SIZE-1],

/* 指向堆栈任务栈顶的指针*/

       SaveDATA1_Task_PRIORITY/* 任务优先级*/

              );

OSTaskCreate(

SaveDATA2_Task,/* 函数指针*/

(void *)0,/* 建立任务时,传递的参数*/  

(OS_STK*)&SaveDATA2_Task_STACK[SaveDATA2_Task_STACK_SIZE-1],

/* 指向堆栈任务栈顶的指针*/

       SaveDATA2_Task_PRIORITY/* 任务优先级*/

);

   

    OSTaskDel(OS_PRIO_SELF); //删除自己

    OS_EXIT_CRITICAL();      //退出临界区(可以被中断打断)

}

二、uCOSii使用信号量实现中断和任务之间的同步

1、举例如下:

串口接收一组配置参数,然后将该参数需要保存到EEPROM中。显然,我们不能在中断中写EPPROM,这样会导致串口中断执行时间太长。因此需要分成两个部分实现,一个是串口接收,一个是负责保存参数,同时还要干其他事情。

有人会在某个任务中扫描串口,若收完配置信息立即保存,不用搞这个信号量也实现,实现方法千万种。这里使用信号量实现中断和任务之间的同步,完成中断和任务之间无缝隙对接。

2、实现方法:

1)、声明事件指针

OS_EVENT *Sem_Event;//定义一个事件指针

2)中断

uint8_t UART4HeadFlag;

uint8_t UART4_in;  //UART4接收缓冲区的输入下标;

#define UART4_RCV_buffer_Size 100

//定义UART4接收缓冲区的长度100;

uint8_t UART4_RCV_buffer[UART4_RCV_buffer_Size];

//用来存放硬件串口接收到的数据;

//(ID=04661219C1677461)

//函数功能:USART4中断服务函数

void UART4_IRQHandler(void)

{

    unsigned char temp;

    (void)temp;//不让temp产生警告

    if(USART_GetITStatus(UART4, USART_IT_RXNE) != RESET)

    {

       temp=USART_ReceiveData(UART4); //从UART4串口读取一个字节;

       if(temp==’(’&& UART4HeadFlag==0)

{

UART4_in =0;

UART4HeadFlag=1;

}

if(UART4HeadFlag==1)

{

UART4_RCV_buffer[UART4_in]=temp;

UART4_in++;

}

       if(temp==’)’&& UART4HeadFlag==1)

{

UART4_in =0;

UART4HeadFlag=0;//接收完成

OSSemPost(Sem_Event);//发出一个信号量

}

    }

    if(USART_GetFlagStatus(UART4,USART_FLAG_PE) != RESET)

    {

       USART_ReceiveData(UART4);//读串口

       USART_ClearFlag(UART4, USART_FLAG_PE);

    }

  if(USART_GetFlagStatus(UART4,USART_FLAG_ORE) != RESET)

  {

       USART_ReceiveData(UART4);//读串口

    USART_ClearFlag(UART4,USART_FLAG_ORE); //清除溢出中断

  }

    if(USART_GetFlagStatus(UART4,USART_FLAG_FE) != RESET)

    {

       USART_ReceiveData(UART4);//读串口

       USART_ClearFlag(UART4,USART_FLAG_FE);

    }

}

3)、任务1

void Task1(void *pdata)

{

u8 Sem_Err;

while(1)

{

OSSemPend(Sem_Event,0,&Sem_Err);//等待一个信号量,实现无缝对接

{

Save_String_To_EEPROM(UART4_RCV_buffer,UART4_in,ID_address);

}

}

}

void LED1_Task(void *pdata)

{

while(1)

{

LED1=!LED1;//信号有效

    OSTimeDlyHMSM(0,0,0,500);//500毫秒闪烁1次

}

}

4)、启动任务

void Start_Task(void *pdata)

{

OS_CPU_SR cpu_sr=0;

OS_ENTER_CRITICAL();

//进入临界区(无法被中断打断),需要定义cpu_sr变量

Sem_Event=OSSemCreate(0);

//创建信号量Sem_Event,设置计数器初始值设置为0,即不发送一个信号量

OSTaskCreate(

Task1,/* 函数指针*/

        (void *)0,/* 建立任务时,传递的参数*/

       (OS_STK*)&Task1_STACK[Task1_STACK_SIZE-1],

/* 指向堆栈任务栈顶的指针*/

       Task1_PRIORITY/* 任务优先级*/

              );

    OSTaskCreate(

LED1_Task,/* 函数指针*/

       (void *)0,/* 建立任务时,传递的参数*/

 (OS_STK*)&LED1_TASK_STACK[LED1_TASK_STACK_SIZE-1],

/* 指向堆栈任务栈顶的指针*/

       LED1_TASK_PRIORITY/* 任务优先级*/

                  );

    OSTaskDel(OS_PRIO_SELF); //删除自己

    OS_EXIT_CRITICAL();      //退出临界区(可以被中断打断)

}

三、uCOSii使用信号量实现任务和任务之间的同步

1、举例如下:

任务1为负责按键触发

任务2负责点灯。

任务1中的按键KEY按下,任务2负责点灯ED1开灯关灯。

使用信号量实现任务与任务之间的同步,完成任务与任务之间无缝隙对接。

2、实现方法:

1)、声明事件指针

OS_EVENT *Sem_Event;//定义一个事件指针

2)、任务1

//函数功能:任务1负责按键触发。

void Key_Task(void *pdata)

{

u8 Sem_Err;

while(1)

{

if(KEY)OSSemPost(Sem_Event);//发出一个信号量

LED0=!LED0;

OSTimeDlyHMSM(0,0,0,500);//500毫秒闪烁1次

}

}

3)、任务2

void LED_Task(void *pdata)

{

u8 Sem_Err;

while(1)

{

OSSemPend(Sem_Event,0,&Sem_Err);//等待一个信号量,实现无缝对接

LED1=!LED1;//信号有效

}

}

4)、启动任务

void Start_Task(void *pdata)

{

OS_CPU_SR cpu_sr=0;

OS_ENTER_CRITICAL();

//进入临界区(无法被中断打断),需要定义cpu_sr变量

Sem_Event=OSSemCreate(0);

//创建信号量Sem_Event,设置计数器初始值设置为0,即不发送一个信号量

OSTaskCreate(

LED_Task,/* 函数指针*/

        (void *)0,/* 建立任务时,传递的参数*/

       (OS_STK*)&LED_Task_STACK[LED_Task_STACK_SIZE-1],

/* 指向堆栈任务栈顶的指针*/

       LED_Task_PRIORITY/* 任务优先级*/

              );

    OSTaskCreate(

Key_Task,/* 函数指针*/

       (void *)0,/* 建立任务时,传递的参数*/

 (OS_STK*)&KEY_TASK_STACK[KEY_TASK_STACK_SIZE-1],

/* 指向堆栈任务栈顶的指针*/

       KEY_TASK_PRIORITY/* 任务优先级*/

                  );

    OSTaskDel(OS_PRIO_SELF); //删除自己

    OS_EXIT_CRITICAL();      //退出临界区(可以被中断打断)

}

相关文章:

uCOSii信号量的作用

uCOSii中信号量的作用: 在创建信号量时,Sem_EventOSSemCreate(1)用于分时复用共享资源; Sem_EventOSSemCreate(0)用于中断和任务间同步或任务之间的同步。 具体在使用时,需要灵活运用。在访问共享资源时,我喜欢用互…...

Android 13 版本变更总览

Android 13 总览 https://developer.android.google.cn/about/versions/13?hlzh-cn 文章基于官方资料上提取 Android 13 功能和变更列表 https://developer.android.google.cn/about/versions/13/summary?hlzh-cn 行为变更:所有应用 https://developer.andr…...

QT 设计ROS GUI界面订阅和发布话题

QT 设计ROS GUI界面订阅和发布话题 主要参考下面的博客 ROS项目开发实战(三)——使用QT进行ROS的GUI界面设计(详细教程附代码!!!) Qt ROS 相关配置请看上一篇博客 首先建立工作空间和功能包&a…...

pandas数据预处理

pandas数据预处理 pandas及其数据结构pandas简介Series数据结构及其创建DataFrame数据结构及其创建 利用pandas导入导出数据导入外部数据导入数据文件 导出外部数据导出数据文件 数据概览及预处理数据概览分析利用DataFrame的常用属性利用DataFrame的常用方法 数据清洗缺失值处…...

Jupyter Notebook如何导入导出文件

目录 0.系统:windows 1.打开 Jupyter Notebook 2.Jupyter Notebook导入文件 3.Jupyter Notebook导出文件 0.系统:windows 1.打开 Jupyter Notebook 1)下载【Anaconda】后,直接点击【Jupyter Notebook】即可在网页打开 Jupyte…...

Linux:/dev/tty、/dev/tty0 和 /dev/console 之间的区别

在Linux操作系统中,/dev/tty、/dev/tty0和/dev/console是三个特殊的设备文件,它们在终端控制和输入/输出过程中扮演着重要的角色。尽管它们看起来很相似,但实际上它们之间存在一些重要的区别。本文将详细介绍这三个设备文件之间的区别以及它们…...

Linux 上安装 PostgreSQL——Ubuntu

打开 PostgreSQL 官网 PostgreSQL: The worlds most advanced open source database,点击菜单栏上的 Download ,可以看到这里包含了很多平台的安装包,包括 Linux、Windows、Mac OS等 。 Linux 我们可以看到支持 Ubuntu 和 Red Hat 等各个平台…...

合并两个有序链表(java)

leetcode 21题:合并两个有序链表 题目描述解题思路:链表的其它题型。 题目描述 leetcode21题:合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入&…...

KEYSIGHT是德DSOX4034A 示波器 350 MHz

KEYSIGHT是德DSOX4034A 示波器 350 MHz,是德4000 X 系列拥有一系列引以为傲的配置,包括采用了电容触摸屏技术的 12.1 英寸显示屏、InfiniiScan 区域触摸触发、100 万波形/秒捕获率、MegaZoom IV 智能存储器技术和标配分段存储器。 是德DSO-X4034A 主要特…...

局域网技术

共享信道的分配技术是局域网的核心技术,而这一技术又与网络的拓扑结构和传输介质有关。 拓扑结构: 1.总线型拓扑: 总线一种多点广播介质,所有的站点通过接口硬件连接到总线上。 传输介质主要是同轴电缆(基带和宽带…...

Pixhawk无人机-ArduPilot 软件SITL仿真模拟飞行(SITL+MAVProxy)

1 引言 本人是先看了多个博客实现了:在ubuntu下建立完整的ardupilot开发环境。 该文是基于搭建完编译环境后,也就是搭建好ardupilot的仿真环境实现的。 在文章: 《Pixhawk无人机扩展教程(5)—SITL仿真模拟飞行:开发环境搭建》.中指出&#…...

vue实现深拷贝的方法

在 vue中,深拷贝是一个很有用的功能,在不改变原来对象状态的情况下,进行对象的复制。 但要实现深拷贝,需要两个对象具有相同的属性。如果两个对象不同,深拷贝也不能实现。 1.我们将变量A的属性赋给变量B,但…...

LAMP架构

文章目录 LAMP架构一.简述各组件的主要作用如下: 二.过程展示1.编译安装Apache httpd服务(1)关闭防火墙,将安装Apache所需软件包传到/opt目录下(2)安装环境依赖包(3)配置软件模块(4)编译及安装(5)优化配置文件路径,并把httpd服务的可执行程序…...

javascript基础七:说说你对Javascript中作用域的理解?

一、作用域 作用域,即变量(变量作用域又称上下文)和函数生效(能被访问)的区域或集合 换句话说,作用域决定了代码区块中变量和其他资源的可见性 举个粟子 function myFunction(){let name小爱同学 } undef…...

chatgpt赋能python:Python变量赋值

Python 变量赋值 在 Python 中,我们可以使用多种符号来给变量赋值。本文将介绍这些符号以及它们在编程中的应用。 等号() 在 Python 中,我们最常用的符号是等号(),它可以将一个值赋给一个变量…...

SAP-QM-物料主数据-质量管理视图字段解析

过账到质检库存:要勾选,否则收货后库存不进入质检库存HU检验:收货到启用HU管理的库位时产生检验批,例如某个成品物料是收货到C002库位,该库位启用了HU管理,那么此处要勾选。但是如果勾选了,却收…...

【Netty】一行简单的writeAndFlush都做了哪些事(十八)

文章目录 前言一、源码分析1.1 ctx.writeAndFlush 的逻辑1.2 writeAndFlush 源码1.3 ChannelOutBoundBuff 类1.4 addMessage 方法1.5 addFlush 方法1.6 AbstractNioByteChannel 类 总结 前言 回顾Netty系列文章: Netty 概述(一)Netty 架构设…...

STM32U575 DMA配置

起个摘要,后期维护 1、DMA原理:参考:【STM32】DMA原理,配置步骤超详细,一文搞懂DMA_dma配置_~Old的博客-CSDN博客 2、STM32U575的DMA资源: (datasheet摘要) 3、UART的使用 4、I2…...

14-Vue3快速上手

目录 1.Vue3简介2. Vue3带来了什么2.1 性能的提升2.2 源码的升级2.3 拥抱TypeScript2.4 新的特性 1、海贼王,我当定了!——路飞 2、人,最重要的是“心”啊!——山治 3、如果放弃,我将终身遗憾。——路飞 4、人的梦想是…...

Docker registry 搭建

1、安装 docker 环境 参考:https://mp.csdn.net/mp_blog/creation/editor/104673841 2、准备 registry 镜像 机器有外网访问权限,直接 docker pull registry 通过 docker images 查看本地镜像 3、启动 registry docker run -d -p 5000:5000 --rest…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

centos 7 部署awstats 网站访问检测

一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

测试markdown--肇兴

day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...

数据链路层的主要功能是什么

数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

数据库分批入库

今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...