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.mzph.cn/news/887157.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hello-Go

Hello-Go 环境变量 GOPATH 和 GOROOT &#xff1a;不同于其他语言&#xff0c;go中没有项目的说法&#xff0c;只有包&#xff0c;其中有两个重要的路径&#xff0c;GOROOT 和 GOPATH Go开发相关的环境变量如下&#xff1a; GOROOT&#xff1a;GOROOT就是Go的安装目录&…

pytorch官方FasterRCNN代码详解

本博文转自捋一捋pytorch官方FasterRCNN代码 - 知乎 (zhihu.com)&#xff0c;增加了其中代码的更详细的解读&#xff0c;以帮助自己理解该代码。 代码理解的参考Faster-RCNN全面解读(手把手带你分析代码实现)---前向传播部分_手把手faster rcnn-CSDN博客 1. 代码结构 作为 to…

全志T113双核异构处理器的使用基于Tina Linux5.0——RTOS系统定制开发

8、RTOS系统定制开发 此处以在rtos/components/aw目录下创建一个简单的软件包为例&#xff0c;帮助客户了解RTOS环境&#xff0c;为RTOS系统定制开发提供基础。 RTOS环境下的软件包主要由三部分组成&#xff0c;源文件&#xff0c;Makefile&#xff0c;Kconfig&#xff0c;如下…

springboot实战(13)(@PatchMapping、@RequestParam、@URL、ThreadLocal线程局部变量)

目录 一、PATCH请求方式。 二、实现用户更新头像功能。 三、注解RequestParam。 四、注解URL。&#xff08;对传来的参数是否是合法地址进行校验&#xff09; 一、PATCH请求方式。 patch中文翻译&#xff1a;局部、小块。PATCH 请求主要用于对已存在的资源进行局部修改&#xf…

nvm安装node遇到的若干问题(vscode找不到npm文件、环境变量配置混乱、npm安装包到D盘)

问题一&#xff1a;安装完nvm后需要做哪些环境变量的配置&#xff1f; 1.打开nvm文件夹下的setting文件&#xff0c;设置nvm路径和安装node路径&#xff0c;并添加镜像。 root: D:\software\nvm-node\nvm path: D:\software\nvm-node\nodejs node_mirror: https://npmmirror.c…

面向FWA市场!移远通信高性能5G-A模组RG650V-NA通过北美两大重要运营商认证

近日&#xff0c;全球领先的物联网整体解决方案供应商移远通信宣布&#xff0c;其旗下符合3GPP R17标准的新一代5G-A模组RG650V-NA成功通过了北美两家重要运营商认证。凭借高速度、大容量、低延迟、高可靠等优势&#xff0c;该模组可满足CPE、家庭/企业网关、移动热点、高清视频…

2024年11月21日Github流行趋势

项目名称&#xff1a;twenty 项目维护者&#xff1a;charlesBochet, lucasbordeau, Weiko, FelixMalfait, bosiraphael项目介绍&#xff1a;正在构建一个由社区支持的现代化Salesforce替代品。项目star数&#xff1a;21,798项目fork数&#xff1a;2,347 项目名称&#xff1a;p…

AWTK 最新动态:支持鸿蒙系统(HarmonyOS Next)

HarmonyOS是全球第三大移动操作系统&#xff0c;有巨大的市场潜力&#xff0c;在国产替代的背景下&#xff0c;机会多多&#xff0c;AWTK支持HarmonyOS&#xff0c;让AWTK开发者也能享受HarmonyOS生态的红利。 AWTK全称为Toolkit AnyWhere&#xff0c;是ZLG倾心打造的一套基于C…

docker 配置同宿主机共同网段的IP 同时通过通网段的另一个电脑实现远程连接docker

docker配置网络 #宿主机执行命令 ifconfig 查询对应的主机ip 子网掩码 网关地址 #[网卡名称]&#xff1a;inet[主机IP] netmask[子网掩码] broadcast[网关地址]这里需要重点关注&#xff1a;eno1[网卡名称]以及【192.168.31.225】网关地址 在宿主机执行docker命令创建一个虚拟…

使用 Elastic AI Assistant for Search 和 Azure OpenAI 实现从 0 到 60 的转变

