FreeRTOS教程——任务(一)

2023-05-16

文章目录

  • FreeRTOS教程——任务(一)
    • 概述
      • 任务状态
      • 任务优先级
      • 执行任务
    • 单元
      • xTaskCreate
      • vTaskDelete
      • vTaskDelay
      • vTaskSuspend
      • vTaskResume
    • 综合实例

FreeRTOS教程——任务(一)

概述

任务状态

一个任务可以是以下几种状态中的一种:

  • 运行 正在执行的任务就是处于运行状态,它占用了处理器。
  • 就绪 就绪的任务是那些可以执行(没有被阻塞或暂停),但是因为其他相同或更高优先级任务正在运行造成还没有运行的任务。
  • 阻塞 当一个任务等待临时事件或外部事件时它就是处于阻塞状态。例如,任务调用 vTaskDelay() ,它将被阻塞(置为阻塞状态)直到超过延时时间 – 一个临时事件。任务也可以阻塞等待队列和信号事件。阻塞状态的任务一般有一个超时时间,超时后任务将解锁。阻塞的任务不会参与调度。
  • 暂停 暂停状态的任务也不参与调度。任务只有在调用 API 函数 vTaskSuspend() 和 xTaskResume() 时才会进入或者退出暂停状态。它不能指定超时时间。

image-20221009182043107img

任务优先级

每个任务将分配一个从 0 到 ( configMAX_PRIORITIES – 1 ) 的优先级。configMAX_PRIORITIES 在文件 FreeRTOSConfig.h 中定义,configMAX_PRIORITIES参数值越大,FreeRTOS 占用的
RAM 就越多。

低优先级任务使用较小的数字,缺省的空闲优先级 tskIDLE_PRIORITY 定义为 0。

调度器保证处于就绪或运行状态的任务分配到处理器时间,高优先级任务先分配。换句话说,处理器时间总是分配给能够运行的最高优先级任务。

执行任务

一个任务有下面的结构形式:

void vATaskFunction( void *pvParameters ) {
  for( ;; ) {
    -- Task application code here.
    --
  }
}

类型 pdTASK_CODE 定义为返回值是 void 的函数,并使用 void 指针作为唯一的参数。所有的任务函数都是这个类型,可以传递任意类型的参数到任务 – 在
任务系统标准演示
中进行了演示。

任务函数应当从不返回,因此它通常执行一个连续的循环,参考 RTOS 的例子。

任务由函数 xTaskCreate() 创建,使用 vTaskDelete() 删除。

单元

  • vTaskDelay
  • vTaskDelayUntil
  • uxTaskPriorityGet
  • vTaskPrioritySet
  • vTaskSuspend
  • vTaskResume
  • vTaskResumeFromISR
  • vTaskSetApplicationTag
  • xTaskCallApplicationTaskHook

xTaskCreate

task. h

 portBASE_TYPE xTaskCreate( 
   pdTASK_CODE pvTaskCode, 
   const portCHAR * const pcName, 
   unsigned portSHORT usStackDepth, 
   void *pvParameters, 
   unsigned portBASE_TYPE uxPriority, 
   xTaskHandle *pvCreatedTask 
 );

创建新的任务并添加到任务队列中,准备运行

Parameters

pvTaskCode指向任务的入口函数. 任务必须执行并且永不返回 (即:无限循环).
pcName描述任务的名字。主要便于调试。最大长度由configMAX_TASK_NAME_LEN.定义
usStackDepth指定任务堆栈的大小 ,堆栈能保护变量的数目- 不是字节数. 例如,如果堆栈为16位宽度,usStackDepth定义为 100, 200 字节,这些将分配给堆栈。堆栈嵌套深度(堆栈宽度)不能超多最大值——包含了size_t类型的变量
pvParameters指针用于作为一个参数传向创建的任务
uxPriority任务运行时的优先级
pvCreatedTask用于传递一个处理——引用创建的任务

返回

pdPASS 是如果任务成功创建并且添加到就绪列中,另外错误代码在projdefs. H文件定义

使用例子

