day03(单片机高级)RTOS

目录

RTOS(实时操作系统)

裸机开发模式

轮询方式

前后台(中断方式)

改进(前后台(中断))定时器

 裸机进一步优化

裸机的其他问题

RTOS的概念

什么是RTOS

为什么要使用 RTOS

RTOS的应用场景

RTOS的选择

RTOS的工作原理

FreeRTOS特点

创建第一个FreeRTOS程序

搭建方法

1、官网源码下载

2、处理工程目录

3、打开编译工程

4、去掉无关代码

5、删除未定义报错内容

6、验证

串口打印实验

如何找串口仿真

命名规范

动态任务的创建

任务实验

实现

函数原型

实验

优先级

延时函数

查看延时时间验证

调度原理

抢占式调度

时间片调度

任务状态

挂起任务、恢复任务

挂起任务函数原型

恢复任务函数原型

任务删除

函数原型

空闲任务

空闲任务钩子函数用途

空闲任务钩子函数的实现限制

钩子函数的使用

使用CUBE配置FreeRTOS编写程序

1、更新安装freertos插件

2.配置FreeRTOS

3.配置基础硬件

4.最后生成工程MDK内编写程序


 

RTOS(实时操作系统)

裸机开发模式

轮询方式

对于简单的应用程序,轮询(无限循环)的实现比较简单,在硬件完成初始化后,顺序的完成各种 任务。在外设的基础实验中,常采用这种方式。

int main()
{ while(1){
     DHT11数据采集;
     读取WIFI数据;
     判断数据;}
}

在实际的嵌入式系统中,存在周期性与触发型任务,每个任务的执行时间与实时响应要求不同,在采用轮询系统进行程序设计时,很难应对这些场景。

前后台(中断方式)

前后台系统是在轮询的基础上加入了中断。外部事件的记录在中断中操作,对事件的响应在轮询中 完成,中断处理过程称之为前台,main 函数中的轮询称为后台。

后台的程序顺序执行,如果产生中断,那么中断会打断后台程序的正常执行,转而去执行中断服务 程序。如果事件的处理过程比较简单,可以直接在中断服务程序中进行处理;如果事件的处理过程比较 复杂,可以在中断中对事件响应进行标记,进而返回后台程序进行处理。

int main()
{ while(1){if(DHT11==1){
     DHT11数据处理;
     DHT11=0;}if(wifi==1){
     处理WIFI数据;
     wifi=0;}}
}
void DHT11_irq()
{
    DHT11=1;
}
void WIFI_irq()
{
    wifi=1;
}
//中断处理的速度高了
//触发之后又成为了轮询操作
//假如DHT11优先级高,且处理时间过长 wifi的处理就不及时了

采用前后台系统进行程序时,对后台的任务需要进行设计,避免单个任务长时间占有处理器资源。 当任务的逻辑比较复杂,任务的拆分难度增加,同时,随着中断事件的增加,整个程序的设计与响应的 实时性将会降低。

改进(前后台(中断))定时器

设置3S定时器中断(DHT11采集)

设置5s定时器中断(Wifi数据处理)

 裸机进一步优化

void wifi(void)
{static int key=0;switch(key){case 0:
      发送AT指令();
      key=1return;case 1:
      接收数据();
       key=2return;case 2:
      判断数据();
      key=0return;} 
}
void DHT11(void)
{static int DHT11=0;switch(DHT11){case 0:
      握手();
      DHT11=1return;case 1:
      接收数据();
       DHT11=2return;case 2:
      判断数据完整性();
      DHT11=3;return;case 3:
      数据处理();
      DHT11=0;return;} 
}
//问题解决了,但是程序的复杂度上来了
//基于裸机架构无法完美解决复杂耗时的多个函数

裸机的其他问题

