freeRTOS使用

创建第一个FreeRTOS程序

1、官网源码下载

(1)进入FreeRTOS官网FreeRTOS professional services for application and RTOS development and consulting. FreeRTOS is an Open Source Code RTOS

 (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也删掉)

  1. 4、去掉无关代码

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

(2)编译

5、删除未定义报错内容

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

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

  1. 验证

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

  1. 配置串口

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

初始化删除多余的东西,只保留串口一的配置(这里的函数就是个串口的初始化,有效程序只有串口配置和GPIO配置,按照我下面写的程序弄就可以了。写完记得再main里调用,参数可以不填写。。或者删掉重新写个这个函数也可以)

xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
		xComPortHandle xReturn;
		USART_InitTypeDef USART_InitStructure;
		GPIO_InitTypeDef GPIO_InitStructure;/* Enable USART1 clock */RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE );/* Configure USART1 Rx (PA10) as input floating */
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init( GPIOA, &GPIO_InitStructure );/* Configure USART1 Tx (PA9) as alternate function push-pull */
		GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;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 );return xReturn;
}

使用printf

仿真里看串口打印消息

  1. 命名规范

三、FreeRTOS命名规范_freertos命名规则-CSDN博客

3、  验证

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

4、  配置串口

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

初始化删除多余的东西,只保留串口一的配置(这里的函数就是个串口的初始化,有效程序只有串口配置和GPIO配置,按照我下面写的程序弄就可以了。写完记得再main里调用,参数可以不填写。。或者删掉重新写个这个函数也可以)

xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{xComPortHandle xReturn;USART_InitTypeDef USART_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;/* Enable USART1 clock */RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE );/* Configure USART1 Rx (PA10) as input floating */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init( GPIOA, &GPIO_InitStructure );/* Configure USART1 Tx (PA9) as alternate function push-pull */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;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 );return xReturn;
}

使用printf

仿真里看串口打印消息

5、  命名规范

三、FreeRTOS命名规范_freertos命名规则-CSDN博客

动态任务的创建

1、  任务是什么

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

说明:使用void *类型形参,确保可以传入任意类型的参数

2、  任务实验

实现

创建任务函数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:任务句柄指针。用于存储创建任务后的任务句柄,可选参数。

返回值

如果任务创建成功,返回pdPASS。

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

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

实验

xTaskCreate(test1,"demo1",100,NULL,1,NULL);
xTaskCreate(test2,"demo2",100,NULL,1,NULL);

int a,b;
void test1(void *param)
{while(1){a++;printf("test1\n");}
}
void test2(void *param)
{while(1){b++;printf("test2\n");}
}

3、  任务的内部

① 代码段和数据区由编译器在编译代码时自动分配与控制

② 堆的分配和使用由程序员控制

③ C代码中一般不会显式使用栈,将由编译器完成;在汇编代码中,程序员可以设置栈的位置并使用

④ C代码也不会显示使用寄存器,也是由编译器完成

个人:代码区 + 数据区 + 栈 + 堆可以理解为任务的实体 + 运行环境

任务切换的本质:保存前一任务(prev)的当前运行状态,恢复后一任务(next)之前的运行状态,并切换到该任务运行

4、  任务控制块

 TCB_t的全称为Task Control Block,也就是任务控制块,这个结构体包含了一个任务所有的信息,但是源代码中存在大量的条件配置选项,以下屏蔽掉的都是可以通过条件来配置的选项,通过条件来决定哪些定义使用或者不用,暂时不需要用到这些,对条件配置项进行屏蔽,TCB最主要的参数在上面它的定义以及相关变量的解释如下

5、任务状态

就绪态(Ready):任务已经具备了运行条件(没有被挂起或阻塞),但是有更高优先级或同优先级的任务正在运行,所以需要等待。

运行态(Running):当任务正在运行时,此时的状态被称为运行态,即CPU的使用权被这个任务占用。

阻塞态(Blocked):任务在等待信号量消息队列、事件标准组、系统延时时,被称为阻塞态,如果等待的事件到了,就会自动退出阻塞态,准备运行。

挂起态(Suspended):任务被暂时停止,通过调用挂起函数(vTaskSuspend())可以把指定任务挂起,任务挂起后暂时不会运行,只有调用恢复函数(xTaskResume())才可以退出挂起状态。

静态任务创建