// 创建任务
void vTaskCode( void * pvParameters ){
  for( ;; ){
    // 任务代码
  }
}
// 函数来创建一个任务
void vOtherFunction( void ){
  static unsigned char ucParameterToPass;
  xTaskHandle xHandle;
  // 创建任务,存储处理。注意传递的参数为ucParameterToPass
  //它在任务中不能始终存在, 所以定义为静态变量. 如果它是动态堆栈的变量,可能存在
  // 没有那么长,或者至少随着时间毁灭,
  // 新的时间, 尝试存储它
  xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
  // 使用句柄来删除任务
  vTaskDelete( xHandle );
}

vTaskDelete

task. h

void vTaskDelete( xTaskHandle pxTask );

INCLUDE_vTaskDelete必须定义为1,这个函数才能可用。查看配置部分获得更多信息。

从RTOS实时内核管理中移除任务。要删除的任务将从就绪,封锁,挂起,事件列表中移除,

注意:空闲任务负责释放内核分配给已删除任务的内存。因此,如果应用程序调用了vTaskDelete (),微控制器执行时间,空闲任务不假死是很重要的。内存分配给任务的代码不会自动释放,应该在任务删除之前。

参考演示程序death. c 中的例子使用 vTaskDelete ().

参数:

pxTask处理要删除的任务。传递NULL将引起调用任务删除

Example usage:

void vOtherFunction( void ){
  xTaskHandle xHandle;
  // 创建任务,存储处理
  xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
  // 使用处理来删除任务. 
  vTaskDelete( xHandle );
}

vTaskDelay

task. h

void vTaskDelay( portTickType xTicksToDelay );

INCLUDE_vTaskDelay必须设置为1,这个函数才为可用。参考配置获得更多信息。

延时任务为已知时间片。任务被锁住剩余的实际时间由时间片率决定。portTICK_RATE_MS常量用来用来从时间片速率(一片周期代表着分辨率)来计算实际时间。

vTaskDelay()指定一个任务希望的时间段,这个时间之后(调用vTaskDelay() )任务解锁。例如,指定周期段为100时间片,将使任务在调用vTaskDelay()100个时间片之后解锁。vTaskDelay()不提供一个控制周期性任务频率的好方法,像通过代码采取的路径,和其他任务和中断一样,在调用vTaskDelay()后 影响频率,因此任务所需的时间下一次执行。

参考

vTaskDelayUntil() ,这个交替的API函数设计了执行固定的频率。它是指定的一个绝对时间(而不是一个相对时间)后,调用任务解锁。

参数:

xTicksToDelay时间数量,调用任务应该锁住的时间片周期

使用例子:

void vTaskFunction( void * pvParameters ) {
/* 挂起500ms. */
const portTickType xDelay = 500 / portTICK_RATE_MS; 
  for( ;; ) {
    /* 简单的每 500ms触发LED, .在每两次触发间挂起*/ 
    vToggleLED();
    vTaskDelay( xDelay );
  }
}

vTaskSuspend

task.h

void vTaskSuspend( xTaskHandle pxTaskToSuspend );

设置INCLUDE_vTaskSuspend 为1,此函数才能使用。参考配置获得更多信息。

挂起任务。当挂起一个任务时,不管优先级是多少,不需要占用任何微控制器处理器时间。

调用vTaskSuspend不会累积——即:在统一任务中调用vTaskSuspend两次,但只需调用一次vTaskResume () 来是挂起的任务就绪。

参数:

xTaskToSuspend处理需要挂起的任务。传递NULL将挂起调用此函数的任务。

使用范例:

void vAFunction( void ){
  xTaskHandle xHandle;
  // 创建任务,保存句柄
  xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
  // ...
  // 使用此句柄来挂起创建的任务
  vTaskSuspend( xHandle );
  // ...
  // 创建的任务不会在这期间运行,除非
  // 其他任务调用 vTaskResume( xHandle )
  //...
  // 挂起自己
  vTaskSuspend( NULL );
  // 不能运行到这里,除非另一个任务调用vTaskResume
  // 使用此任务的句柄为参数
}

vTaskResume

task. h

void vTaskResume( xTaskHandle pxTaskToResume );

设置INCLUDE_vTaskSuspend为1,此函数才能使用。参考配置获得更多信息。