作者&#xff1a;来自 Elastic Greg Crist Elasticsearch 推出了一项新功能&#xff1a;Elastic AI Assistant for Search。你可以将其视为 Elasticsearch 和 Kibana 开发人员的内置指南&#xff0c;旨在回答问题、引导你了解功能并让你的生活更轻松。在 Microsoft AI Services…

React (三)

文章目录 项目地址十二、性能优化12.1 使用useMemo避免不必要的计算12.2 使用memo缓存组件,防止过度渲染12.3 useCallBack缓存函数12.4 useCallBack里访问之前的状态(没懂)十三、Styled-Components13.1 安装13.2给普通html元素添加样式13.3 继承和覆盖样式13.4 给react组件添…

Etcd 框架

基本了解 客户端、长连接与租约的关系 客户端对象 etcd的客户端对象是用户与etcd服务进行交互的主要接口&#xff0c;主要功能就是存储、通知和事务等功能访问 键值存储&#xff1a;客户端通过put 和 get操作存储数据&#xff1b;数据存储在etcd的层级化键值数据库中监听器&a…

IDEA2023 创建SpringBoot项目(一)

一、Spring Boot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。 二、快速开发 1.打开IDEA选择 File->New->Project 2、…

教育数字化转型新时代:探索智慧学习空间的无限可能

在信息技术的浪潮推动下&#xff0c;教育行业正迎来一场前所未有的变革。这场变革的核心在于教育数字化转型&#xff0c;它要求我们重新审视和构建传统的学习模式&#xff0c;以适应快速变化的社会需求。在这个过程中&#xff0c;智慧学习空间作为数字化转型的重要成果&#xf…

LSTM原理解读与实战

在RNN详解及其实战中&#xff0c;简单讨论了为什么需要RNN这类模型、RNN的具体思路、RNN的简单实现等问题。同时&#xff0c;在文章结尾部分我们提到了RNN存在的梯度消失问题&#xff0c;及之后的一个解决方案&#xff1a;LSTM。因此&#xff0c;本篇文章主要结构如下&#xff…

【成品文章+四小问代码更新】2024亚太杯国际赛B题基于有限差分格式的空调形状优化模型

这里仅展示部分内容&#xff0c;完整内容获取在文末&#xff01; 基于有限差分格式的空调形状优化模型 摘 要 随着科技进步&#xff0c;多功能环境调节设备成为市场趋势&#xff0c;集成了空调、加湿器和空气 净化器功能的三合一设备能提供更舒适健康的室内环境。我们需要分析…

中国省级新质生产力发展指数数据(任宇新版本)2010-2023年

一、测算方式&#xff1a;参考C刊《财经理论与实践》任宇新&#xff08;2024&#xff09;老师的研究&#xff0c;新质生产力以劳动者劳动资料劳动对象及其优化组合的质变为 基本内涵&#xff0c;借 鉴 王 珏 和 王 荣 基 的 做 法构建新质生产力发展水平评价指标体系如下所示&a…

简单理解下基于 Redisson 库的分布式锁机制

目录 简单理解下基于 Redisson 库的分布式锁机制代码流程&#xff1a;方法的调用&#xff1a;具体锁的实现&#xff1a;riderBalance 方法&#xff1a;tryLock 方法&#xff08;重载&#xff09;&#xff1a;tryLock 方法&#xff08;核心实现&#xff09;&#xff1a; 简单理解…

Diving into the STM32 HAL-----DAC笔记

根据所使用的系列和封装&#xff0c;STM32微控制器通常只提供一个具有一个或两个专用输出的DAC&#xff0c;除了STM32F3系列中的少数零件编号实现两个DAC&#xff0c;第一个具有两个输出&#xff0c;另一个只有一个输出。STM32G4 系列的一些较新的 MCU 甚至提供多达 5 个独立的…

【数据分析】认清、明确

1、什么是数据分析。 - 通过对大量的数据进行科学的分析。 - 得出结论&#xff0c;提出建议&#xff0c;辅助公司企业的决策。2、数据分析分为几步。 - 1.明确目的! - 2.收集数据!自己的数据! 自动化采集的数据! - 3.数据处理! - 4.数据分析!数据分析(业务)数据挖掘(代码算法…