嵌入式实时操作系统笔记2:UCOS基础知识_UC/OS-III移植(STM32F4)_编写简单的UC/OS-III任务例程(失败.....)

 今日学习嵌入式实时操作系统RTOS:UC/OS-III实时操作系统

本文只是个人学习笔记备忘用,附图、描述等 部分都是对网上资料的整合......

文章主要研究如何将UC/OS-III 移植到 STM32 F407VET6上,提供测试工程下载

 (2024.5.21 文章未写完,测试有问题,以后再说)

 (2024.5.22 系统移植失败,测试有问题,以后再说)

 附言:网络上的资料真是参差不齐,整整浪费我一天时间......

目录

UCOS基础知识:

任务的五种状态:

 任务五种状态转换图:

UCOS-III的三大列表:

UCOS-III系统配置文件说明:

UC/OS-III移植(STM32F4):

添加 UC/OS-III 源码部分:

修改system_stm32f4xx.s启动文件代码:

修改/确定 系统时钟(SysTick)内核:

修改CONFIG/app_cfg.h:

修改CONFIG/includes.h :

尝试编写简单的 UC/OS-III 任务例程:

先引用头文件:

定义任务栈大小/优先级:

定义任务控制块TCB:

定义任务栈:

定义任务主体函数:

创建任务TASK1-2-3:

CPU_SR_ALLOC();  

OS_CRITICAL_ENTER();  

OS_CRITICAL_EXIT();

启动UCOS III 系统函数:

主函数调用情况展示:

测试效果展示:

整体测试工程下载:

网上学习资料网址贴出:


UCOS基础知识:

任务的五种状态:

 任务五种状态转换图:

1、被创建的任务,初始状态均为就绪态
2、被删除的任务,会转为休眠态
3、仅就绪态和中断态可转变成运行态
4、其他状态的任务想运行,必须先转变成就绪

UCOS-III的三大列表:

UCOS-川主要有三大类列表用来跟踪任务状态:


就绪列表  准备运行的任务将放在就绪列表:OSRdyList[x],其中x代表任务优先级数值
Tick列表   正在等待延时超时或挂起的对象超时的任务,将放在OSTickList
挂起列表   当任务等待信号量、事件时,任务将放置在挂起列表PendList

UCOS-III系统配置文件说明:

以下就是我们接下来需要移植的 部分文件,他们的作用大致各自如下:

UC/OS-III移植(STM32F4):

本次尝试移植UC/OS-III 于立创梁山派天空星开发板上,芯片型号是STM32F407VET6

其中UC/OS-III 的源码可以在整体工程下载中的压缩包内找到

注意:这里的源码是被我阉割过的,削除了官方文件中不必要的文件与目录

其次就是网络上那些所谓提供UC/OS源码或者教程的,如果没有移植成功的工程供下载的案例,基本都是垃圾!浪费时间!不是缺少文件,就是解释不详细,缺步漏步!

本人也是在艰难的学习中掉进太多移植源码方面的坑里了.........

添加 UC/OS-III 源码部分

在工程中新建几个分组:

uC-OS3/CPU

uC-OS3/LIB

uC-OS3/PORT

uC-OS3/SOURCE

uC-OS3/CONFIG
 

点击uC-OS3/CPU–>Add Files

UC-OSIII/CPU添加以下文件,如果只查找到一个,请将文件类型(I)选为 ALL files(''.'')

点击uC-OS3/CPU–>Add Files

UCOSIII\bsp添加以下文件,如果只查找到一个,请将文件类型(I)选为 ALL files(''.'')

点击uC-OS3/LIB–>Add Files

UCOSIII\uC-LIB添加以下所有文件,如果只查找到一个,请将文件类型(I)选为 ALL files(''.'')

点击uC-OS3/PORT–>Add Files

UCOSIII\uCOS-III\Ports添加以下所有文件,如果只查找到一个,请将文件类型(I)选为 ALL files(''.'')

点击uC-OS3/SOURCE–>Add Files

UCOSIII\uCOS-III\Source添加以下所有文件,如果只查找到一个,请将文件类型(I)选为 ALL files(''.'')

uC-OS3/CONFIG添加文件:

UCOSIII\config添加以下所有文件,如果只查找到一个,请将文件类型(I)选为 ALL files(''.'')

最后别忘记在魔棒中添加各个文件路径:

补:补充添加一条bsp的路径,之前忘记添加了,导致报错......

添加结束,编译看看有无报错缺漏:

