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

常规网站服务器cms程序

常规网站服务器,cms程序,WordPress同步某个表,wordpress邮箱验证码注册引言在嵌入式开发领域,任务同步与通信是系统稳定运行的核心。STM32配合FreeRTOS操作系统,为开发者提供了强大的工具支持。其中,二值信号量和计数信号量作为FreeRTOS的关键同步机制,分别用于任务间的简单同步和资源计数控制。二值信…

引言

在嵌入式开发领域,任务同步与通信是系统稳定运行的核心。STM32配合FreeRTOS操作系统,为开发者提供了强大的工具支持。其中,二值信号量和计数信号量作为FreeRTOS的关键同步机制,分别用于任务间的简单同步和资源计数控制。二值信号量如同一个开关,用于控制任务的进入与退出;而计数信号量则用于管理有限资源的访问,确保资源的合理分配。本文将深入剖析这两种信号量的工作原理、使用方法及在STM32平台上的应用实例,助力开发者精准掌握其精髓,提升系统开发效率与稳定性。

什么是二值信号量?

二值信号量是一种同步机制,用于在多任务环境中协调任务的执行。它本质上是一个只能取两个值(通常是0和1)的变量,类似于一个开关。当信号量的值为1时,表示资源可用;当值为0时,表示资源已被占用。在FreeRTOS中,二值信号量主要用于任务间的同步,而不是用于互斥。它的工作原理如下:当一个任务需要资源时,它会尝试获取信号量。如果信号量的值为1,任务会将其值减1并继续执行;如果信号量的值为0,任务会进入阻塞状态,等待信号量变为1。当另一个任务释放资源时,它会将信号量的值加1,从而唤醒等待的任务。

什么是计数信号量?

计数信号量是一种用于同步和资源管理的机制,它维护一个非负整数值,表示可用资源的数量。在FreeRTOS中,计数信号量通常用于管理有限数量的资源,例如缓冲区、硬件设备等。计数信号量的工作原理如下:当一个任务需要使用资源时,它会尝试获取信号量。如果信号量的值大于0,任务会将其值减1并继续执行,表示占用了一个资源;如果信号量的值为0,任务会进入阻塞状态,等待资源变为可用。当任务释放资源时,它会将信号量的值加1,从而表示资源数量增加,可能会唤醒等待的任务。

二值信号量

创建二值信号量句柄

步骤都跟前面的创建任务差不多,只不过在创建任务的基础上添加了二值信号量的相关函数,从本文章开始就不再细说怎么创建任务,直接开始讲二值信号量的创建及使用。

首先定义一下二值信号量的句柄并为其赋初始值为NULL:

SemaphoreHandle_t BinarySem_Handle =NULL; //二值信号量句柄

然后是xSemaphoreCreateBinary,它是FreeRTOS操作系统提供的一个函数,用于创建一个二值信号量,前面也说了,二值信号量是一个特殊的信号量,它的值只能是0或1,通常用于任务间的同步。其函数原型为:

SemaphoreHandle_t xSemaphoreCreateBinary(void);

这个函数没有参数,但有一个返回值,通常返回的是一个二值信号量的句柄,如果创建成功就返回相应的值,失败就返回NULL。

发送二值信号量

也叫释放二值信号量,其函数为xSemaphoreGive(),该函数原型为:

BaseType_t xSemaphoreGive(SemaphoreHandle_t xSemaphore)

参数xSemaphore为需要发送或释放的信号量句柄,这里我们填入上面定义好的二值信号量句柄。同时,该函数还有一个返回值,返回的类型是BaseType_t,通常是一个整数类型。如果返回值为pdTRUE(在freertos中通常定义为1),则表示信号量发送或释放成功。如果返回值为pdFALSH(在freertos中通常定义为0),则表示发送或释放失败。

获取二值信号量

有发送就有获取,其函数为xSemaphoreTake(),该函数原型为:

BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore, TickType_t xTicksToWait);

参数xSemaphore跟上面的一样,填入定义好的句柄即可。参数xTicksToWait为任务等待信号量的最大时间,可根据需要选择,通常为portMAX_DELAY。该函数还有一个返回值,跟上面一样,这里就跳过了。

二值信号量示例代码