while(1)
{ 
  DHT11;if(key){delay(100);//程序在这停止了,效率被影响了if(key){wifi();}}
}

按键消抖优化:

在按键中断服务程序开启定时器

在定时器中断服务程序执行按键操作,并关掉定时器

RTOS的概念

什么是RTOS

为什么要使用 RTOS

主要是为了满足系统在时间和资源管理上的特殊需求

使用实时内核的理由可以从多个方面来描述,包括可维护性、可扩展性、模块化、团队开发、测试、代码复用、效率、空闲时间、电源管理、中断处理以及混合处理需求。以下是对这些方面的详细解释:

  • 可维护性:实时内核通常具有抽象化的时间细节,这减少了模块间的依赖关系,使软件更易于维护和演化。由于内核负责计时,应用程序的执行受底层硬件变化的影响较小,进一步提高了可维护性。
  • 模块化:实时内核的每个任务通常被设计为独立的模块,具有明确的设计目的。这种模块化设计有助于团队开发,因为每个团队成员可以独立地负责一个模块的开发和维护,提高开发效率和系统稳定性。
  • 可扩展性:实时内核的设计通常允许添加新的功能或模块,而不需要对现有系统进行大规模修改。这使得系统能够随着需求的变化而扩展,保持长久的生命力。
  • 代码复用:实时内核的模块化设计使得代码更容易被复用。通过低耦合设计,代码可以在不同的模块之间共享和重用,提高了开发效率并降低了维护成本。
  • 提升效率:实时内核通常设计为事件驱动,这意味着它仅在事件发生时才进行处理。这种设计有助于提高系统的响应速度和运行效率。

RTOS的应用场景

物联网(IoT):RTOS是专门为物联网设备设计的操作系统,它提供了实时性、高效性和可靠性,以满足物联网应用的特殊需求。RTOS通过任务调度算法管理任务的执行顺序,确保高优先级任务能够及时响应,满足物联网设备对实时性的要求。

智能家居:RTOS在智能家居系统中用于控制各种智能设备,如智能灯泡、智能插座、智能门锁等。RTOS提供了设备之间的实时通信和协同工作,使用户能够方便地通过智能手机或其他设备控制家居环境。

医疗设备:RTOS在医疗设备中发挥着重要作用,如心脏起搏器、监护仪等设备需要实时处理生理参数,确保患者的生命安全。RTOS的高可靠性和实时性使得这些设备能够在关键时刻发挥关键作用。SAFERTOS等RTOS产品特别针对医疗设备的需求,提供响应迅速、稳健、确定性的嵌入式实时操作系统,降低项目风险、开发成本,并缩短上市时间。

汽车电子:在汽车领域,RTOS的应用越来越广泛。例如,高级驾驶辅助系统(ADAS)需要实时处理大量的传感器数据,以实现自动驾驶、车辆导航等功能。RTOS能够确保这些系统的实时性和稳定性,提高驾驶安全性。

工业自动化和机器人技术:RTOS在工业自动化系统中扮演关键角色,通过精确定时和控制能力,确保生产线的稳定运行,提高生产效率和质量。在机器人技术中,RTOS能够确保机器人实时响应指令,执行复杂任务,如无人机和机器人的飞行轨迹控制、任务执行等。

航空航天:在航空航天领域,RTOS的应用至关重要。由于航空电子系统的复杂性和对实时性的极高要求,RTOS能够提供高度可靠的中断处理和任务调度机制,确保飞行控制系统、导航系统和传感器数据处理的实时性和准确性。

RTOS的选择

安全性:RTOS 是否有助于设备的安全性或损害设备的安全性?容易出现用户错误吗?

性能:RTOS 能否促进应用程序代码的开发?代码是否在所需参数内执行?

可靠性:RTOS 是否会影响设备的可靠性?

功能:RTOS 是否具备完成这项工作所需的设施?

学习RTOS的3个步骤

学会使用API

了解API实现原理

可以优化改进API

RTOS的工作原理

① RTOS相当于实现了后台的主循环,并能够处理ISR主循环的交互

使得用户可以只考虑任务的设计

③ RTOS还提供了各种组件用于实现任务间交互及其他控制管理功能(e.g. 存储管理)

提供多个执行流,虽然实际只有一颗CPU,但通过"虚拟化",每个Task好像独占CPU

提供资源管理和通信组件

提供一些组件用于简化任务对资源的访问,事件的处理,以及任务之间的通信,有效降低任务之间的代码耦合

FreeRTOS特点

创建第一个FreeRTOS程序

搭建方法

  1. 移植文件(FreeRTOS相关文件)+时钟配置
  2. 官网源码下的DEMO(需要精简 去掉无关文件)+标准库
  3. CUBEMX直接生成就可以了
1、官网源码下载

(1)进入FreeRTOS官网

(2)点击下载FreeRTOS

2、处理工程目录

(1)下载后解压FreeRTOS文件

(2)删除多余文件(红框里的)

(3)删除"FreeRTOSv202212.01\FreeRTOS\Demo"目录下用不到的示例工程,留下common这里放了一些公共文件

(4)"FreeRTOSv202212.01\FreeRTOS\Source\portable"目录下只保留如下两个文件夹,其他全部删掉。

(5)"FreeRTOSv202212.01\FreeRTOS\Source\portable\RVDS"目录下只保留如下一个文件夹,其他全部删掉

3、打开编译工程

(1删除后文件后,进入如下图打开工程

(2)弹出如下对话框,说明该工程是用KeilMDK4创建的。点击“Migrate to Device Pack”更新为KeilMDK5。

(3弹出对话框,点击“确定”。

  1. 更新后,关闭工程再重新打开,编译。
  2. 工程目录介绍(System里还有一个lcd也删掉)

4、去掉无关代码

(1Demo Files文件下只保留“serial.c和main.c”文件,其他都删掉(删完之后main里去掉一些头文件)

(2)编译

5、删除未定义报错内容

(1)在文件STM32F10x.s中,删除如下内容。

(2)删除其他未定义的相关内容,再次编译。报错的内容均删除或者注释,直到没错为止。

6、验证

在原有任务的基础上加个i++验证

串口打印实验

1、重定向

这个fputc在main中:

int fputc( int ch, FILE *f )//重定向  修改数据传输方向
{
  while(!(USART1->SR & (1<<7))){}
	USART1->DR =ch;
	return ch;
}

2、配置串口

初始化删除多余的东西,自己写一个串口一的初始化。

 void Uart_Init(void){
     GPIO_InitTypeDef GPIO_InitStructure;
	 USART_InitTypeDef USART_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE );//tx
		 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
		 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
		 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//rx
		 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
		 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA,&GPIO_InitStructure);	  USART_InitStructure.USART_BaudRate = 115200;
		USART_InitStructure.USART_WordLength = USART_WordLength_8b;
		USART_InitStructure.USART_StopBits = USART_StopBits_1;
		USART_InitStructure.USART_Parity = USART_Parity_No ;
		USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
		USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
		USART_InitStructure.USART_Clock = USART_Clock_Disable;
		USART_InitStructure.USART_CPOL = USART_CPOL_Low;
		USART_InitStructure.USART_CPHA = USART_CPHA_2Edge;
		USART_InitStructure.USART_LastBit = USART_LastBit_Disable;USART_Init( USART1, &USART_InitStructure );	  USART_Cmd( USART1, ENABLE ); }

如何找串口仿真

命名规范

数据类型

命名规范

动态任务的创建

任务是什么

任务是由 C 语言函数实现的。唯一特别的地方是其函数原型,必须返回 void,并带有一个 void 指针参数。

 任务的外观:一个永远不返回的函数

任务实验

实现

创建任务函数xTaskCreate:任务也不是很复杂的东西,任务也就是一个函数

xTaskCreate。简单得说,创建一个任务,你得提供它的执行函数,你得提供它的栈的大小,函数的执行空间,函数的优先级等重要的条件。因为任务在运行中,任务函数有调用关系,有局部变量,这些都保存在任务的栈里面;任务有可能被切换,有可能被暂停,这时候CPU寄存器中断现场数据都保存在栈里面。

函数原型

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName, const configSTACK_DEPTH_TYPE usStackDepth,
void * const pvParameters,
                            UBaseType_t uxPriority,
                            TaskHandle_t * const pxCreatedTask )

参数说明

pvTaskCode:指向任务函数的指针。该函数表示任务要执行的代码。

pcName:任务名称字符串。用于调试和跟踪,不影响任务功能。也可用于获取任务句柄

usStackDepth:任务栈大小(以单词为单位)。根据任务需求设定,过小可能导致栈溢出。

pvParameters:传递给任务函数的参数。可以是任意类型的指针。

uxPriority:任务优先级。数值越大,优先级越高。

pxCreatedTask:任务句柄指针。用于存储创建任务后的任务句柄,可选参数。可为NULL

返回值

如果任务创建成功,返回pdPASS。如果任务创建失败(例如内存不足),返回错误码。

任务创建成功后,系统会自动将其加入到调度队列。调度器会根据任务优先级选择合适的任务执行。

实验

优先级

结论

FreeRTOS中,优先级数越大优先级越高,两个任务同优先级时通过时间片轮转执行,如果有高优先级时,高优先级执行,一直到高优先级停止执行低优先级才能执行。

延时函数

void vTaskDelay( const TickType_t xTicksToDelay );

查看延时时间验证

声明个变量a只有任务一执行时才为1,其他时候为0,然后进入仿真使用虚拟逻辑分析仪查看变量a状态

查看方法(进入仿真使用):

调度原理

调度器是内核中负责决定在任何特定时间应执行哪些任务的部分。内核可以在任务生命周期内多次挂起并且稍后恢复一个任务。调度策略是调度器用来决定在任何时间点执行哪个任务的算法。非实时多用户系统的策略极有可能使每个任务具有"公平"比例的处理时间。

FreeRTOS 共支持三种任务调度方式,分别为抢占式调度、时间片调度和协程式调度。需要注意的是,FreeRTOS 官方对协程式调度做了特殊说明,协程式调度用于一些资源非常少的设备上,但是现在已经很少用到。虽然协程式调度的相关代码还没有被删除,FreeRTOS 官方并未计划继续开发协程式调度。因此不推荐在开发中继续使用协程式调度,我们接着理解一下抢占式调度与时间片调度的概念。

抢占式调度

抢占式调度主要时针对优先级不同的任务,每个任务都有一个优先级,优先级高的任务可以抢占优先级低的任务,只有当优先级高的任务发生阻塞或者被挂起,低优先级的任务才可以运行。

时间片调度

时间片调度主要针对优先级相同的任务,当多个任务的优先级相同时, 任务调度器会在每一次系统时钟节拍到的时候切换任务,也就是说 CPU 轮流运行优先级相同的任务,每个任务运行的时间就是一个系统时钟节拍。

在 FreeRTOS 中的任务存在四种状态,分别为运行态、就绪态、阻塞态和挂起态。在 FreeRTOS 运行时,任务的状态一定是这四种状态中的一种,下面是四种任务状态的介绍。

任务状态

同优先级的任务正在运行,所以需要等待。

运行态(Running):如果一个任务得到 CPU 的使用权,即任务被实际执行时,那么这个任务处于运行态。如果运行 FreeRTOS 的 MCU 只有一个处理器核心,那么在任务时刻,都只能有一个任务处理运行态。

就绪态:如果一个任务已经能够被执行(不处于阻塞态或挂起态),但当前还未被执行(具有相同优先级或更高优先级的任务正持有 CPU 使用权),那么这个任务就处于就绪态。

阻塞态(Blocked):如果一个任务因延时一段时间或等待外部事件发生,那么这个任务就处理阻塞态。例如任务调用了函数 vTaskDelay(),进行一段时间的延时,那么在延时超时之前,这个任务就处理阻塞态。任务也可以处于阻塞态以等待队列、信号量、事件组、通知或信号量等外部事件。通常情况下,处于阻塞态的任务都 有一个阻塞的超时时间,在任务阻塞达到或超过这个超时时间后,即使任务等待的外部事件还没有发生, 任务的阻塞态也会被解除。要注意的是,处于阻塞态的任务是无法被运行的。

挂起态(Suspended):任务一般通过函数 vTaskSuspend()和函数 vTaskResums()进入和退出挂起态与阻塞态一样,处于挂起态的任务也无法被运行。

挂起任务、恢复任务

挂起任务函数原型
vTaskSuspend( TaskHandle_t xTaskToSuspend )

参数

xTaskToSuspend:需要挂起任务的句柄

创建任务时加上句柄

句柄声明

恢复任务函数原型

 void vTaskResume( TaskHandle_t xTaskToResume )

参数

TaskToResumex:需要恢复任务的句柄

任务删除

vTaskDelete()函数用于删除任务。在使用这个函数时,需要提供一个任务句柄作为参数,以便通知内核删除哪个任务。

函数原型
void vTaskDelete( TaskHandle_t xTaskToDelete )

参数:

xTaskToDelete:需要删除任务的句柄

如果写的是NULL,则自杀

空闲任务

当创建的任务大部分时间都处于阻塞状态。当任务处于阻塞状态时,它们无法运行,因此调度器无法选择它们。必须始终至少有一个任务可以进入运行状态(即使在使用 FreeRTOS 的特殊低功耗功能时也是如此,在这种情况下,如果应用程序创建的任务都无法执行,那么执行 FreeRTOS 的微控制器将被置于低功耗模式)。为了确保这种情况,当调用 vTaskStartScheduler()时,调度器会自动创建一个空闲任务。空闲任务除了在一个循环中等待之外几乎不执行其他任何操作,因此,就像第一个示例中的任务一样,它始终能够运行。

空闲任务具有尽可能低的优先级(优先级为 0),以确保它永远不会阻止更高优先级的应用程序任务进入运行状态。然而,这并不妨碍应用程序设计者根据需要创建与空闲任务共享优先级的任务。可以使用 FreeRTOSConfig.h 中的 configIDLE_SHOULD_YIELD 编译时配置常量阻止空闲任务消耗处理时间,可以更有效地分配给具有同样优先级的应用程序任务处理时间。运行在最低优先级确保了当更高优先级的任务进入就绪状态时,空闲任务会立即从运行状态转换出来。

注意:如果一个任务使用 vTaskDelete() API 函数来删除自己,那么必须确保空闲任务不会因处理时间不足而受到影响。这是因为空闲任务负责清理由已删除自身的任务所使用的内核资源。

空闲任务钩子函数用途

可以通过使用空闲钩子(或空闲回调)函数直接在空闲任务中添加应用程序的相关功能。处理一些不紧急的任务。空闲钩子函数是一种函数,它在空闲任务循环的每次迭代中自动由空闲任务调用。空闲任务钩子的常见用途包括:

  • 执行低优先级、后台或连续处理功能,而无需为此目的创建应用程序任务,所带来额外的 RAM开销。
  • 测量空闲处理能力(空闲任务仅在所有更高优先级的应用程序任务没有工作要执行时,空闲任务才会运行;因此,测量分配给空闲任务的处理时间,可以清楚地表明有多少处理时间是空闲的)。
  • 将处理器置于低功耗模式,提供了一种简单且自动的方法,在没有应用程序处理要执行时,节省功耗。

空闲任务钩子函数的实现限制

  1. 空闲任务钩子函数绝对不能阻塞或挂起自己。(以任何方式阻塞空闲任务都可能导致没有任务能够进入运行态!)
  2. 如果一个应用程序任务使用 vTaskDelete() API 函数删除自己,那么必须在合理的时间段内将闲任务钩子返回给调用者。这是因为任务被删除后,空闲任务负责清理内核资源。如果空闲任务永久保持在空闲钩子函数中,则无法进行这种清理。

钩子函数的使用

  • main函数中找到vTaskStartScheduler()并跳转

  • vTaskStartScheduler()内可以找到如图的函数

  • 跳转空闲任务函数找到了vApplicationIdleHook()函数就是钩子函数,但是需要configUSE_IDLE_HOOK==1

  • 右键跳转configUSE_IDLE_HOOK并将configUSE_IDLE_HOOK等于1

  • 编译发现报错,内容为vApplicationIdleHook未定义

  • 接下来我们声明写一个vApplicationIdleHook函数并在里面写自己的任务程序就可以了
TaskHandle_t xTask1ToSuspend;
void vApplicationIdleHook( void )
{while(1){printf("我是钩子,我的优先级为0\n");}
}
void task1( void *pvParameters )
{for(;;){printf("我是任务1,我的优先级高\n");vTaskDelay(10);}
}
void task2( void *pvParameters )
{for(;;){printf("我是任务2,我的优先级低\n");vTaskDelete(xTask1ToSuspend);}
}

使用CUBE配置FreeRTOS编写程序

1、更新安装freertos插件

2.配置FreeRTOS

创建一个新的工程

3.配置基础硬件

4.最后生成工程MDK内编写程序

void StartTask02(void *argument)
{/* USER CODE BEGIN myTask02 *//* Infinite loop */for(;;){HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);osDelay(100);}/* USER CODE END myTask02 */
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

基于SSM的毕业论文管理系统【附源码】

基于SSM的毕业论文管理系统&#xff08;源码L文说明文档&#xff09; 目录 4 系统设计 4.1 系统结构设计 4.2 系统顺序图设计 4.3 系统数据库设计 5 系统的实现 5.1 登录模块的实现 5.2 学生管理模块的实现 5.3 导师管理模块的实现 5.4 课题管理模块的实现 …

擎耀数字车灯CAN/LIN总线网络定向数据采集控制解决方案实施流程

2024年是数字车灯崛起的元年&#xff0c;随着车辆的智能化和网络化程度不断提高&#xff0c;车载网络系统&#xff08;如CAN总线&#xff09;成为连接各个电子控制单元&#xff08;ECU&#xff09;的重要纽带。车灯作为车辆重要的安全组件之一&#xff0c;其工作状态直接影响到…

【C++之STL】摸清 string 的模拟实现(上)

文章目录 1. 为什么要模拟实现&#xff1f;2. 基本框架搭建3. 构造函数3. 1 默认构造/from c_str3. 2 拷贝构造3. 2. 1 深浅拷贝 3. 3 fill3. 4 迭代器区间构造 4. 容量操作4. 1 size()和capacity()和empty()4. 2 clear()4. 3 resize()4. 4 reserve() 1. 为什么要模拟实现&…

视频直播5G CPE解决方案:ZX7981PG/ZX7981PMWIFI6网络覆盖

方案背景 视频直播蓬勃发展的当下&#xff0c;传统直播网络联网方式的局限性越来越明显。目前传统直播的局限性主要集中在以下几个方面&#xff1a; 传统直播间网络架构条件有限&#xff0c;可连接WIFI数量少&#xff0c;多终端同时直播难以维持&#xff1b;目前4G网络带宽有限…

input file结合vue3和vant实现上传图片效果,并显示上传进度百分比%

这里写自定义目录标题 采用的dom结构是input file&#xff0c;label事件绑定&#xff0c;一下为代码传入参数为uploadNum实现效果如图上传中&#xff0c;图片1上传成功&#xff0c;图片2 采用的dom结构是input file&#xff0c;label事件绑定&#xff0c;一下为代码 传入参数为…

SELECT 语句详解

开发准备 注:如果你是从上一节直接进入本节进行学习的,请先删除上一节建立的数据库mysql_shiyan,删除语句为DROP DATABASE mysql_shiyan;。在正式开始本实验内容之前,需要先下载相关数据库表,搭建好一个名为mysql_shiyan 的数据库(有三张表:department,employee,projec…

重力传感器算法概述!

一、核心技术 高精度重力测量技术&#xff1a; 无人机重力传感器的核心技术之一是能够高精度地测量重力加速度数据。这通常依赖于先进的传感器设计和制造工艺&#xff0c;以确保传感器具有高度的灵敏度和稳定性。 例如&#xff0c;中国船舶第七〇七研究所自主研发的低空重力…

炼码LintCode--数据库题库(级别:中等;数量:更新中~)--刷题笔记_03

目录 炼码LintCode--数据库题库&#xff08;级别&#xff1a;中等&#xff1b;数量&#xff1a;更新中~&#xff09;--刷题笔记_033617 更换连续两个人的座位&#xff08;case when&#xff09;题&#xff1a;sql&#xff1a;解释&#xff1a; 3615 数据中位数&#xff08;窗…

【stm入门学习SPI_铁头山羊系列教程】

stm入门学习SPI_铁头山羊教程 1.SPI总线1.电路结构与通信协议2.SPI的特点&#xff1a;3. 极性 相位4. 4中时钟模式5. 比特位的传输模式6.数据宽度 2. SPI引脚IO引脚初始化 1.SPI总线 1.电路结构与通信协议 主机向从机NSS引脚发送低电压&#xff0c;选中该从机。 主机通过向MOS…

RK3568平台开发系列讲解(platform虚拟总线驱动篇)实验:点亮一个LED

🚀返回专栏总目录 文章目录 一、设备树二、平台驱动三、应用沉淀、分享、成长,让自己和他人都能有所收获!😄 📢xxx 程序编写的主要内容为添加 LED 灯的设备树节点、在驱动程序中使用 of 函数获取设备节点中的属性,编写测试应用程序。 • 首先向设备树添加 LED 设备节点…

Spring Boot 与腾讯云 MySQL 监听 Binlog 数据变化,并使用 UI 展示页面效果

引言 在现代的分布式系统和微服务架构中&#xff0c;数据同步和变更监控是保证系统一致性和实时性的核心问题之一。MySQL 数据库的 binlog&#xff08;二进制日志&#xff09;功能能够记录所有对数据库的修改操作&#xff0c;如插入&#xff08;INSERT&#xff09;、更新&…

菜鸟驿站二维码/一维码 取件识别功能

特别注意需要引入 库文 ZXing 可跳转&#xff1a; 记录【WinForm】C#学习使用ZXing.Net生成条码过程_c# zxing-CSDN博客 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Net.…

PlantUML——时序图

PlantUML时序图 背景 时序图&#xff08;Sequence Diagram&#xff09;&#xff0c;又名序列图、循序图&#xff0c;是一种UML交互图&#xff0c;用于描述对象之间发送消息的时间顺序&#xff0c;显示多个对象之间的动态协作。时序图的使用场景非常广泛&#xff0c;几乎各行各…

算法——链表相交(leetcode23)

链表相交这题就是找出两个相交链表相交的节点并返回 如上图假设上方第一个节点是链表A的头结点下方第一个节点是链表B的头结点 解法有以下两种 方法一(移动长链表指针后同步移动两个链表的指针直至相等) 也就是先遍历链表A和链表B的长度接着得到链表A和B长度的差值然后领长链…

STM32单片机锁死

自己画了一块stm32f407板子&#xff0c;外部晶振用了25MHz&#xff0c;烧写了8MHz的程序&#xff0c;第一次烧写成功&#xff0c;第二次开始识别不到芯片&#xff0c;第一次烧写成功由于外部晶振为25Hz&#xff0c;芯片内频率计算器却是按照8MHz写的&#xff0c;所以得出最后的…

Windows文件资源管理器增强工具

引言&#xff1a; 资源管理器在我们使用电脑时是经常用到的&#xff0c;各种文件资源等的分类整理都离不开它。但是Windows Explorer确实不好用&#xff0c;不智能&#xff0c;不符合人体工程学。特别是在一些场合&#xff0c;在打开的一堆文件夹里&#xff0c;想从中找到自己要…

聚类中3个解空间的描述

深度学习中做分类任务时&#xff0c;我们常常根据最后的全连接层得到一组向量A&#xff08;比如&#xff1a;[0.9, 0.7, 0.2]&#xff09;&#xff0c;这组向量经过归一化得到向量B(比如&#xff1a;[0.5&#xff0c; 0.3&#xff0c; 0.2])&#xff0c;再根据B向量采用概率最大…

Empirical analysis of hardware-assisted GPU virtualization

​ 年份&#xff1a;2019 作者&#xff1a;Anshuj Garg 会议&#xff1a;ESCI 出版商&#xff1a;IEEE 摘要 本篇文章对vGPU虚拟化的性能开销、调度算法的影响、同构与异构工作负载的干扰效应&#xff0c;以及PCI直通与vGPU的性能差异进行了研究。结果表明&#xff0c;vGP…

Java面试题2024-Java基础

Java基础 1、 Java语言有哪些特点 1、简单易学、有丰富的类库 2、面向对象&#xff08;Java最重要的特性&#xff0c;让程序耦合度更低&#xff0c;内聚性更高&#xff09; 3、与平台无关性&#xff08;JVM是Java跨平台使用的根本&#xff09; 4、可靠安全 5、支持多线程 2、…

【案例分享】运用 Infragistics Ultimate UI 让工业物联网 IIoT 数据流更易于访问

客户概况 贝克休斯旗下的 Bently Nevada 是状态监测和资产保护领域的全球领导者。该公司拥有 60 多年的专业知识&#xff0c;在全球安装了超过 600 万个传感器和 100,000 个机架监测系统。 如今&#xff0c;Bently Nevada的开发团队正在使用现代 UI 工具包来增强他们的系统&a…