这里也是完美无报错的典范了哈哈哈......

修改system_stm32f4xx.s启动文件代码:

打开工程自带的 system_stm32f4xx.s启动文件(这是启动文件,不是UC/OS源码!)

我们需要对其进行一些修改:

1

第80行框出代码修改:

                DCD     OS_CPU_PendSVHandler             ; PendSV HandlerDCD     OS_CPU_SysTickHandler            ; SysTick Handler

第220行框出代码修改:

OS_CPU_PendSVHandler\PROCEXPORT  OS_CPU_PendSVHandler       [WEAK]B       .ENDP
OS_CPU_SysTickHandler\PROCEXPORT  OS_CPU_SysTickHandler      [WEAK]B       .ENDP

最后编译检查无问题:

修改/确定 系统时钟(SysTick)内核:

这里我还特意出去学习了一下系统内核时钟的初始化等知识:并附文:

STM32F407VET6 学习笔记3:内核定时器SystemTick(SysTick)初始化中断-CSDN博客

/*** This function will initial stm32 board.*/
void board_init(void)
{/* NVIC Configuration */
#define NVIC_VTOR_MASK              0x3FFFFF80
#ifdef  VECT_TAB_RAM/* Set the Vector Table base location at 0x10000000 */SCB->VTOR  = (0x10000000 & NVIC_VTOR_MASK);
#else  /* VECT_TAB_FLASH  *//* Set the Vector Table base location at 0x08000000 */SCB->VTOR  = (0x08000000 & NVIC_VTOR_MASK);
#endifSysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); //Systick 时钟源频率168M// 计算SysTick重装载值(SystemCoreClock为168MHz,希望SysTick中断频率为1ms(1000 Hz))//SysTick_LOAD = (SystemCoreClock / TickRate) - 1uint32_t reload = SystemCoreClock / 1000 - 1; // 1ms中断频率  SysTick->LOAD = reload;  // 清除SysTick当前值并启动SysTick,同时使能中断SysTick->VAL  = 0; // 清空当前值  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;  /* 设置NVIC优先级分组 */  // 4位抢占优先级和0位子优先级  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);   /* 设置SysTick中断的优先级 */  // 设置SysTick的抢占优先级为3(最低),没有子优先级(因为分组4没有子优先级位)  NVIC_SetPriority(SysTick_IRQn, 3); // 注意:优先级值根据分组设置可能有所不同 }
// 声明SysTick中断处理函数  
void SysTick_Handler(void)
{OSIntEnter();		      //进入中断OSTimeTick();       //调用ucos的时钟服务程序               OSIntExit();        //触发任务切换软中断
}

修改CONFIG/app_cfg.h:

#define APP_CFG_SERIAL_EN        DEF_ENABLED ------>

#define APP_CFG_SERIAL_EN        DEF_DISABLED

改后如下:

#define APP_TRACE BSP_Ser_Printf --------> #define APP_TRACE (void)

修改CONFIG/includes.h :

尝试编写简单的 UC/OS-III 任务例程:

先引用头文件:

/*****************UC/OS头文件***************/
#include "os.h"
#include "os_cpu_bsp.h"
#include <app_cfg.h>
#include <cpu_core.h>
#include <os_app_hooks.h>
#include <cpu.h>
/* USER CODE END Includes */

定义任务栈大小/优先级:


//任务栈大小定义
#define  START_STK_SIZE                     128
#define  TASK1_STK_SIZE                     128
#define  TASK2_STK_SIZE                     128
#define  TASK3_STK_SIZE                     128
//任务优先级定义
#define  APP_TASK_START_PRIO                     4
#define  APP_TASK_1_PRIO                         5
#define  APP_TASK_2_PRIO                         6
#define  APP_TASK_3_PRIO                         7

定义任务控制块TCB:

//创建任务控制块
static OS_TCB Start_Task_TCB;
static OS_TCB Task1_TCB;
static OS_TCB Task2_TCB;
static OS_TCB Task3_TCB;

定义任务栈:

//任务堆栈	
CPU_STK START_TASK_STK[START_STK_SIZE];
CPU_STK TASK1_TASK_STK[TASK1_STK_SIZE];
CPU_STK TASK2_TASK_STK[TASK2_STK_SIZE];
CPU_STK TASK3_TASK_STK[TASK3_STK_SIZE];

定义任务主体函数:

这个放置在主函数下面吧就:

任务里面一定要有阻塞延时,如果这个任务的优先级最高且没有阻塞延时,那么操作系统就只会执行这一个任务,其他的任务就得不到执行。

注意:这里的    OSTimeDly ( 2000, OS_OPT_TIME_DLY, & err ); 对应的延时 不仅与 内传的参数 有关 还与 内核定时器SystemTick 有关:

创建任务TASK1-2-3:

各个TASK的任务如下描述:

//TASK_1 报告自己执行次数(2s),并在执行8次后删除 TASK_2

//TASK_2 串口报告自己执行的次数 (4s)

//这里的 TASK_3 会每隔 17S 恢复TASK_2 (全新的开始)
/*
    创建一个全新的任务实例,而不是简单地“恢复”一个已经被删除的任务。
  这意味着新的任务实例将拥有自己独立的堆栈(stack)和其他资源,而原来的任务实例(如果已经被删除)的资源将被释放
*/

//TASK_1 报告自己执行次数(2s),并在执行8次后删除 TASK_2
void TASK_1(void)
{OS_ERR  err;			// 定义一个“错误” 变量用来存放一些错误的类型int TASK1_num=0;  //记录任务TASK_1执行次数//在某些嵌入式系统中,进入和退出关键区域可能需要禁用中断,以防止在关键代码执行过程中被中断打断。	CPU_SR_ALLOC();   //为保存和恢复CPU的状态寄存器(Status Register)或中断状态做准备工作。OS_CRITICAL_ENTER();/* 此处添加不希望被打断的硬件初始化代码等......*/OS_CRITICAL_EXIT();while(1){TASK1_num++;	//任务TASK_1执行次数加1if(TASK1_num%8==0){OSTaskDel((OS_TCB*)&Task2_TCB,&err);	        //任务1每执行8次后(即16s时) 删除掉任务2printf("TASK_1 has Deleted the TASK_2 !\r\n");//打印报告	任务1 删除了 任务2}UsartPrintf(USART1,"TASK_1 has Carred out %d times! \r\n",TASK1_num);	//打印测试字符串(并报告TASK_1执行次数)OSTimeDly ( 2000, OS_OPT_TIME_DLY, & err ); //使当前任务延迟指定的时间(2s):  (让当前任务放弃CPU一段时间,CPU让给其余任务)}
}//TASK_2 串口报告自己执行的次数 (4s)
void TASK_2(void)
{OS_ERR  err;			// 定义一个“错误” 变量用来存放一些错误的类型int TASK2_num=0;  //记录任务TASK_2执行次数while(1){UsartPrintf(USART1,"TASK_2 has Carred out %d times! \r\n",TASK2_num);	//打印测试字符串(并报告TASK_2执行次数)OSTimeDly ( 4000, OS_OPT_TIME_DLY, & err );//使当前任务延迟指定的时间(4S):  (让当前任务放弃CPU一段时间,CPU让给其余任务) }
}//这里的 TASK_3 会每隔 17S 恢复TASK_2 (全新的开始)
/*创建一个全新的任务实例,而不是简单地“恢复”一个已经被删除的任务。这意味着新的任务实例将拥有自己独立的堆栈(stack)和其他资源,而原来的任务实例(如果已经被删除)的资源将被释放
*/
void TASK_3(void)
{OS_ERR  err;			// 定义一个“错误” 变量用来存放一些错误的类型int TASK3_num=0;  //记录任务TASK_3执行次数CPU_SR_ALLOC();OS_CRITICAL_ENTER();	//进入临界区			 //重新创建TASK2任务OSTaskCreate((OS_TCB 	* )&Task2_TCB,		(CPU_CHAR	* )"TASK_2", 		(OS_TASK_PTR )TASK_2, 			(void		* )0,					(OS_PRIO	  )TASK2_PRIO,     	(CPU_STK   * )&TASK2_TASK_STK[0],	(CPU_STK_SIZE)TASK2_STK_SIZE/10,	(CPU_STK_SIZE)TASK2_STK_SIZE,		(OS_MSG_QTY  )0,					(OS_TICK	  )0,					(void   	* )0,				(OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR 	* )&err);	OS_CRITICAL_EXIT();	//退出临界区	 		while(1){UsartPrintf(USART1,"TASK_3 has Resume the TASK_2 %d times! \r\n",TASK3_num);	//打印测试字符串(并报告TASK_3执行次数)							 OSTimeDly ( 17000, OS_OPT_TIME_DLY, & err );//使当前任务延迟指定的时间(17S):  (让当前任务放弃CPU一段时间,CPU让给其余任务) }
}//开始任务任务函数
void start_task(void *p_arg)
{OS_ERR err;CPU_SR_ALLOC();p_arg = p_arg;CPU_Init();
#if OS_CFG_STAT_TASK_EN > 0uOSStatTaskCPUUsageInit(&err);  	//统计任务                
#endif#ifdef CPU_CFG_INT_DIS_MEAS_EN		//如果使能了测量中断关闭时间CPU_IntDisMeasMaxCurReset();	
#endif#if	OS_CFG_SCHED_ROUND_ROBIN_EN  //当使用时间片轮转的时候//使能时间片轮转调度功能,时间片长度为1个系统时钟节拍,既1*5=5msOSSchedRoundRobinCfg(DEF_ENABLED,1,&err);  
#endif	OS_CRITICAL_ENTER();	//进入临界区//创建TASK1任务OSTaskCreate((OS_TCB 	* )&Task1_TCB,				          //任务控制块(CPU_CHAR	* )"TASK_1", 	 		                  //任务名字	(OS_TASK_PTR )TASK_1, 			            //任务函数(void		* )0,					                //传递给任务函数的参数					(OS_PRIO	  )TASK1_PRIO,     (CPU_STK   * )&TASK1_TASK_STK[0],	(CPU_STK_SIZE)TASK1_STK_SIZE/10,	(CPU_STK_SIZE)TASK1_STK_SIZE,		(OS_MSG_QTY  )0,					(OS_TICK	  )0,					(void   	* )0,					(OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR,(OS_ERR 	* )&err);				//创建TASK2任务OSTaskCreate((OS_TCB 	* )&Task2_TCB,		(CPU_CHAR	* )"TASK_2", 		(OS_TASK_PTR )TASK_2, 			(void		* )0,					(OS_PRIO	  )TASK2_PRIO,     	(CPU_STK   * )&TASK2_TASK_STK[0],	(CPU_STK_SIZE)TASK2_STK_SIZE/10,	(CPU_STK_SIZE)TASK2_STK_SIZE,		(OS_MSG_QTY  )0,					(OS_TICK	  )0,					(void   	* )0,				(OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR 	* )&err);		//创建TASK3任务OSTaskCreate((OS_TCB 	* )&Task3_TCB,		(CPU_CHAR	* )"TASK_3", 		(OS_TASK_PTR )TASK_3, 			(void		* )0,					(OS_PRIO	  )TASK3_PRIO,     	(CPU_STK   * )&TASK3_TASK_STK[0],	(CPU_STK_SIZE)TASK3_STK_SIZE/10,	(CPU_STK_SIZE)TASK3_STK_SIZE,		(OS_MSG_QTY  )0,					(OS_TICK	  )0,					(void   	* )0,				(OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, (OS_ERR 	* )&err);	OS_CRITICAL_EXIT();	//退出临界区OSTaskDel((OS_TCB*)0,&err);	//删除start_task任务自身
}

CPU_SR_ALLOC();  

OS_CRITICAL_ENTER();  

OS_CRITICAL_EXIT();

	//在某些嵌入式系统中,进入和退出关键区域可能需要禁用中断,以防止在关键代码执行过程中被中断打断。	CPU_SR_ALLOC();   //为保存和恢复CPU的状态寄存器(Status Register)或中断状态做准备工作。/*OS_CRITICAL_ENTER();这个函数通常用于进入一个关键区域。在进入关键区域之前,它可能会禁用中断(如果之前通过CPU_SR_ALLOC();已经做了相关准备),或者通过其他机制(如锁)来确保没有其他线程或中断可以访问当前线程正在使用的共享资源。通过禁用中断或获得锁,OS_CRITICAL_ENTER();确保了代码的关键部分在执行时不会被其他任务或中断打断,从而保证了数据的一致性和操作的原子性。*/OS_CRITICAL_ENTER();/*OS_CRITICAL_EXIT();这个函数用于退出之前由OS_CRITICAL_ENTER();进入的关键区域。在退出关键区域时,它可能会重新启用之前被禁用的中断,或者释放之前获得的锁。这样做允许其他任务或中断再次访问之前被保护的共享资源*/OS_CRITICAL_EXIT();

启动UCOS III 系统函数:

//启动UCOS III 系统 !
void UCOS_III_init(void)
{OS_ERR err;CPU_SR_ALLOC();OSInit(&err);		      //初始化UCOSIIIOS_CRITICAL_ENTER();	//进入临界区			 //创建开始任务OSTaskCreate((OS_TCB 	* )&Start_Task_TCB,		      //任务控制块(CPU_CHAR	* )"start_task", 		            //任务名字(OS_TASK_PTR )start_task, 			    //任务函数(void		* )0,					            //传递给任务函数的参数(OS_PRIO	  )START_TASK_PRIO,       //任务优先级(CPU_STK   * )&START_TASK_STK[0],	//任务堆栈基地址(CPU_STK_SIZE)START_STK_SIZE/10,	  //任务堆栈深度限位(CPU_STK_SIZE)START_STK_SIZE,		  //任务堆栈大小(OS_MSG_QTY  )0,				//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息(OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,(void   	* )0,					//用户补充的存储区(OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项(OS_ERR 	* )&err);			//存放该函数错误时的返回值OS_CRITICAL_EXIT();	//退出临界区	 OSStart(&err);      //开启UCOSIII	 
}

主函数调用情况展示:

网上学习资料网址贴出:

第3讲 UCOS基础知识_哔哩哔哩_bilibili

uCosII移植STM32F407教程_stm32f407 ucos-CSDN博客

基于stm32cubemx移植uC/OS-III操作系统_cubemx ucos-CSDN博客

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

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

相关文章

Java web应用性能分析之【高并发之缓存-多级缓存】

说到缓存&#xff0c;作为java开发第一时间想到的是不是上图所示的Redis&#xff0c;又或者是Guava Cache、Caffeine、EhCache这些&#xff1b;Redis作为分布式缓存、其他的可以作为本地缓存。但是作为一名资深开发人员&#xff0c;着眼的层面应该再提升一个级别&#xff0c;从…

Prometheus监控平台配置--监控mysql

上一篇中讲述了怎么安装Prometheus&#xff0c;然后对服务器集群资源信息进行监控并通过grafana展示监控信息&#xff0c;在这一篇中我们只讲和mysql相关的监控&#xff0c;关于prometheus的监控原理以及安装可以看下上一篇。 1.上传 通过rz命令将安装包上传到任意目录&#xf…

翻译AnyDoor: Zero-shot Object-level Image Customization

摘要 本研究介绍了AnyDoor&#xff0c;这是一款基于扩散模型的图像生成器&#xff0c;能够在用户指定的位置&#xff0c;以期望的形状将目标对象传送到新场景中。与为每个对象调整参数不同&#xff0c;我们的模型仅需训练一次&#xff0c;就能在推理阶段轻松地泛化到多样化的对…

SpringBoot——整合Redis

目录 Redis 创建Commodity表 启动MySQL和Redis 新建一个SpringBoot项目 pom.xml application.properties Commodity实体类 ComMapper接口 ComService业务层接口 ComServiceImpl业务接口的实现类 ComController控制器 RedisConfig配置类 SpringbootRdisApplication启…

在Visual Studio Code和Visual Studio 2022下配置Clang-Format,格式化成Google C++ Style

项目开发要求好的编写代码格式规范&#xff0c;常用的是根据Google C Style Guide 网上查了很多博文&#xff0c;都不太一样有的也跑不起来&#xff0c;通过尝试之后&#xff0c;自己可算折腾好了&#xff0c;整理一下过程 背景&#xff1a; 编译器主要有三部分&#xff1a;前…

Baidu地图SDK接入后的点击事件实现。

在很多APP中&#xff0c;我们接入了百度地图&#xff0c;而这个百度地图只是拥有提示、展示的作用&#xff0c;并不希望它具有操作功能。 比如&#xff0c;在外卖APP中&#xff0c;粗略地展示一下地理位置&#xff0c;点击地图后&#xff0c;直接跳转对应的导航。 于是这样写…

Github 2024-05-25 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-05-25统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目3TypeScript项目3非开发语言项目1HTML项目1Rust项目1Go项目1Jupyter Notebook项目1Java项目1Angular文档:交付Web应用程序的自信之选…

【Kotlin】使用`when`表达式来实现类似于Java中的`switch`语句的功能

val 常量 val x 2 when (x) {1 -> println("x is 1")2 -> println("x is 2")else -> println("x is neither 1 nor 2") }在这个示例中&#xff0c;when表达式会根据x的值执行相应的代码块。如果x的值是1&#xff0c;那么会执行第一个…

C++第三方库 【HTTP/HTTPS】— httplib库

目录 认识httplib库 安装httplib库 httplib的使用 httplib请求类 httplib响应类 Server类 Client类 httplib库搭建简单服务器&客户端 认识httplib库 httplib库&#xff0c;是一个C11单头文件的&#xff0c;轻量级的跨平台HTTP/HTTPS库&#xff0c;可以用来创建简单的…

全面透视AI Agents:概念、功能、类型、原理、优点、示例和趋势

AI Agents 技术正在引领商业领域的革命性变革。本文将为您提供一个全面的视角&#xff0c;深入探讨 AI Agents 的工作原理、功能特性以及其多样化的类型&#xff0c;包括反应式 Agents、目标驱动 Agents、效用驱动 Agents 和学习型 Agents。通过深入了解 AI Agents 的运作机制&…

使用curl发送http请求

curl发送post请求 可以通过-X指定请求类型&#xff0c;-d传递数据 curl -X POST -d "param1value1&param2value2" http://example.com/resource发送JSON数据&#xff0c;可以使用-H来指定Content-Type&#xff0c;并使用-d传递JSON字符串 curl -X POST -H &qu…

一些c++容器的基本操作

vector 向量&#xff08;Vector&#xff09;是STL中最常用的容器之一&#xff0c;它提供了动态数组的功能&#xff0c;支持随机访问和动态调整大小。下面是向量的一些基本操作&#xff1a; 创建向量&#xff1a; #include <vector> std::vector<int> vec; // …

【Text2SQL】WikiSQL 数据集与 Seq2SQL 模型

论文&#xff1a;Seq2SQL: Generating Structured Queries from Natural Language using Reinforcement Learning ⭐⭐⭐⭐⭐ ICLR 2018 Dataset: github.com/salesforce/WikiSQL Code&#xff1a;Seq2SQL 模型实现 一、论文速读 本文提出了 Text2SQL 方向的一个经典数据集 —…

Linux--10---安装JDK、MySQL

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 安装JDK[Linux命令--03----JDK .Nginx. 数据库](https://blog.csdn.net/weixin_48052161/article/details/108997148) 第一步 查询系统中自带的JDK第二步 卸载系统中…

刀片式服务器是什么?

什么是刀片式服务器&#xff1f; 刀片式服务器是服务器的一种&#xff0c;能够在标准高度的机架式机箱中插装多个卡式的服务器单元&#xff0c;是专门为特殊应用行业和高密度计算环境专门设计的&#xff0c;主要的结构是一大型主体机箱&#xff0c;内部可以插入许多“刀片”。 …

Unity Physics入门

概述 在unity中物理属性是非常重要的&#xff0c;它可以模拟真实物理的效果在unity中&#xff0c;其中的组件是非常多的&#xff0c;让我们来学习一下这部分的内容吧。 Unity组件入门篇总目录----------点击导航 Character Controller(角色控制) 说明&#xff1a;组件是Unity提…

华为编程题目(实时更新)

1.大小端整数 计算机中对整型数据的表示有两种方式&#xff1a;大端序和小端序&#xff0c;大端序的高位字节在低地址&#xff0c;小端序的高位字节在高地址。例如&#xff1a;对数字 65538&#xff0c;其4字节表示的大端序内容为00 01 00 02&#xff0c;小端序内容为02 00 01…

Java数据结构与算法(平衡二叉树)

前言 平衡二叉树是为了提高二叉树的查询速度&#xff0c;通过满足特定的条件来保持其平衡性。平衡二叉树具有以下特点&#xff1a; 左子树和右子树的高度差不会大于1&#xff0c;这是为了确保树的高度不会过大&#xff0c;从而减少查询时的磁盘I/O开销&#xff0c;提高查询速…

【开源】史上最全的JAVA面试题总结

史上最全的JAVA面试题总结 为什么要做这件事情前言JAVA基础开发框架springSpringMVCmybatisdubbospringbootspringcloudnacos 数据库mysqloracle 缓存redismongodbElasticSearch 消息队列rabbitmqrocketmqkafka 监控prometheusgraylogzabbix 工具篇tcpdumpgitjenkins 容器docke…

【案例分享】医疗布草数字化管理系统:聚通宝赋能仟溪信息科技

内容概要 本文介绍了北京聚通宝科技有限公司与河南仟溪信息科技有限公司合作开发的医疗布草数字化管理系统。该系统利用物联网技术实现了医疗布草生产过程的实时监控和数据分析&#xff0c;解决了医疗布草洗涤厂面临的诸多挑战&#xff0c;包括人工记录、生产低效率和缺乏实时…