#include "myfreertos.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "queue.h"
#include "Usart.h"
#include "oled.h"
#include "Task.h"
#include "led.h"
#include "key.h"TaskHandle_t MyTaskHandler;//任务句柄TaskHandle_t MyTask1Handler;//任务1句柄TaskHandle_t SendTask_Handler;  //发送消息句柄TaskHandle_t ReceiveTask_Handler;//接收消息句柄void MyTask(void *pvParameters);    //声明启动函数void MyTask1(void *pvParameters);   //声明任务1函数void Send_task(void *pvParameters);  //声明发送消息函数void Receive_task(void *pvParameters);  //声明接收消息函数SemaphoreHandle_t BinarySem_Handle =NULL; //二值信号量句柄void Start_Task(void)
{xTaskCreate(MyTask,"MyTask",128,NULL,1,&MyTaskHandler);//动态方法创建任务vTaskStartScheduler();//启动任务调动		
}void MyTask(void *arg)            //开始创建任务函数
{taskENTER_CRITICAL();           //进入临界区	/* 创建二值信号量 BinarySem */BinarySem_Handle = xSemaphoreCreateBinary();	xTaskCreate(MyTask1,"MyTask1",50,NULL,2,&MyTask1Handler);//动态方法创建任务1xTaskCreate(Receive_task,"Receive_task",50,NULL,3,&ReceiveTask_Handler);//创建接收消息任务xTaskCreate(Send_task,"Send_task",50,NULL,4,&SendTask_Handler);  //创建发送消息任务vTaskDelete(MyTaskHandler);    //删除开始任务taskEXIT_CRITICAL();           //退出临界区
}void MyTask1(void *arg)     //任务1函数体
{while(1){OLED_ShowString(1,1,"Runing Task Led");GPIO_ResetBits(GPIOC,GPIO_Pin_13);vTaskDelay(300);GPIO_SetBits(GPIOC,GPIO_Pin_13);vTaskDelay(900);}	
}//接收任务函数
void Receive_task(void *pvParameters)
{BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */while(1){		      //获取二值信号量 xSemaphore,没获取到则一直等待xReturn = xSemaphoreTake(BinarySem_Handle,100); /* 等待时间 */if(pdTRUE == xReturn)OLED_ShowString(3,1,"Receive_OK");elseOLED_ShowString(3,1,"Receive_NO");vTaskDelay(200);}
}//发送任务函数
void Send_task(void *pvParameters)
{BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */while(1){if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==1){xReturn = xSemaphoreGive( BinarySem_Handle );//给出二值信号量if( xReturn == pdTRUE )OLED_ShowString(2,1,"Send_OK");}else{OLED_ShowString(2,1,"Send_NO");}vTaskDelay(200);}
}

计数信号量

创建计数信号量

跟二值信号量一样,先定义一个计数信号量句柄并给其赋初值为NULL:

SemaphoreHandle_t CountSem_Handle =NULL; //计数信号量句柄

xSemaphoreCreateCounting()是FreeRTOS中用于创建计数信号量的函数,其函数原型为:

SemaphoreHandle_t xSemaphoreCreateCounting(
UBaseType_t uxMaxCount,
UBaseType_t uxInitialCount
)

参数uxMaxCount是计数信号量的最大计数值,当信号量值达此值时,不能再通过xSemaphoreGive增加其值。参数uxInitialCount为信号量的初始计数值。该函数还有一个返回值,如果成功创建信号量,就返回信号量的句柄,失败则返回NULL。

发送计数信号量与获取计数信号量

步骤都跟二值信号量大致相同,这里就不过多论述。

计数信号量示例代码

#include "myfreertos.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "queue.h"
#include "Usart.h"
#include "oled.h"
#include "Task.h"
#include "led.h"
#include "key.h"TaskHandle_t MyTaskHandler;//任务句柄TaskHandle_t MyTask1Handler;//任务1句柄TaskHandle_t SendTask_Handler;  //发送消息句柄TaskHandle_t ReceiveTask_Handler;//接收消息句柄void MyTask(void *pvParameters);    //声明启动函数void MyTask1(void *pvParameters);   //声明任务1函数void Send_task(void *pvParameters);  //声明发送消息函数void Receive_task(void *pvParameters);  //声明接收消息函数SemaphoreHandle_t CountSem_Handle =NULL; //计数信号量句柄void Start_Task(void)
{xTaskCreate(MyTask,"MyTask",128,NULL,1,&MyTaskHandler);//动态方法创建任务vTaskStartScheduler();//启动任务调动		
}void MyTask(void *arg)            //开始创建任务函数
{taskENTER_CRITICAL();           //进入临界区	/* 创建 CountSem */CountSem_Handle = xSemaphoreCreateCounting(5,5); 	xTaskCreate(MyTask1,"MyTask1",50,NULL,2,&MyTask1Handler);//动态方法创建任务1xTaskCreate(Receive_task,"Receive_task",50,NULL,3,&ReceiveTask_Handler);//创建接收消息任务xTaskCreate(Send_task,"Send_task",50,NULL,4,&SendTask_Handler);  //创建发送消息任务vTaskDelete(MyTaskHandler);    //删除开始任务taskEXIT_CRITICAL();           //退出临界区
}void MyTask1(void *arg)     //任务1函数体
{while(1){OLED_ShowString(1,1,"Runing Task Led");GPIO_ResetBits(GPIOC,GPIO_Pin_13);vTaskDelay(300);GPIO_SetBits(GPIOC,GPIO_Pin_13);vTaskDelay(900);}	
}//接收任务函数
void Receive_task(void *pvParameters)
{BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */while(1){		      //获取计数信号量 xSemaphore,没获取到则一直等待xReturn = xSemaphoreTake(CountSem_Handle,100); /* 等待时间 */if(pdTRUE == xReturn)OLED_ShowString(3,1,"Receive_OK");//elseOLED_ShowString(3,1,"Receive_NO");vTaskDelay(200);}
}//发送任务函数
void Send_task(void *pvParameters)
{BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */while(1){if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6)==1){xReturn = xSemaphoreGive( CountSem_Handle );//给出计数信号量if( xReturn == pdTRUE )OLED_ShowString(2,1,"Send_OK");}else{OLED_ShowString(2,1,"Send_NO");}vTaskDelay(200);}
}

二值信号量与计数信号量的区别

二值信号量只有两种状态(0和1),通常用于控制互斥访问,一次只允许一个进程进入临界区。而计数信号量可以有多个值,用于表示资源的数量,允许多个进程同时访问有限数量的资源。

讲解一下上面两个代码的思路

二值信号量

这个我主要是通过按下按键然后去释放二值信号量,按下按键释放二值信号量,然后被接收二值信号量任务接收,该任务就会执行里面的程序,执行完以后退出,二值信号量的信息返回值有由1变0,等待下一次信号的到来。值得注意的是,二值信号量是单次事件,如果需要执行多个事件,执行事件的顺序就从高优先级向低优先级执行,不能同时执行。

计数信号量

跟二值信号量的思路逻辑是一样的,但对于计数信号量而言,它能同时执行多个任务,提高了资源的利用率。

总结

以上是我的个人看法,如有不足,欢迎指出!

http://www.dtcms.com/a/419364.html

相关文章:

  • tomcat创建bat启动,结合任务计划实现自动重启tomcat服务
  • 滨海网站建设wordpress .htaccess下载
  • CCS主题配置,
  • 08网站建设自己做电商网站吗
  • Nginx 入门:高性能 Web 服务器与反向代理的利器
  • [Linux基础——Lesson2.Linux的基本指令使用]
  • wordpress建小说网站wordpress后台文章排序
  • 河北住房建设厅网站军事新闻头条
  • 鸿蒙Next HCE卡模拟开发指南:从零构建虚拟NFC应用
  • 从零构建短视频推荐系统:双塔算法架构解析与代码实现
  • 摄像头,硬盘录像机,网络平台,图像处理算法之间的联系和工作方式
  • 信阳网站建设信阳淘宝搜索关键词排名
  • 开发施工建设网站审核视频网站后台管理
  • Lightpanda:专为 AI 和自动化设计的无头浏览器
  • 做烘焙的网站网络营销的形式网站营销
  • PyTorch 中模型测试与全局平均池化的应用总结
  • 社交媒体与兴趣电商环境下品类创新机会研究——以“开源AI智能名片链动2+1模式S2B2C商城小程序”为例
  • 【pytorch】数据增强与时俱进,未来的改进和功能将仅添加到 torchvision.transforms.v2 转换中
  • java设计模式:建造者模式
  • 建设银行如何招聘网站动易网站 青春
  • Nginx 高级配置指南:Rewrite、If判断、浏览器分离与防盗链
  • 蓝桥杯嵌入式——基础模块的使用(初始化+调度器+LED+按键+LCD)
  • 厦门专业网站推广建站深圳建设集团是国企吗
  • web开发兼容注意
  • websocket网络通信协议
  • 佛山网站建设的大品牌wordpress远程写作
  • 网站建设的可用性yw55523can优物入口4虎
  • 如何将网站从建站服务商转移出来
  • 使用C#将Markdown转换为Word或PDF:高效文档转换的利器
  • 做淘宝优惠网站坪山网站建设行情