xTaskCreateStatic():

  xTaskCreateStatic() 用于在系统中创建静态任务。与xTaskCreate()动态分配任务内存不同,xTaskCreateStaitc()需要开发者为任务栈和任务控制块(TCB)提供预先分配的内存空间。这对于内存受限或需要更精准控制任务内存的系统来说非常有用。

函数原型

TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,const char * const pcName,                                     const uint32_t ulStackDepth,void * const pvParameters,UBaseType_t uxPriority,StackType_t * const puxStackBuffer,StaticTask_t * const pxTaskBuffer )

参数解释:

pvTaskCode:指向任务函数的指针。

pcName:任务的名称,通常用于调试目的。

ulStackDepth:任务栈大小,以堆栈类型(StackType_t)为单位计算。

pvParameters:传递给任务函数的参数指针。

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

puxStackBuffer:指向已分配的任务栈内存缓冲区的指针。

pxTaskBuffer:指向已分配的任务控制块 (TCB) 内存结构的指针

函数返回值:

成功创建任务时,返回任务句柄 TaskHandle_t。

若任务创建失败,返回 NULL。

挂起任务、恢复任务

挂起任务函数原型

vTaskSuspend( TaskHandle_t xTaskToSuspend )

参数

xTaskToSuspend:需要挂起任务的句柄

实验

创建任务时加上句柄

句柄声明

在任务1里挂起任务2

void vTask1( void *pvParameters )
{while(1){printf("vTask1\n");demo1=1;demo2=0;vTaskDelay(4);vTaskSuspend(CreatedTask);}
}

恢复任务函数原型

 void vTaskResume( TaskHandle_t xTaskToResume )

参数

TaskToResumex:需要恢复任务的句柄

实验

//挂起后又恢复了实验中如果正常执行任务2就验证了
//也可以再创建个任务3,进入延时一段时间恢复任务2
void vTask1( void *pvParameters )
{while(1){printf("vTask1\n");demo1=1;demo2=0;vTaskDelay(4);vTaskSuspend(CreatedTask);vTaskDelay(4);vTaskResume(CreatedTask); }}

任务删除

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

函数原型

void vTaskDelete( TaskHandle_t xTaskToDelete )

参数:

xTaskToDelete:需要删除任务的句柄

空闲任务与钩子函数

1、空闲任务

创建的任务大部份时间都处于阻塞态。这种状态下所有的任务都不可运行,所以也不能被调度器选中。但处理器总是需要代码来执行——所以至少要有一个任务处于运行态。为了保证这一点,当调用 vTaskStartScheduler()时,调度器会自动创建一个空闲任务。空闲任务是一个非常短小的循环——和最早的示例任务十分相似,总是可以运行。空闲任务拥有最低优先级(优先级 0)以保证其不会妨碍具有更高优先级的应用任务进入运行态——当然,没有任何限制说是不能把应用任务创建在与空闲任务相同的优先级上;如果需要的话,你一样可以和空闲任务一起共享优先级。运行在最低优先级可以保证一旦有更高优先级的任务进入就绪态,空闲任务就会立即切出运行态。

2、  钩子函数

通过空闲任务钩子函数(或称回调,hook, or call-back),可以直接在空闲任务中添加应用程序相关的功能。空闲任务钩子函数会被空闲任务每循环一次就自动调用一次。通常空闲任务钩子函数被用于:

● 执行低优先级,后台或需要不停处理的功能代码。

● 测试系统处理(空闲任务只会在所有其它任务都不运行时才有机会执行,所以测量出空闲任务占用的处理时间就可以清楚的知道系统有多少富余的处理时间)。

●  将处理器配置到低功耗模式——提供一种自动省电方法,使得在没有任何应用功能

● 需要处理的时候,系统自动进入省电模式。

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

1. 绝不能阻或挂起。空闲任务只会在其它任务都不运行时才会被执行(除非有应用任务共享空闲任务优先级)。以任何方式阻塞空闲任务都可能导致没有任务能够进入运行态!

2.  如果应用程序用到了 vTaskDelete() AP 函数,则空闲钩子函数必须能够尽快返回。因为在任务被删除后,空闲任务负责回收内核资源。如果空闲任务一直运行在钩子函数中,则无法进行回收工作。

4、  钩子函数的使用

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

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

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

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

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

● 接下来我们声明写一个vApplicationIdleHook函数并在里面写自己的任务程序就可以了

FreeRTOS的延时函数

vTaskDelay()延时函数,参数xTicksToDelay表示,延时xTicksToDelay*Tick的时间,填入1表示延时1个Tick的时间