唤醒挂起的任务。

必须是调用 vTaskSuspend () 后挂起的任务,才有可能通过调用 vTaskResume ()重新运行。

  • Parameters:

    pxTaskToResume 就绪的任务的句柄

使用范例:

 void vAFunction( void )
 {
 xTaskHandle xHandle;
// 创建任务,保存句柄
xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
// ...
// 使用此句柄来挂起创建的任务
vTaskSuspend( xHandle );
// ...
// 创建的任务不会在此期间运行,除
// 另外一个任务调用 vTaskResume( xHandle )
//...
// 唤醒自己
vTaskResume( xHandle );
// 创建的任务将按照它在系统中的优先级
// 再次获得微处理器的处理时间
 }

综合实例

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "key.h"
#include "exti.h"
#include "FreeRTOS.h"
#include "task.h"
#include "beep.h"
/*
key_up键按下,任务1挂起,key1键按下,任务1恢复运行,key2键按下,任务2挂起,
*/
//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);

//任务优先级
#define KEY_TASK_PRIO		2
//任务堆栈大小	
#define KEY_STK_SIZE 		128  
//任务句柄
TaskHandle_t KeyTask_Handler;
//任务函数
void key_task(void *pvParameters);

//任务优先级
#define TASK1_TASK_PRIO		3
//任务堆栈大小	
#define TASK1_STK_SIZE 		128  
//任务句柄
TaskHandle_t Task1Task_Handler;
//任务函数
void task1_task(void *pvParameters);

TaskHandle_t Task2Task_Handler;
TaskHandle_t Task3Task_Handler;
void task2_task(void *pvParameters);
void task3_task(void *pvParameters);


int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 
	delay_init();	    				//延时函数初始化	 
	uart_init(115200);					//初始化串口
	LED_Init();		  					//初始化LED
	KEY_Init();							//初始化按键
	EXTIX_Init();						//初始化外部中断
	BEEP_Init();         	//初始化蜂鸣器端口

	//创建开始任务
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
	//创建KEY任务
	xTaskCreate((TaskFunction_t )key_task,             
                (const char*    )"key_task",           
                (uint16_t       )KEY_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )KEY_TASK_PRIO,        
                (TaskHandle_t*  )&KeyTask_Handler);  
    //创建TASK1任务
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //创建TASK2任务
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task1_task",   
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
		//创建TASK3任务
    xTaskCreate((TaskFunction_t )task3_task,     
                (const char*    )"task3_task",   
                (uint16_t       )TASK1_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK1_TASK_PRIO,
                (TaskHandle_t*  )&Task3Task_Handler); 
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//key任务函数
void key_task(void *pvParameters)
{
	u8 key;
	while(1)
	{
		
		key=KEY_Scan(0);
		switch(key)
		{
			case KEY0_PRES:
				vTaskSuspend(Task1Task_Handler);//挂起任务1
				printf("挂起任务1的运行!\r\n");
				break;	
			case KEY1_PRES:
				vTaskSuspend(Task2Task_Handler);//挂起任务2
				printf("挂起任务2的运行!\r\n");
				break;
			case KEY2_PRES:
				vTaskSuspend(Task3Task_Handler);//挂起任务3
				printf("挂起任务3的运行!\r\n");
				break;
			case WKUP_PRES:
				vTaskResume(Task1Task_Handler);	//恢复任务1
				vTaskResume(Task2Task_Handler);	//恢复任务1
				vTaskResume(Task3Task_Handler);	//恢复任务1
				printf("恢复所有任务的运行!\r\n");
		}
		vTaskDelay(10);			//延时10ms 
	}
}



//task1任务函数
void task1_task(void *pvParameters)
{
	u8 task1_num=0;
	while(1)
	{
		task1_num++;
		printf("任务1已经执行:%d次\r\n",task1_num);
    vTaskDelay(1000);                          
	}
}

