嵌入式实时操作系统笔记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;前…

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

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

【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第二步 卸载系统中…

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…

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

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

DNF手游攻略:角色培养与技能搭配!游戏辅助!

角色培养和技能搭配是《地下城与勇士》中提升战斗力的关键环节。每个职业都有独特的技能和发展路线&#xff0c;合理的属性加点和技能搭配可以最大化角色的潜力&#xff0c;帮助玩家在各种战斗中立于不败之地。接下来&#xff0c;我们将探讨如何有效地培养角色并搭配技能。 角色…

JavaEE之线程(9) _定时器的实现代码

前言 定时器也是软件开发中的一个重要组件. 类似于一个 “闹钟”。 达到一个设定的时间之后&#xff0c;就执行某个指定好的代码&#xff0c;比如&#xff1a; 在受上述场景中&#xff0c;当客户端发出去请求之后&#xff0c; 就要等待响应&#xff0c;如果服务器迟迟没有响应&…

大小字符判断

//函数int my_isalpha(char c)的功能是返回字符种类 //大写字母返回1&#xff0c;小写字母返回-1.其它字符返回0 //void a 调用my_isalpha()&#xff0c;返回大写&#xff0c;输出*&#xff1b;返回小写&#xff0c;输出#&#xff1b;其它&#xff0c;输出&#xff1f; #inclu…

【Linux】Linux的安装

文章目录 一、Linux环境的安装虚拟机 镜像文件云服务器&#xff08;可能需要花钱&#xff09; 未完待续 一、Linux环境的安装 我们往后的学习用的Linux版本为——CentOs 7 &#xff0c;使用 Ubuntu 也可以 。这里提供几个安装方法&#xff1a; 电脑安装双系统&#xff08;不…

深入解析力扣162题:寻找峰值(线性扫描与二分查找详解)

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

virtual box ubuntu20 全屏展示

virtual box 虚拟机 ubuntu20 系统 全屏展示 ubuntu20.04 视图-自动调整窗口大小 视图-自动调整显示尺寸 系统黑屏解决 ##设备-安装增强功能 ##进入终端 ##终端打不开&#xff0c;解决方案-传送门ubuntu Open in Terminal打不开终端解决方案-CSDN博客 ##点击cd盘按钮进入文…

【RabbitMQ】使用SpringAMQP的Publish/Subscribe(发布/订阅)

Publish/Subscribe **发布(Publish)、订阅(Subscribe)&#xff1a;**允许将同一个消息发送给多个消费者 **注意&#xff1a;**exchange负责消息路由&#xff0c;而不是存储&#xff0c;路由失败则消息丢失 常见的**X(exchange–交换机)***类型&#xff1a; Fanout 广播Direc…

【设计模式】JAVA Design Patterns——Callback(回调模式)

&#x1f50d;目的 回调是一部分被当为参数来传递给其他代码的可执行代码&#xff0c;接收方的代码可以在一些方便的时候来调用它。 &#x1f50d;解释 真实世界例子 我们需要被通知当执行的任务结束时。我们为调用者传递一个回调方法然后等它调用通知我们。 通俗描述 回调是一…

试用百川智能的百小应-说的太多,做的太少

“百小应”的品牌标识&#xff08;logo&#xff09;上有一缕黄色&#xff0c;这是王小川特意设计的。他说&#xff0c;其他AI应用都在强调科技感&#xff0c;更愿意用蓝色或者冷色调。但他觉得这一代科技与上个时代不一样&#xff0c;现代科技应该像人&#xff0c;所以选择使用…