vTaskDelayUntil()函数,参数pxPreviousWakeTime是一个起始的Tick时间,xTimeIncrement是填入所需要延时的时间。当需要我们的任务在精确时间开始执行时可以使用该函数达到准确延时。

xTaskGetTickCount()获取当前时间节点

void vTask1( void *pvParameters )
{int i=0;int j=0;int BUF[6]={4,16,12,2};while(1){TickType_t tStart = xTaskGetTickCount();//获取时间节拍for(i=0;i<BUF[j];i++){printf("vTask1\n");}j++;if(j>4){j=0;}demo1=1;demo2=0;
//		vTaskDelay(4);//固定延时xTaskDelayUntil(&tStart,4);//动态调节的延时}
}

Cubemx使用

1、  打开cubemx

2、  新建工程,选择自己芯片的型号

3 、配置LED灯以后,选择FreeRTOS,并配置版本V2

3、改下时钟

4、  生成工程

5、  程序编写

//初始化
void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_SET);/*Configure GPIO pin : PB0 */GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);}

void StartDefaultTask(void *argument)
{/* USER CODE BEGIN StartDefaultTask *//* Infinite loop */for(;;){HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);osDelay(500);}/* USER CODE END StartDefaultTask */
}
void StartTask02(void *argument)
{/* USER CODE BEGIN StartTask02 *//* Infinite loop */for(;;){HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0);osDelay(500);}/* USER CODE END StartTask02 */
}

5、烧录验证两个灯闪烁了

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

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

相关文章

基于多智能体系统一致性算法的电力系统分布式经济调度策略MATLAB程序

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 参考文献&#xff1a; 主要内容&#xff1a; 应用多智能体系统中的一致性算法&#xff0c;以发电机组的增量成本和柔性负荷的增量效益作为一致性变量&#xff0c;设计一种用于电力系统经济调度的算法&#x…

openwrt中taiscale自动安装脚本详解

openwrt中taiscale自动安装脚本详解 一、代码仓库地址 https://github.com/adyanth/openwrt-tailscale-enabler 二、代码仓库中脚本文件详解 主要包含三个脚本分别是etc/init.d/tailscale、usr/bin/tailscale、usr/bin/tailscaled &#xff0c;接下来逐个分析一下脚本中的具…

3.1【窗口】窗口简介与窗口组

一,窗口简介 Windows用于显示内容,并将不同生成的内容组合在一起。每个不同的呈现器都可以在同一个进程中,也可以在另一个或多个进程中。 Screen中的窗口概念与你在传统窗口系统中可能习惯的略有不同。在Screen中,当内容来自不同来源时,应用程序被分成几个窗口,当应用程…

Linux查看进程PID以及杀掉进程的方法

目录 参考链接 前言 查看进程PID PS命令 ps -le命令 查找父进程 杀死进程 参考链接 【Linux 】 ps命令详解&#xff0c;查看进程pid_linux查看pid 对应的程序-CSDN博客 Linux查看进程PID的方法&#xff08;linux查进程的pid&#xff09;附带自动kill 掉_linux查看pid 对…

DDA 算法

CAD 算法是计算机辅助设计的算法&#xff0c;几何算法是解决几何问题的算法 CAD 算法是指在计算机辅助设计软件中使用的算法&#xff0c;用于实现各种设计和绘图功能&#xff0c;CAD 广泛应用于建筑、机械、电子等领域&#xff0c;可以大大提高设计效率和精度 绘图算法是 CAD…

机器学习算法---聚类

类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统计学检验箱…

大数据机器学习与深度学习——过拟合、欠拟合及机器学习算法分类

大数据机器学习与深度学习——过拟合、欠拟合及机器学习算法分类 过拟合&#xff0c;欠拟合 针对模型的拟合&#xff0c;这里引入两个概念&#xff1a;过拟合&#xff0c;欠拟合。 过拟合&#xff1a;在机器学习任务中&#xff0c;我们通常将数据集分为两部分&#xff1a;训…

03进程基础-学习笔记

Process 进程 进程为操作系统的基本调度单位&#xff0c;占用系统资源(cpu,内存)完成特定任务&#xff0c;所有说进程是操作系统的标准执行单元 进程与程序的差别 程序是静态资源&#xff0c;存储与电脑磁盘中(disk磁盘资源)程序执行后会创建进程&#xff0c;负责完成功能&a…

Python-flask 入门代码