//task2任务函数
void task2_task(void *pvParameters)
{
	u8 task2_num=0;
	while(1)
	{
		task2_num++;
		printf("任务2已经执行:%d次\r\n",task2_num);
    vTaskDelay(1000);                         
	}
}
void task3_task(void *pvParameters)
{
	u8 task3_num=0;
	while(1)
	{
		task3_num++;
		printf("任务3已经执行:%d次\r\n",task3_num);
    vTaskDelay(1000);                         
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS教程——任务(一) 的相关文章

  • FreeRTOS内核配置说明---FreeRTOS Kernel V10.2.1

    FreeRTOS内核是高度可定制的 使用配置文件FreeRTOSConfig h进行定制 每个FreeRTOS应用都必须包含这个头文件 用户根据实际应用来裁剪定制FreeRTOS内核 这个配置文件是针对用户程序的 而非内核 因此配置文件一般
  • 【FreeRTOS 信号量】互斥信号量

    互斥信号量与二值信号量类似 但是互斥信号量可以解决二值信号量出现的优先级翻转问题 解决办法就是优先级继承 普通互斥信号量创建及运行 参阅安富莱电子demo 互斥信号量句柄 static SemaphoreHandle t xMutex NU
  • FreeRTOS 软件定时器的使用

    FreeRTOS中加入了软件定时器这个功能组件 是一个可选的 不属于freeRTOS内核的功能 由定时器服务任务 其实就是一个定时器任务 来提供 软件定时器是当设定一个定时时间 当达到设定的时间之后就会执行指定的功能函数 而这个功能函数就叫
  • FreeRTOS简述和移植文档

    FreeRTOS简述和移植文档 文章目录 FreeRTOS简述和移植文档 1 前言 2 FreeRTOS简述 1 概述 2 实现 3 主要特色 4 支持平台 3 移植FreeRTOS 4 最后 1 前言 目前由于IOT的飞速发展 针对单片机
  • 一文教你学会keil软件仿真

    仿真在我们调试代码中是非常重要的 通过仿真 我们可以快速定位到错误代码 或者错误逻辑的地方 这里我就以上一篇博客为例 教大家如何软件仿真 软件仿真不需要单片机 直接通过keil软件进行代码调试 一 打开工具 二 选择软件仿真 三 开始仿真
  • FreeRTOS系列

    本文主要介绍如何在任务或中断中向队列发送消息或者从队列中接收消息 使用STM32CubeMX将FreeRTOS移植到工程中 创建两个任务以及两个消息队列 并开启两个中断 两个任务 Keyscan Task 读取按键的键值 并将键值发送到队列
  • freertos---软定时器

    一 软件定时器介绍 freeRTOS软件定时器的时基是基于系统时钟节拍实现的 可以创建很多个 在硬件定时器资源不充足的情况下非常有用 软件定时器一般用作周期性地执行函数 在创建软件定时器时指定软件定时器的回调函数 在回调函数中实现相应的功能
  • FreeRTOS系列

    1 RTOS简介 RTOS全称为 Real Time Operation System 即实时操作系统 RTOS强调的是实时性 又分为硬实时和软实时 硬实时要求在规定的时间内必须完成操作 不允许超时 而软实时里对处理过程超时的要求则没有很严
  • FreeRTOS_中断

    传送门 博客汇总帖 传送门 Cortex M3 中断 异常 传送门 Cortex M3笔记 基础 笔记内容参考 正点原子的FreeRTOS开发手册 cortex m3权威指南 Cortex M3和Cortex M4权威指南等 文中stm32
  • STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • Arduino IDE将FreeRTOS用于STM32

    介绍 适用于STM32F103C8的FreeRTOS STM32F103C是一种能够使用FreeRTOS的ARM Cortex M3处理器 我们直接在Arduino IDE中开始使用STM32F103C8的FreeRTOS 我们也可以使用K
  • [FreeRTOS入门学习笔记]定时器

    定时器的使用步骤 1 定义一个handle xTimerCreate创建 2 启动定时器 在Task1中调用 通过队列通知守护任务来执行定时器任务 要再config头文件中定义守护任务相关配置 虽然定时器是在task1中启动 但是定时器的任
  • FreeRTOS多任务调度器基础

    Cortex M4中SysTick调度器核心 Cortex M4中的中断管理 Cortex M4中影子栈指针 Cortex M4中SVC和PendSV异常 1 Cortex M4中SysTick调度器核心 systick每一次中断都会触发内
  • FreeRTOSConfig.h 配置优化及深入

    本篇目标 基于上一篇的移植freertos stm32f4 freertos 上 修改 FreeRTOSConfig h 文件的相关配置来优化辅助 FreeRtos 的使用 并且建立一些基本功能 信号量 消息地列等 的简单应用位于 stm3
  • FreeRTOS 配置TICK_RATE_HZ

    我使用的是带有 5 4 版 FreeRTOS 的 MSP430f5438 我有一个有趣的问题 我无法弄清楚 基本上 当我将 configTICK RATE HZ 设置为不同的值时 LED 闪烁得更快或更慢 它应该保持相同的速率 我将 con
  • 使用 GCC 编译器的 ARM 内核的堆栈回溯(当存在 MSP 到 PSP 切换时)

    核心 ARM Cortex M4 编译器 GCC 5 3 0 ARM EABI 操作系统 免费 RTOS 我正在使用 gcc 库函数 Unwind Reason Code Unwind Backtrace Unwind Trace Fn v
  • 防止GCC LTO删除函数

    我使用 GCC ARM Embedded 和 FreeRTOS FreeRTOS具有的功能vTaskSwitchContext 仅在某些情况下使用 内联汇编代码 问题是 当我使用LTO时 GCC不考虑内联汇编代码并认为该函数没有被使用 因此
  • FreeRTOS 匈牙利表示法 [重复]

    这个问题在这里已经有答案了 我是 RTOS 和 C 编程的新手 而且我仍在习惯 C 的良好实践 因此 我打开了一个使用 FreeRTOS 的项目 我注意到操作系统文件使用匈牙利表示法 我知道一点符号 但面临一些新的 标准 FreeRTOS
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J

随机推荐

  • CUDNN_STATUS_NOT_INITIALIZED解决办法

    在某平台跑代码 xff0c 最开始尝试去训练 xff0c 发现训练成功后久终止 xff0c 修改部分参数后再次运行发现这个错误 CUDNN STATUS NOT INITIALIZED 解决方法 xff1a 就是python进程其实还在继续
  • 企业数据仓库总线架构、总线矩阵笔记 (第三篇)

    一 总线架构 维度建模的数据仓库中 xff0c 有一个概念叫Bus Architecture xff0c 中文一般翻译为 总线架构 总线架构是Kimball的多维体系结构 xff08 MD xff09 中的三个关键性概念之一 xff0c 另
  • Mininet使用教程

    注 xff1a 1 重要的链接 xff1a http mininet org walkthrough display startup options 2 IPv4与IPv6之间的地址转换 https www subnetonline com
  • 关系型数据库与非关系型数据库

    开发工作中我们常用的数据库大致分为关系型数据库和非关系型数据库两种 xff0c 那这两种到底是什么呢 xff1f 1 关系型数据库 所谓关系型数据库 xff0c 是建立在关系模型 基础上的数据库 关系模型由关系数据结构 关系操作集合 关系完
  • 深度学习常用优化算法moment/Adagrad/RMSProp/Adadelta/Adam

    1 经验风险和风险 经验风险是训练数据集的平均损失 xff0c 风险是整个数据群的预期损失 2 优化算法作用 在最小化目标函数方面的性能 xff0c 即减小训练误差 xff0c 而不是模型的泛化误差 3 深度学习的优化挑战 局部最小值 小批
  • K8S 快速入门(五)网络通信原理:Pod网络

    一 Pod网络 1 Pod结构 Pod的特点 xff1a 容器 1 有自己的IP地址 2 有自己的hostname 3 有自己的端口 Pod实际上可以理解为就是k8s云平台中的虚拟机 xff0c 而这个pod内部封装的是由docker引擎所
  • 代码优化之策略模式

    前言 xff1a 最近刚完成一个专项的代码codeing xff0c 今天花了一下午把代码优化了下 xff0c 总结了一些优化时用到的思想和方法 xff0c 后续也会继续补充好的代码习惯和最佳范式 策略模式 自我介绍 策略这个词应该怎么理解
  • python保存图片变色,与原始图像颜色不一致

    有时候将图片保存到本地会发现颜色与原来不一致 xff0c 有的变成相反的颜色了 针对这个问题 xff0c 我试了好多方法 xff0c 原理不大清楚 但多换一种保存方式就OK了 常用的有三种 xff1a 1 PIL span class to
  • 树莓派(Raspberry) WIFI 配置 (无显示器)

    目标 在没有显示器的情况下 xff0c 通过一根网线配置树莓派WIFI 然后开机自动连接WIFI xff0c 以后就可以直接通过主机通过VNC Viewer Putty也可以 控制树莓派 当然 xff0c 如果有网线也可以控制了 xff0c
  • 网站搭建教程(详细步骤 )

    目录 网站组成 一 服务器 二 网站程序 三 域名 四 空间基本介绍 搭建网站的基本步骤流程 教程解说 一 购买域名 二 购买服务器 三 相关配置 网站组成 一 服务器 什么是服务器 我们可以理解为一个容器 用来存放网站的内容部分 我们在互
  • c++11的regex使用

    首先不论在window下还是linux下 xff0c 你要通过c c 43 43 使用正则表达式 xff0c 你就必须包含所需的头文件regex 里面包含了所需的函数 xff0c 一般的第一步需要确定要匹配的模式pattern 使用rege
  • Qt信号与槽的五种连接方式

    qt信号与槽的五种连接方式 xff1a 1 默认连接 xff1a 如果是在同一线程等价于直连 xff0c 在不同线程等价于队列连接 2 直连 xff1a 信号在哪 xff0c 在哪个线程执行 xff08 最好只在同一线程中用 xff09 3
  • Android (Android studio3.0.1)一篇可以实现app多语言的转换(简单操作)的教程

    最近接触到了项目需要 xff0c 多语言的转换 网上有很多资料 xff0c 我整理一些 xff0c 简单适合自己使用的操作 第一步 打开Android studio 添加 Android Studio插件 AndroidLocalizati
  • Centos7部署java环境

    先更新 yum y update amp amp yum y upgrade 1 xff0c Wget 参考 xff1a https blog csdn net xieshen86 article details 125472698 htt
  • Ubuntu16.04安装deb包

    deb包是Debian xff0c Ubuntu等Linux发行版的软件安装包 xff0c 扩展名为 deb xff0c 是类似于rpm的软件包 xff0c Debian xff0c Ubuntu系统不推荐使用deb软件包 xff0c 因为
  • HCIE-RS面试--STP弊端

    1 收敛速度慢 监听状态15s是为了避免STP协议在收敛过程中产生临时环路 xff0c 让BPDU有足够的时间在整个网络进行传递 监听状态期间 xff0c MAC地址表受TC BPDU的影响会进行提前老化 xff0c 清除错误的MAC地址信
  • mapreduce 班级学生成绩统计

    这个是最近的一个实验 xff0c 其中这个实验老师的要求是 1 统计每个班成绩的最大值 最小值 并且输出姓名 如果有多个那么要都要输出 xff0c 然后输出每个班的平均值 再者就是每个班的成绩分布 xff0c 优秀良好 xff0c 及格不及
  • 解决修改css或js文件后,浏览器缓存未更新问题

    问题描述 xff1a 最近在上线新版本项目的时候 xff0c 发现有的用户的操作还是调用的老版本JS里面的内容 xff0c 这样就造成原来新的JS里面加上的限制不能限制用户的操作 xff0c 从而导致用户可以重复操作 问题产生原因 xff1
  • 最全UnityHub国际版下载链接Unity2022~2017各版本+Unity5.x【间歇性更新】

    Unity2022 2017各版本UnityHub国际版下载链接 间歇性更新 直链下载国际版UnityHub国际版下载链接Unity2022 xUnity2021 xUnity2020 xUnity2019 xUnity2018 xUnit
  • FreeRTOS教程——任务(一)

    文章目录 FreeRTOS教程 任务 xff08 一 xff09 概述任务状态任务优先级执行任务 单元xTaskCreatevTaskDeletevTaskDelayvTaskSuspendvTaskResume 综合实例 FreeRTOS