【freertos】FreeRTOS信号量的介绍及使用
FreeRTOS信号量
- 一、概述
- 二、PV原语
- 三、函数接口
- 1.创建一个计数信号量
- 2.删除一个信号量
- 3.信号量释放
- 4.在中断释放信号量
- 5.获取一个信号量,可以是二值信号量、计数信号量、互斥量。
- 6.在中断获取一个信号量,可以是二值信号量、计数信号量
- 7.创建一个二值信号量
- 四、示例代码
- 1、计数型信号量
- 2、二值信号量-保护共享资源
- 五、优先级翻转
- 1、概述
- 2、解决方案
一、概述
\quad 信号量,Semaphore。
\quad 信号量常用于任务的同步,通过该信号,就能够控制某个任务的执行,这个信号具有计数值,因此,可以称为计数信号量。
\quad 计数信号量可以用于资源管理,允许多个任务获取信号量访问共享资源,但会限制任务的最大数目,初值常为共享资源的数量。访问的任务数达到可支持的最大数目时,会阻塞其他试图获取该信号量的任务,直到有任务释放了信号量。这就是计数型信号量的运作机制,虽然计数信号量允许多个任务访问同一个资源,但是也有限定,比如某个资源限定只能有3个任务访问,那么第4个任务访问的时候,会因为获取不到信号量而进入阻塞,等到有任务(比如任务1)释放掉该资源的时候,第4个任务才能获取到信号量从而进行资源的访问,其运作的机制具体见下图。
二、PV原语
$\quad$1965年,荷兰学者Dijkstra提出了利用信号量机制解决进程同步问题,信号量正式成为有效的进程同步工具,现在信号量机制被广泛的用于单处理机和多处理机系统以及计算机网络中。
\quad 信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用临界区的进程数。
\quad Dijkstra同时提出了对信号量操作的PV原语。
P原语操作的动作是:
(1)S减1;
(2)若S减1后仍大于或等于零,则进程继续执行;
(3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度。
V原语操作的动作是:
(1)S加1;
(2)若相加结果大于零,则进程继续执行;
(3)若相加结果小于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度。
PV操作对于每一个进程来说,都只能进行一次,而且必须成对使用。在PV原语执行期间不允许有中断的发生。
\quad 信号量的P、V操作,P表示申请一个资源,每次P操作使信号量减1,V是释放一个资源,每次V操作使信号量加1。信号量表示的是当前可用的资源个数,当信号量为负时,申请资源的进程(任务)就只能等待了。所以,信号量是负的多少,就表明有多少个进程(任务)申请了资源但无资源可用,只能处于等待状态。
\quad 除了访问共享资源外,亦可中断/任务控制某任务的执行,称之为“单向同步”。
三、函数接口
信号量使能,文件路径:freertos.h,另外用户代码要包含semphr.h。
#ifndef configUSE_COUNTING_SEMAPHORES#define configUSE_COUNTING_SEMAPHORES 1
#endif
1.创建一个计数信号量
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount);
参数说明:
- uxMaxCount-计数信号量的最大值,当达到这个值的时候,信号量不能再被释放。
- uxInitialCount-创建计数信号量的初始值。
返回值:
- 如果创建成功则返回一个计数信号量句柄,用于访问创建的计数信号量。
- 如果创建不成功则返回 NULL。
2.删除一个信号量
\quad vSemaphoreDelete()用于删除一个信号量,包括二值信号量,计数信号量,互斥量和递 归互斥量。如果有任务阻塞在该信号量上,那么不要删除该信号量。
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
参数说明:
- xSemaphore-信号量句柄。
返回值:
\quad 无。
3.信号量释放
\quad xSemaphoreGive()是一个用于释放信号量的宏,真正的实现过程是调用消息队列通用发送函数。释放的信号量对象必须是已经被创建的,可以用于二值信号量、计数信号量、互斥量的释放,但不能释放由函数xSemaphoreCreateRecursiveMutex()创建的递归互斥量。此外该函数不能在中断中使用。
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );
参数说明:
- xSemaphore-信号量句柄。
返回值:
- pdTRUE-信号量被释放。
- pdFALSE-信号量发生错误,
4.在中断释放信号量
\quad 用于释放一个信号量,带中断保护。被释放的信号量可以是二进制信号量和计数信号量。
BaseType_t xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore,signed BaseType_t *pxHigherPriorityTaskWoken)
参数说明:
- xSemaphore-信号量句柄。
- pxHigherPriorityTaskWoken-一个或者多个任务有可能阻塞在同一个信号量上,调用函数xSemaphoreGiveFromISR()会唤醒阻塞在该信号量上优先级最高的信号量入队任务,如果被唤醒的任务的优先级大于或者等于被中断的任务的优先级,那么形参
pxHigherPriorityTaskWoken 就会被设置为
pdTRUE,然后在中断退出前执行一次上下文切换,中断退出后则直接返回刚刚被唤醒的高优先级的任务。从 FreeRTOS V7.3.0
版本开始,pxHigherPriorityTaskWoken 是一个可选的参数,可以设置为 NULL。
返回值:
- pdTRUE-信号量被释放
- pdFALSE-信号量 发生错误
5.获取一个信号量,可以是二值信号量、计数信号量、互斥量。
\quad xSemaphoreTake()函数用于获取信号量,不带中断保护。获取的信号量对象可以是二 值信号量、计数信号量和互斥量,但是递归互斥量并不能使用这个 API 函数获取。其实获取信号量是一个宏,真正调用的函数是 xQueueGenericReceive ()。该宏不能在中断使用, 而是必须由具体中断保护功能的 xQueueReceiveFromISR()版本代替。
BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore,TickType_t xTicksToWait );
参数说明:
- xSemaphore-信号量句柄。
- xTicksToWait -等待信号量可用的最大超时时间,单位为 tick(即系统节拍周期)。 如果宏
INCLUDE_vTaskSuspend 定义为 1 且形参 xTicksToWait 设置为 portMAX_DELAY
,则任务将一直阻塞在该信号量上(即没有超时时间)。
返回值:
- 获取成功则返回pdTRUE,
- 在指定的超时时间中没有获取成功则返回errQUEUE_EMPTY。
\quad 从该宏定义可以看出释放信号量实际上是一次消息出队操作,阻塞时间由用户指定xTicksToWait,当有任务试图获取信号量的时候,当且仅当信号量有效的时候,任务才能读获取到信号量。如果信号量无效,在用户指定的阻塞超时时间中,该任务将保持阻塞状态以等待信号量有效。当其它任务或中断释放了有效的信号量,该任务将自动由阻塞态转移为就绪态。当任务等待的时间超过了指定的阻塞时间,即使信号量中还是没有可用信号量,任务也会自动从阻塞态转移为就绪态。
6.在中断获取一个信号量,可以是二值信号量、计数信号量
\quad xSemaphoreTakeFromISR()是函数 xSemaphoreTake()的中断版本,用于获取信号量,是一个不带阻塞机制获取信号量的函数,获取对象必须由是已经创建的信号量,信号量类型可以是二值信号量和计数信号量,它与 xSemaphoreTake()函数不同,它不能用于获取互斥xSemaphoreTake()函数不同,它不能用于获取互斥量,因为互斥量不可以在中断中使用,并且互斥量特有的优先级继承机制只能在任务中起作用,而在中断中毫无意义。
BaseType_t xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore, signed BaseType_t *pxHigherPriorityTaskWoken)
功能描述:在中断中获一个信号量(其实很少在中断中获取信号量)。可以是二值信号量、计数信号量。
参数说明:
- xSemaphore-信号量句柄。
- pxHigherPriorityTaskWoken-一个或者多个任务有可能阻塞在同一个信号量上,调用函数xSemaphoreTakeFromISR()会唤醒阻塞在该信号量上优先级最高的信号量入队任务,如果被唤醒的任务的优先级大于或者等于被中断的任务的优先级,那么形参
pxHigherPriorityTaskWoken 就会被设置为
pdTRUE,然后在中断退出前执行一次上下文切换,中断退出后则直接返回刚刚被唤醒的高优先级的任务,可提高实时性。从 FreeRTOS
V7.3.0 版本开始,pxHigherPriorityTaskWoken 是一个可选的参数,可以设置为 NULL。
返回值:
- 获取成功则返回 pdTRUE,
- 没有获取成功则返回 errQUEUE_EMPTY,没有获取成功是因为信号量不可用。
7.创建一个二值信号量
\quad 二值信号量通常用于互斥访问或同步,二值信号量和互斥信号量非常类似,但是还是有一些细微的差别,互斥信号量拥有优先级继承机制,二值信号量没有优先级继承
。因此二值信号另更适合用于同步(任务与任务或任务与中断的同步,即控制任务的执行),而互斥信号量适合用于简单的互斥访问。
SemaphoreHandle_t xSemaphoreCreateBinary( void );
参数说明:
\quad 无
返回值:
- 如果创建成功则返回一个二值信号量句柄,用于访问创建的二值信号量。
- 如果创建不成功则返回 NULL。
四、示例代码
1、计数型信号量
#include "semphr.h"SemaphoreHandle_t g_sem_count;int main(void)
{/* 创建计数型的信号量 ,计数值递增到最大值就不能再增加了,初值为0*/g_sem_count=xSemaphoreCreateCounting(255,0); }void app_task1(void *pvParameters)
{while(1){ /* 发送信号 */xSemaphoreGive(g_sem_count);xSemaphoreGive(g_sem_count);xSemaphoreGive(g_sem_count);printf("[app_task1] running ...........\r\n");vTaskDelay(1000);}
}void app_task2(void *pvParameters)
{while(1){ /* 等待信号量,portMAX_DELAY一直阻塞等待 */xSemaphoreTake(g_sem_count,portMAX_DELAY);printf("[app_task2] running ...........\r\n");}
}
现象:
2、二值信号量-保护共享资源
前提:使用二值信号量的任务优先级相同,若不相同可能会导致优先级翻转。
#include "semphr.h"SemaphoreHandle_t g_sem_binary;int main(void)
{/* 创建二值型信号量*/vSemaphoreCreateBinary(g_sem_binary);
}void app_task1(void *pvParameters)
{while(1){ /* 等待信号量,portMAX_DELAY一直阻塞等待 */xSemaphoreTake(g_sem_binary,portMAX_DELAY);printf("[app_task1] running ...........\r\n");/* 释放信号 */xSemaphoreGive(g_sem_binary);vTaskDelay(1000);}
}void app_task2(void *pvParameters)
{while(1){ /* 等待信号量,portMAX_DELAY一直阻塞等待 */xSemaphoreTake(g_sem_binary,portMAX_DELAY);printf("[app_task2] running ...........\r\n");/* 释放信号 */xSemaphoreGive(g_sem_binary);vTaskDelay(1000);}
}
现象:
五、优先级翻转
1、概述
\quad 优先级翻转是当一个高优先级任务通过信号量机制访问共享资源时,该信号量已被一低优先级任务占有,因此造成高优先级任务被许多具有较低优先级任务阻塞,实时性难以得到保证。
\quad 高优先级任务无法运行而低优先级任务(任务M、任务L)可以运行的现象称为“优先级翻转”。
(1)任务H和任务M处于挂起状态,等待某一事件的发生,任务L正在运行。
(2)某一时刻任务L想要访问共享资源,在此之前它必须先获得对应该资源的信号量。
(3)任务L获得信号量并开始使用该共享资源。
(4)由于任务H优先级高,它等待的事件发生后便剥夺了任务L的CPU使用权。
(5)任务H开始运行。
(6)任务H运行过程中也要使用任务L正在使用着的资源,由于该资源的信号量还被任务L占用着,任务H只能进入阻塞等待状态,等待任务L释放该信号量。
(7)任务L继续运行。
(8)由于任务M的优先级高于任务L,当任务M等待的事件发生后,任务M剥夺了任务L的CPU使用权。
(9)任务M处理该处理的事。
(10)任务M执行完毕后,将CPU使用权归还给任务L。
(11)最终任务L完成所有的工作并释放了信号量,到此为止,由于实时内核知道有个高优先级的任务在等待这个信号量,故内核做任务切换。
\quad 在这种情况下,任务H的优先级实际上降到了任务L的优先级水平。因为任务H要一直等待直到任务L释放其占用的那个共享资源。由于任务M剥夺了任务L的CPU使用权,使得任务H的情况更加恶化,这样就相当于任务M的优先级高于任务H,导致优先级翻转。
\quad 优先级翻转。简单地说,就是高优先级任务必须等待低优先级任务的完成。
示例代码:
static void app_task_Low(void* pvParameters)
{uint32_t i;while(1){xSemaphoreTake(BinarySemaphore,portMAX_DELAY); //获取二值信号量printf("[taskL]:access res begin\r\n");printf("low task Running!\r\n");for(i=0; i<0x5000000; i++) //模拟低优先级任务占用二值信号量{//taskYIELD(); //发起任务调度}printf("[taskL]:access res end\r\n");xSemaphoreGive(BinarySemaphore); //释放二值信号量vTaskDelay(1000); //延时1s,也就是1000个时钟节拍 }
} static void app_task_med(void* pvParameters)
{EventBits_t EventValue;for(;;){vTaskDelay(1000); //延时1s,也就是1000个时钟节拍 printf("[taskM]:middle task running!\r\n");}
} static void app_task_high(void* pvParameters)
{BaseType_t err=pdFALSE;for(;;){ vTaskDelay(500); //延时500ms,也就是500个时钟节拍 xSemaphoreTake(BinarySemaphore,portMAX_DELAY); //获取二值信号量printf("[taskH]:access res begin\r\n");printf("high task Running!\r\n");printf("[taskH]:access res end\r\n");xSemaphoreGive(BinarySemaphore); //释放信号量vTaskDelay(500); //延时500ms,也就是500个时钟节拍 }}
2、解决方案
\quad 为了避免优先级翻转这个问题,RTOS支持一种特殊的二进制信号量:互斥信号量,即互斥锁,用它可以解决优先级翻转问题。
\quad 目前解决优先级翻转有许多种方法。其中普遍使用的有2种方法:一种被称作优先级继承(priority inheritance);另一种被称作优先级天花板(priority ceilings)。
A. 优先级继承(priority inheritance) :优先级继承是指将低优先级任务的优先级提升到等待它所占有的资源的最高优先级任务的优先级。当高优先级任务由于等待资源而被阻塞时,此时资源的拥有者的优先级将会临时自动被提升,以使该任务不被其他任务所打断,从而能尽快的使用完共享资源并释放,再恢复该任务原来的优先级别。
B. 优先级天花板(priority ceilings): 优先级天花板是指将申请某资源的任务的优先级提升到可能访问该资源的所有任务中最高优先级任务的优先级
。(这个优先级称为该资源的优先级天花板) 。这种方法简单易行, 不必进行复杂的判断, 不管任务是否阻塞了高优先级任务的运行, 只要任务访问共享资源都会提升任务的优先级。
A和B的区别:优先级继承,只有当占有资源的低优先级的任务被阻塞时,才会提高占有资源任务的优先级;而优先级天花板,不论是否发生阻塞,都提升。
在UCOSIII/FreeRTOS,默认使用方案A,详细如下图。
相关文章:

【freertos】FreeRTOS信号量的介绍及使用
FreeRTOS信号量 一、概述二、PV原语三、函数接口1.创建一个计数信号量2.删除一个信号量3.信号量释放4.在中断释放信号量5.获取一个信号量,可以是二值信号量、计数信号量、互斥量。6.在中断获取一个信号量,可以是二值信号量、计数信号量7.创建一个二值信号…...

React Native 全栈开发实战班 - 图片加载与优化
在移动应用中,图片加载与优化 是提升用户体验和减少资源消耗的重要环节。图片加载不当可能导致应用卡顿、内存泄漏甚至崩溃。本章节将介绍 React Native 中常用的图片加载方法,包括 Image 组件的使用、第三方图片加载库(如 react-native-fast…...

Golang云原生项目:—实现ping操作
熟悉报文结构 ICMP校验和算法: 报文内容,相邻两个字节拼接到一起组成一个16bit数,将这些数累加求和若长度为奇数,则将剩余一个字节,也累加求和得出总和之后,将和值的高16位与低16位不断求和,直…...

mysql如何查看当前事务的事务id
-- 开启一个事务,但不执行写操作 START TRANSACTION; -- 查询 InnoDB 事务信息 SELECT * FROM information_schema.innodb_trx;在 MySQL 的 MVCC (多版本并发控制) 中,事务 ID (Transaction ID) 是由 InnoDB 存储引擎分配的,它的分配机制与事…...

在linux里如何利用vim对比两个文档不同的行数
在Linux中,可以使用vimdiff命令来对比两个文档中不同的行。首先确保你的系统中安装了vim编辑器。 打开终端,使用以下命令来启动vimdiff: vimdiff file1 file2 这里file1和file2是你想要对比的两个文件的路径。 vimdiff会以并排方式打开两…...

深入解析Python中的逻辑回归:从入门到精通
引言 在数据科学领域,逻辑回归(Logistic Regression)是一个非常重要的算法,它不仅用于二分类问题,还可以通过一些技巧扩展到多分类问题。逻辑回归因其简单、高效且易于解释的特点,在金融、医疗、广告等多个…...

【数据库】mysql数据库迁移前应如何备份数据?
MySQL 数据库的备份是确保数据安全的重要措施之一。在进行数据库迁移之前,备份现有数据可以防止数据丢失或损坏。以下是一套详细的 MySQL 数据库备份步骤,适用于大多数情况。请注意,具体的命令和工具可能因 MySQL 版本的不同而有所差异。整个…...

C语言——鸡兔同笼问题
没注释的源代码 #include <stdio.h> #include <stdlib.h> /* run this program using the console pauser or add your own getch, system("pause") or input loop */ int main(int argc, char *argv[]) { int tou 10; i…...

数据结构王道P234第二题
#include<iostream> using namespace std; int visit[MAxsize]; int color[MaxSize];//1表示红,2表示白; bool dfs(Graph G, int i){visit[i]1;ArcNode *p;bool flag1;for(pG.vertices[i].firsrarc; p ; pp->next){int jp->adjvex;if(!visi…...

层归一化和批归一化
层归一化是针对某一样本的所有特征,批归一化是针对所有样本的某一特征。 计算公式:(当前值 - 均值)/ 标准差。 作用:缓解梯度消失和梯度爆炸的问题,并提高网络的泛化性能。 为什么Transform和BERT中使用层归…...

Spring Cloud Gateway 网关
微服务网关 Spring Cloud Gateway https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories Spring Cloud 在版本 2020.0.0 开始,去除了 Zuul 网关的使用,改用 Spring Cloud Gateway 作为网关…...

LabVIEW中的UDP与TCP比较
在LabVIEW中,UDP和TCP可以用于不同的网络通信场景,开发者可以根据需求选择合适的协议。以下是结合LabVIEW开发时的一些比较和应用场景: 1.TCP在LabVIEW中的应用: 可靠性高的场景:当开发一个对数据传输的准确性和完整…...

半导体器件与物理篇3 P-N结
热平衡时的PN结 pn结的定义:由p型半导体和n型半导体接触形成的结 pn结的特性和关键变量包括:整流性(即电流单向导通的特性)、平衡费米能级(费米能级 E F E_F EF为常数, d E F d x 0 )、内建电势 \frac…...

深入剖析String类的底层实现原理
嘿嘿,家人们,今天咱们来模拟实现string,好啦,废话不多讲,开干! 1:string.h 1.1:构造函数与拷贝构造函数 1.1.1:写法一 1.1.2:写法二(给缺省值) 1.2:赋值运算符重载与operatror[]获取元素 1.3:容量与迭代器 1.4:reserve与resize 1.5:清空与判断是否为空 1.6:push_back与…...

#其它:面试题
第一面试官提问如下: 1、自我介绍 2、根据项目提问:混合开发调取api的通讯方式 3、技术提问:如何隐藏div,但是div需要存在 使用 visibility 隐藏: 1.visibility: hidden2.display: none 3.opcity: 04、css塌陷问题…...

计算机视觉中的双边滤波:经典案例与Python代码解析
🌟 计算机视觉中的双边滤波:经典案例与Python代码解析 🚀 Hey小伙伴们!今天我们要聊的是计算机视觉中的一个重要技术——双边滤波。双边滤波是一种非线性滤波方法,主要用于图像去噪和平滑,同时保留图像的边…...

【AI日记】24.11.17 看 GraphRAG 论文,了解月之暗面
【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 核心工作 内容:看 GraphRAG 论文时间:4 小时评估:不错,继续 非核心工作 内容:了解国内大模型方向,重点了解了创业独角兽-月之暗面&…...

Front Panel Window Bounds 与 Front Panel Window Bounds 的区别与应用
在LabVIEW中,Front Panel Window Bounds 和 Front Panel WindowBounds 是两个不同的属性节点,用于描述前面板窗口的位置和大小。它们的区别主要体现在它们表示的是窗口的不同部分,具体如下: 1 Window Bounds:调整整个…...

比较TCP/IP和OSI/RM的区别
一、结构不同 1、OSI:OSI划分为7层结构:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。 2、TCP/IP:TCP/IP划分为4层结构:应用层、传输层、互联网络层和主机-网络层。 二、性质不同 1、OSI:OSI是制定…...

【Java项目】基于SpringBoot的【招聘信息管理系统】
技术简介:系统软件架构选择B/S模式、SpringBoot框架、java技术和MySQL数据库等,总体功能模块运用自顶向下的分层思想。 系统简介:招聘信息管理系统的功能分为管理员,用户和企业三个部分,系统的主要功能包括首页、个人中…...

【论文笔记】LLaMA-VID: An Image is Worth 2 Tokens in Large Language Models
🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 基本信息 标题: LLaMA-VID: An Image is W…...

使用Web Storage API实现客户端数据持久化
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 使用Web Storage API实现客户端数据持久化 使用Web Storage API实现客户端数据持久化 使用Web Storage API实现客户端数据持久化…...

基于STM32F103的秒表设计-液晶显示
基于STM32F103的秒表设计-液晶显示 仿真软件: Proteus 8.17 编程软件: Keil 5 仿真实现: 在液晶1602上进行秒表显示,每100ms改变一次数值,一共三个按键,分为启动按键、暂停按键、复位按键。 电路介绍: 前面章节里已经和大家介绍了使用数码管设计的秒表,本次仿真将数…...

ReentrantLock的具体实现细节是什么
在 JDK 1.5 之前共享对象的协调机制只有 synchronized 和 volatile,在 JDK 1.5 中增加了新的机制 ReentrantLock,该机制的诞生并不是为了替代 synchronized,而是在 synchronized 不适用的情况下,提供一种可以选择的高级功能。 在 Java 中每个对象都隐式包含一个 monitor(监…...

【JavaScript】this 指向
1、this 指向谁 多数情况下,this 指向调用它所在方法的那个对象。即谁调的函数,this 就归谁。 当调用方法没有明确对象时,this 就指向全局对象。在浏览器中,指向 window;在 Node 中,指向 Global。&#x…...

DB Type
P位 p 1时段描述符有效,p 0时段描述符无效 Base Base被分成了三个部分,按照实际拼接即可 G位 如果G 0 说明描述符中Limit的单位是字节,如果是G 1 ,那么limit的描述的单位是页也就是4kb S位 S 1 表示代码段或者数据段描…...

python-返回函数
Python的函数不但可以返回int、str、list、dict等数据类型,还可以返回函数! 例如,定义一个函数 f(),我们让它返回一个函数 g,可以这样写: def f()ÿ…...

python语言基础-5 进阶语法-5.2 装饰器-5.2.1 闭包
声明:本内容非盈利性质,也不支持任何组织或个人将其用作盈利用途。本内容来源于参考书或网站,会尽量附上原文链接,并鼓励大家看原文。侵删。 5.2 装饰器 python中的装饰器相当于java中的注解。装饰器用于为函数添加某些修饰性、…...

用vscode编写verilog时,如何有信号定义提示、信号定义跳转(go to definition)、模块跳转(跨文件跳转)这些功能
(一)方法一:安装插件SystemVerilog - Language Support 安装一个vscode插件即可,插件叫SystemVerilog - Language Support。虽然说另一个插件“Verilog-HDL/SystemVerilog/Bluespec SystemVerilog”也有信号提示及定义跳转功能&am…...

MQTT+Springboot整合
1.mqttconfig配置(配置参数是从数据库查出来的) package com.terminal.dc3.api.center.manager.config;import com.collection.common.utils.StringUtils; import com.collection.system.mapper.MqttConfigMapper; import lombok.Data; import org.springframework.beans.fact…...