python与pycharm安装 过程略&#xff0c;网上很多&#xff0c;记得为pycharm配置默认解释器 虚拟环境 pipenv # 全局安装虚拟环境 # 可加-U参数&#xff0c;明确全局安装&#xff0c;不加好像也可以? pip3 install pipenv #检查安装情况 pipenv --version # ---控制台输出…

机械硬盘和固态硬盘速度测试

利用ubuntu自带的disk磁盘管理软件对手头的三个硬盘做压力测试&#xff0c;disk软件挺好用的&#xff0c;再也不用命令了。 第一个是致态的1T固态硬盘&#xff0c;速度1.8GB/S。 ST机械硬盘&#xff0c;速度只有300多MB/S. 三星固态硬盘&#xff0c;速度1.4GB/s。

汽车发动机市场调研:预计2029年将达到642亿美元

过去汽车发动机行业快速发展&#xff0c;很多产品都出现供不应求&#xff0c;甚至加价销售的状况&#xff0c;而随着产能过剩、需求下滑&#xff0c;未来汽车发动机行业的价格竞争将愈发激烈&#xff0c;形成新的供需矛盾。根据动力源类型&#xff0c;汽车可分类为传统燃油汽车…

MATLAB2022安装下载教程

安装包需从夸克网盘自取&#xff1a; 链接&#xff1a;https://pan.quark.cn/s/373ffc9213a1 提取码&#xff1a;N7PW 1.将安装包解压 2.以管理员的身份运行文件夹中的setup文件 3.点击高级选项--->我有文件安装密钥 4. 选择【是】&#xff0c;进入下一步 5.输入密钥 0532…

【PHP入门】1.1-PHP初步语法

-PHP语法初步- PHP是一种运行在服务器端的脚本语言&#xff0c;可以嵌入到HTML中。 1.1.1PHP代码标记 在PHP历史发展中&#xff0c;可以使用多种标记来区分PHP脚本 ASP标记&#xff1a; <% php代码 %>短标记&#xff1a; <? Php代码 ?>&#xff0c;以上两种…

智能优化算法应用:基于供需算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于供需算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于供需算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.供需算法4.实验参数设定5.算法结果6.参考文献7.MA…

大模型自定义算子优化方案学习笔记:CUDA算子定义、算子编译、正反向梯度实现

01算子优化的意义 随着大模型应用的普及以及算力紧缺&#xff0c;下一步对于计算性能的追求一定是技术的核心方向。因为目前大模型的计算逻辑是由一个个独立的算子或者说OP正反向求导实现的&#xff0c;底层往往调用的是GPU提供的CUDA的驱动程序。如果不能对于整个计算过程学习…

货物数据处理pandas版

1求和 from openpyxl import load_workbook import pandas as pddef print_hi(name):# Use a breakpoint in the code line below to debug your script.print(fHi, {name}) # Press CtrlF8 to toggle the breakpoint.# Press the green button in the gutter to run the scr…

【C++学习————引用】

【C学习——————引用】 欢迎阅读新一期的c模块————引用 ✒️个人主页&#xff1a;-Joker- &#x1f3f7;️专栏&#xff1a;C &#x1f4dc;代码仓库&#xff1a;c_code &#x1f339;&#x1f339;欢迎大佬们的阅读和三连关注&#xff0c;顺着评论回访&#x1f339;&a…

对可恢复的情况使用受检异常

在Java中&#xff0c;受检异常&#xff08;Checked Exception&#xff09;通常用于表示程序能够预期并且可能进行恢复的异常情况。这类异常是在编译时由编译器强制进行处理的&#xff0c;使得程序员必须显式处理这些异常&#xff0c;或者在方法签名中使用 throws 关键字声明。 …

react之项目打包,本地预览,路由懒加载,打包体积分析以及如何配置CDN

react之项目打包,本地预览,路由懒加载,打包体积分析以及如何配置CDN 一、项目打包二、项目本地预览三、路由懒加载四、打包体积分析五、配置CDN 一、项目打包 执行命令 npm run build根目录下生成的build文件夹 及时打包后的文件 二、项目本地预览 1.全局安装本地服务包 npm…

【Linux】介绍:进程退出、进程等待、进程程序替换

目录 一、进程退出 _exit函数 exit函数 _exit()与exit比较 return退出 二、进程等待 wait方法 waitpid方法 三、进程程序替换 替换函数 函数解释 命名理解 使用举例 一、进程退出 正常终止&#xff08;可以通过 echo $? 查看进程退出码&#xff09;&#xff1a;1.…