【FreeRTOS】二值信号量实现线程的同步

2023-05-16

【FreeRTOS】二值信号量实现线程的同步

测试环境如下

stm32L431RCT6
MDK keil5
stm32cube + FreeRTOS

一、添加多个任务

1、引脚配置

LED使用的引脚PA8和PB2设置成output

在这里插入图片描述

在这里插入图片描述

将按键引脚PC9设置为Input
在这里插入图片描述

2、选择时钟源,配置时钟

在这里插入图片描述

在这里插入图片描述

3、调试模式和基础源时钟

在这里插入图片描述

在基于STM32 HAL的项目中,一般需要维护的 “时基” 主要有2个:

  • HAL的时基,SYS Timebase Source
  • OS的时基(仅在使用OS的情况下才考虑)

而这些 “时基” 该去如何维护,主要分为两种情况考虑:

  • 裸机运行:

可以通过 SysTick(滴答定时器)或 (TIMx)定时器 的方式来维护 SYS Timebase Source,也就是HAL库中的 uwTick,这是HAL库中维护的一个全局变量。在裸机运行的情况下,我们一般选择默认的 SysTick(滴答定时器) 方式即可,也就是直接放在 SysTick_Handler() 中断服务函数中来维护。

  • 带OS运行:

前面提到的 SYS Timebase Source 是STM32的HAL库中的新增部分,主要用于实现 HAL_Delay() 以及作为各种 timeout 的时钟基准。

在使用了OS(操作系统)之后,OS的运行也需要一个时钟基准(简称“时基”),来对任务和时间等进行管理。而OS的这个 时基 一般也都是通过 SysTick(滴答定时器) 来维护的,这时就需要考虑 “HAL的时基” 和 “OS的时基” 是否要共用 SysTick(滴答定时器) 了。

如果共用SysTick,当我们在CubeMX中选择启用FreeRTOS之后,在生成代码时,CubeMX一定会报如下提示:在这里插入图片描述

建议不要使用 SysTick(滴答定时器)作为 “HAL的时基”,因为FreeRTOS要用,如果共用,潜在一定风险。

4、调试串口选择

在这里插入图片描述

需要在NVIC使能串口UART1中断

在这里插入图片描述

5、选择使用FREERTOS以及接口版本

在这里插入图片描述

Cortex微控制器软件接口标准(CMSIS)是独立于供应商的硬件抽象层,用于基于Arm Cortex处理器的微控制器。 CMSIS定义了通用工具接口,并提供一致的设备支持。 CMSIS软件接口简化了软件重用,CMSIS提供了到处理器和外围设备,实时操作系统以及中间件组件的接口。

V1使得软件能够在不同的RTOS系统下工作,为实时操作系统提供通用的API。 V2是在V1基础上的扩展了一些关于 Armv8-M的支持,动态对象,多核系统相关的东西。

6、创建任务

在这里插入图片描述

在这里插入图片描述

7、生成代码

在这里插入图片描述
在这里插入图片描述

8、添加UART串口打印代码

1)在uart.c里面添加printf重定向

/* USER CODE BEGIN 0 */
static uint8_t s_uart1_rxch;
char           g_uart1_rxbuf[256];
uint8_t        g_uart1_bytes;

/* USER CODE END 0 */
………..省略………
/* USER CODE BEGIN 1 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch,FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
	HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xFFFF);
	return ch;
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)
	{
		if(g_uart1_bytes<sizeof(g_uart1_rxbuf))
		{
			g_uart1_rxbuf[g_uart1_bytes++]=s_uart1_rxch;
		}
		HAL_UART_Receive_IT(&huart1,&s_uart1_rxch,1);
	}
}

2)使能UART1的中断,在该函数中进行

void MX_UART1_UART_Init(void)
{
。。。。
  /* USER CODE BEGIN USART1_Init 2 */
  //中断接收的每个字节暂时放在s_uart1_rxch
  HAL_UART_Receive_IT(&huart1, &s_uart1_rxch, 1);
  /* USER CODE END USART1_Init 2 */

}

3)在uart.h里面添加头文件和定义


/* USER CODE BEGIN Includes */
#include <stdio.h>

#include <string.h>
/* USER CODE END Includes */


/* USER CODE BEGIN Private defines */
extern char       g_uart1_rxbuf[256];

extern uint8_t    g_uart1_bytes;

#define clear_uart1_rxbuf() do {memset(g_uart1_rxbuf,0,sizeof(g_uart1_rxbuf));\
        g_uart1_bytes=0; } while(0)


/* USER CODE END Private defines */
void MX_USART1_UART_Init(void);

/* USER CODE BEGIN Prototypes */


9、跑马灯跑起来

跑马灯跑起来 在 freertos.c 文件中我们能看到我们创建的任务函数: void Start_RedLed_toggle(void const * argument) 我们需要在任务函数中写跑马灯程序:

在这里插入图片描述

/* USER CODE END Header_Start_RedLed_toggle */
void Start_RedLed_toggle(void const * argument)
{
  /* USER CODE BEGIN Start_RedLed_toggle */
  /* Infinite loop */
  for(;;)
  {

    osDelay(500);
    HAL_GPIO_WritePin(RedLED_GPIO_Port, RedLED_Pin, GPIO_PIN_SET);
    printf("this is RED!\r\n");
    osDelay(500);
    HAL_GPIO_WritePin(RedLED_GPIO_Port, RedLED_Pin, GPIO_PIN_RESET);
    osDelay(500);
  }
  /* USER CODE END Start_RedLed_toggle */
}

/* USER CODE END Header_start_GreenLed_toggle */
void start_GreenLed_toggle(void const * argument)
{
  /* USER CODE BEGIN start_GreenLed_toggle */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1000);
    HAL_GPIO_WritePin(GreenLED_GPIO_Port, GreenLED_Pin, GPIO_PIN_SET);
    printf("this is Green!\r\n");
    osDelay(1000);
    HAL_GPIO_WritePin(GreenLED_GPIO_Port, GreenLED_Pin, GPIO_PIN_RESET);
    osDelay(1000);
  }
  /* USER CODE END start_GreenLed_toggle */
}


10、运行测试

然后编译下载 ,可以观察到板子上的LED灯安装程序跑起来了,可以看到RedLed和GreenLed交替闪烁。1秒内红灯闪两次,绿灯闪一次。

在这里插入图片描述

二、实现多任务间的同步

在多任务处理系统中,如果一个任务开始访问资源,但在脱离运行状态之前没有完成其访问,则有可能出错。 如果任务使资源处于不一致状态,则通过任何其他任务或中断访问同一资源可能导致数据损坏或其他类似问题。

对任务之间或任务与中断之间共享的资源的访问必须使用**“互斥”技术进行管理**。 目标是确保一旦一个任务开始访问一个不可重入且不线程安全的共享资源,同一任务就具有对资源的独占访问权限,直到资源返回到一致状态为止。

FreeRTOS提供了几个可以用来实现互斥的特性,但是最好的互斥方法是(只要有可能,因为它不实用)设计应用程序,使资源不被共享,并且每个资源只从一个任务访问。

1、二值信号量

互斥信号是一种特殊类型的二进制信号量,用于控制对两个或多个任务之间共享的资源的访问。

信号量名副其实就是一个信号可以进行任务之前信息的交互,二值信号量通常用于互斥访问或同步。二值信号量就是一个只能保存一个数据的队列,这个队列要么是空要么是有他就只有两种状态。

2、创建信号量Semaphore

在 Timers and Semaphores 进行配置。

1)创建二值信号量Binary Semaphore,

这里比较简单我们只需要设置一下二值信号量的名字即可

在这里插入图片描述

  • Semaphore Name: 信号量名称
  • Allocation: 分配方式:Dynamic 动态内存创建
  • Conrol Block Name: 控制块名称

2)代码编写

1.创建二值信号量

这部分代码cubeMX会自动生成
在这里插入图片描述

3、相关API介绍

(1) osSemaphoreCreate

用于创建一个二值信号量,并返回一个ID。

函数 osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count)
参数 semaphore_def: 引用由osSemaphoreDef定义的信号量 count: 信号量数量
返回值 成功返回信号量ID,失败返回0
(2)osSemaphoreDelete

用于删除一个信号量,包括二值信号量,计数信号量,互斥量和递归互斥量。如果有任务阻塞在该信号量上,那么不要删除该信号量。

函数 osStatus osSemaphoreDelete (osSemaphoreId semaphore_id)
参数 semaphore_id: 信号量ID
返回值 错误码
(3)osSemaphoreRelease

用于释放信号量的宏。释放的信号量对象必须是已经被创建的,可以用于二值信号量、计数信号量、互斥量的释放,但不能释放由函数 xSemaphoreCreateRecursiveMutex() 创建的递归互斥量。可用在中断服务程序中。

函数 osStatus osSemaphoreRelease (osSemaphoreId semaphore_id)
参数 semaphore_id: 信号量ID
返回值 错误码
(4)osSemaphoreWait

用于获取信号量,不带中断保护。获取的信号量对象可以是二值信号量、计数信号量和互斥量,但是递归互斥量并不能使用这个 API 函数获取。可用在中断服务程序中。

函数 int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec)
参数 semaphore_id: 信号量ID millisec:等待信号量可用的最大超时时间,单位为 tick(即系统节拍周期)。 如果宏 INCLUDE_vTaskSuspend 定义为 1 且形参 xTicksToWait 设置为 portMAX_DELAY ,则任务将一直阻塞在该信号量上(即没有超时时间)
返回值 错误码

4、二值信号量使用

在 freertos.c 文件中,找到我们创建的两个任务,修改代码。

/* USER CODE END Header_Start_RedLed_toggle */
void Start_RedLed_toggle(void const * argument)
{
  /* USER CODE BEGIN Start_RedLed_toggle */
	osStatus xReturn = osErrorValue;
  /* Infinite loop */
  for(;;)
  {
	xReturn = osSemaphoreWait(myBinarySem01Handle, /* 二值信号量句柄 */
	                               osWaitForever); /* 等待时间 */
	if(osOK == xReturn)
	{
		printf("BinarySem get!\n\n");
		osDelay(500);
		HAL_GPIO_WritePin(RedLED_GPIO_Port, RedLED_Pin, GPIO_PIN_RESET);
		printf("this is RED!\r\n");
		osDelay(500);
		HAL_GPIO_WritePin(RedLED_GPIO_Port, RedLED_Pin, GPIO_PIN_SET);
		osDelay(500);
	}
  }
  /* USER CODE END Start_RedLed_toggle */
}

/* USER CODE END Header_start_GreenLed_toggle */
void start_GreenLed_toggle(void const * argument)
{
  /* USER CODE BEGIN start_GreenLed_toggle */
        osStatus xReturn;
  /* Infinite loop */
  for(;;)
  {

         if(HAL_GPIO_ReadPin(Key1_GPIO_Port, Key1_Pin) == GPIO_PIN_RESET)
         {
                 xReturn = osSemaphoreRelease(myBinarySem01Handle);//给出二值信号量
                 if(osOK == xReturn)
                 {
                         printf("release!\r\n");
                         osDelay(1000);
                         HAL_GPIO_WritePin(GreenLED_GPIO_Port, GreenLED_Pin, GPIO_PIN_RESET);
                         printf("this is Green!\r\n");
                         osDelay(1000);
                         HAL_GPIO_WritePin(GreenLED_GPIO_Port, GreenLED_Pin, GPIO_PIN_SET);
                         osDelay(1000);
                  }
                  else
                  {
                     printf("BinarySem release fail!\r\n");
                  }
         }
         osDelay(100);

  }
  /* USER CODE END start_GreenLed_toggle */
}

5、运行测试

红灯尝试获取资源,由于资源是可用的,红灯任务成功的获取资源(红灯闪烁一次),绿灯任务尝试获取资源,但是资源被红灯任务持有,所以尝试失败,绿灯任务进入阻塞状态等待资源,允许红灯再次运行(红灯闪烁一次),按键按下资源被释放,绿灯任务退出阻塞状态,绿灯任务获取资源成功(绿灯闪烁一次)并且之后允许访问资源,当绿灯任务执行完之后也会将资源释放。资源可以再次用于两个任务之间。

在这里插入图片描述

2、计数信号量

在这里插入图片描述

这里需要使用两个按键,按键配置的方法和KEY1一样,实现按下KEY1申请资源,按下KEY2释放资源。

1)创建计数信号量Counting Semaphore

要想使用计数信号量必须在 Config parameters 中把 USE_COUNTING_SEMAPHORES 选择 Enabled 来使能。

用计数信号量实现二值信号量只需将计数信号量的初始值设置为 1 即可。

在这里插入图片描述

添加计数信号量
在这里插入图片描述

  • Semaphore Name: 信号量名称
  • Count: 计数信号量的最大值
  • Allocation: 分配方式:Dynamic 动态内存创建
  • Conrol Block Name: 控制块名称

2)生成代码,计数信号量自动创建。

在这里插入图片描述

3)修改代码

void Start_RedLed_toggle(void const * argument)
{
  /* USER CODE BEGIN Start_RedLed_toggle */
	osStatus xReturn = osErrorValue;
  /* Infinite loop */
  for(;;)
  {
	/*xReturn = osSemaphoreWait(myBinarySem01Handle, // 二 ? 信号量句柄
	                            osWaitForever); // 等待时间
	*/

	if(HAL_GPIO_ReadPin(Key2_GPIO_Port, Key2_Pin) == GPIO_PIN_RESET)
	{
		 xReturn = osSemaphoreWait(myCountingSem01Handle, /* 计数信号量句柄 */
		                                        0); /* 等待时间:0 */

	 if(osOK == xReturn)
	 {
	      printf( "Key2 is pressed and successfully applied for parking space.\r\n" );
	      osDelay(500);
	      HAL_GPIO_WritePin(RedLED_GPIO_Port, RedLED_Pin, GPIO_PIN_RESET);
	      printf("this is RED!\r\n");
	      osDelay(500);
	      HAL_GPIO_WritePin(RedLED_GPIO_Port, RedLED_Pin, GPIO_PIN_SET);
	      osDelay(500);
	 }
	 else
	 {
	      printf( "Key2 is pressed. Sorry, the parking lot is full now!\r\n" );
	 }
	}
  }
  /* USER CODE END Start_RedLed_toggle */
}
void start_GreenLed_toggle(void const * argument)
{
  /* USER CODE BEGIN start_GreenLed_toggle */
	osStatus xReturn;
  /* Infinite loop */
  for(;;)
  {

	 if(HAL_GPIO_ReadPin(Key1_GPIO_Port, Key1_Pin) == GPIO_PIN_RESET)
	 {
		 //xReturn = osSemaphoreRelease(myBinarySem01Handle);//给出二 ? 信号量
		 xReturn = osSemaphoreRelease(myCountingSem01Handle);// 给出计数信号量

	 if(osOK == xReturn)
	 {
		 printf( "Key1 is pressed to release 1 parking space.\r\n" );
		 osDelay(1000);
		 HAL_GPIO_WritePin(GreenLED_GPIO_Port, GreenLED_Pin, GPIO_PIN_RESET);
		 printf("this is Green!\r\n");
		 osDelay(1000);
		 HAL_GPIO_WritePin(GreenLED_GPIO_Port, GreenLED_Pin, GPIO_PIN_SET);
		 osDelay(1000);
	  }
	  else
	  {
		  printf( "Key1 is pressed, but there is no parking space to release!\r\n" );
	  }
	 }
	 osDelay(100);

  }
  /* USER CODE END start_GreenLed_toggle */
}

4)运行测试

按下key2申请资源,按下key1释放资源,当申请资源数量为5时,再次申请资源会失败,只能等资源释放后才能再次申请。
在这里插入图片描述

参考资料:

配置说明:FreeRTOS记录(一、熟悉开发环境以及CubeMX下FreeRTOS配置) - 知乎 (zhihu.com)

二值信号量:(92条消息) FreeRTOS笔记篇:第七章 – 资源管理(互斥锁、二进制信号量、死锁)_墨客Y的博客-CSDN博客_freertos 死锁

创建二值信号量:(92条消息) STM32CubeMX学习笔记(30)——FreeRTOS实时操作系统使用(信号量)_Leung_ManWah的博客-CSDN博客_ossemaphorecreate

创建二值信号量:(92条消息) STM32CubeMX学习笔记(30)——FreeRTOS实时操作系统使用(信号量)_Leung_ManWah的博客-CSDN博客_ossemaphorecreate

(92条消息) STM32FreeRTOS二值信号量的基本介绍和操作_花落已飘的博客-CSDN博客

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【FreeRTOS】二值信号量实现线程的同步 的相关文章

  • FreeRTOS 软件定时器的使用

    FreeRTOS中加入了软件定时器这个功能组件 是一个可选的 不属于freeRTOS内核的功能 由定时器服务任务 其实就是一个定时器任务 来提供 软件定时器是当设定一个定时时间 当达到设定的时间之后就会执行指定的功能函数 而这个功能函数就叫
  • FreeRTOS学习笔记 6 - 互斥量

    目录 1 创建 2 获取 3 释放 4 测试 FreeRTOS不支持调度方式的设置 所以下面2个宏定义可以随意设置值 define RTOS IPC FLAG FIFO 0x00 define RTOS IPC FLAG PRIO 0x01
  • FreeRTOS学习笔记(3、信号量、互斥量的使用)

    FreeRTOS学习笔记 3 信号量 互斥量的使用 前言 往期学习笔记链接 学习工程 信号量 semaphore 两种信号量的对比 信号量的使用 1 创建信号量 2 give 3 take 4 删除信号量 使用计数型信号量实现同步功能 使用
  • Freertos中vTaskDelay()是怎么用的

    1 常见的使用场景 void vLED Task void pvParameters while 1 Heartbeat LED vTaskDelay 1000 portTICK RATE MS 说明 上面这段代码的意思是 led翻转后经过
  • STM32移植FreeRTOS的Tips

    转自 http bbs armfly com read php tid 7140 1 在FreeRTOS的demo文件夹中拷贝对应的FreeRTOSConfig h文件后 需要加入一行 define configUSE MUTEXES 1
  • 【FreeRTOS】队列的使用

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • FreeRTOS学习笔记<中断>

    中断概念 Cortex M的NVIC最多支持240个IRQ 中断请求 1个不可屏蔽中断 NMI 1个Systick 滴答定时器 定时器中断和多个系统异常 Cortex M处理器有多个用于管中断和异常的可编程寄存器 这些寄存器大多数都在 NV
  • FreeRTOS ------- 任务(task)

    在学习RTOS的时候 个人觉得带着问题去学习 会了解到更多 1 什么是任务 在FreeRTOS中 每个执行线程都被称为 任务 每个任务都是在自己权限范围内的一个小程序 其具有程序入口每个任务都是在自己权限范围内的一个小程序 其具有程序入口通
  • FreeRTOS打印任务对CPU的占有率

    1 配置RTOS 1 打开RTOS Config Parameter 找到Run Time And Task States gathering related definitions 使能GENERATE RUN TIME STATS US
  • 【FreeRTOS(三)】任务状态

    文章目录 任务状态 任务挂起 vTaskSuspend 取消任务挂起 vTaskResume 挂起任务调度器 vTaskSuspendAll 取消挂起任务调度器 xTaskResumeAll 代码示例 任务挂起 取消任务挂起 代码示例 挂起
  • freeRTOS使用uxTaskGetStackHighWaterMark函数查看任务堆栈空间的使用情况

    摘要 每个任务都有自己的堆栈 堆栈的总大小在创建任务的时候就确定了 此函数用于检查任务从创建好到现在的历史剩余最小值 这个值越小说明任务堆栈溢出的可能性就越大 FreeRTOS 把这个历史剩余最小值叫做 高水位线 此函数相对来说会多耗费一点
  • 基于HAL库的FREERTOS-----------三.队列

    一 队列简介 在实际的应用中 常常会遇到一个任务或者中断服务需要和另外一个任务进行 沟通交流 这个 沟通交流 的过程其实就是消息传递的过程 在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式 但是如果在使用操作系统的应用中用
  • FreeRTOS临界段和开关中断

    http blog sina com cn s blog 98ee3a930102wg5u html 本章教程为大家讲解两个重要的概念 FreeRTOS的临界段和开关中断 本章教程配套的例子含Cortex M3内核的STM32F103和Co
  • FreeRTOS,串口中断接收中使用xQueueOverwriteFromISR()函数,程序卡死在configASSERT

    原因 UART的中断优先级设置的太高 高于了configMAX SYSCALL INTERRUPT PRIORITY宏定义的安全中断等级 UART的中断等级小于等于宏定义的优先等级即可
  • FreeRTOS笔记(一)简介

    这个笔记主要依据韦东山freertos快速入门系列记录 感谢韦东山老师的总结 什么是实时操作系统 操作系统是一个控制程序 负责协调分配计算资源和内存资源给不同的应用程序使用 并防止系统出现故障 操作系统通过一个调度算法和内存管理算法尽可能把
  • FreeRTOS临界段

    1 临界段 在访问共享资源时不希望被其他任务或者中断打断的代码 这段要执行的代码称为临界段代码 2 设置临界段的目的 保护共享资源 例如 全局变量 公共函数 不可重入函数 函数里面使用 了一些静态全局变量 malloc 等 保护外设的实时性
  • STM32 Freertos 添加 外部sram heap_5.c

    1 添加外部SRAM 初始化 2 添加heap 5 c 3 初始化heap 5 c 外部堆栈 Define the start address and size of the two RAM regions not used by the
  • 使用 GCC 编译器的 ARM 内核的堆栈回溯(当存在 MSP 到 PSP 切换时)

    核心 ARM Cortex M4 编译器 GCC 5 3 0 ARM EABI 操作系统 免费 RTOS 我正在使用 gcc 库函数 Unwind Reason Code Unwind Backtrace Unwind Trace Fn v
  • 如何将 void* 转换为函数指针?

    我在 FreeRTOS 中使用 xTaskCreate 其第四个参数 void const 是传递给新线程调用的函数的参数 void connect to foo void const task params void on connect
  • 有可用的 FreeRTOS 解释语言库吗?

    我在一家公司工作 该公司使用 FreeRTOS 为多个设备创建固件 最近 我们对新功能的要求已经超出了我们固件工程师的工作能力 但我们现在也无力雇用任何新人 即使进行微小的更改 也需要固件人员在非常低的级别上进行修改 我一直在为 FreeR

随机推荐

  • 路径规划资料

    1 RRT算法原理图解 https blog csdn net weixin 43465857 article details 96451631 2 最透彻的A 算法详解 https my oschina net u 4847229 blo
  • nav2阅读笔记

    1 机器人起始坐标是在全局地图中 xff0c 目标点也在全局地图中 xff0c 全局路径规划在全局地图完成 机器人的运动控制是在局部地图中完成 xff0c 也就是在车体坐标系下 2 无人机 自动驾驶车辆全局路径规划 局部路径规划都是在全局坐
  • 日常使用标签2

    日常使用标签2 1 CUDA入门教程 https blog csdn net luoganttcc article details 123474189
  • 人工智能概述

    目录 什么是人工智能实现人工智能的方法逻辑编程机器学习深度学习机器学习和深度学习的区别 人工智能的分类如何实现人工智能 什么是人工智能 人工智能 又被称为机器智能 xff0c 是一种综合计算机科学 统计学 语言学等多种学科 xff0c 使机
  • 2019了,转行学编程过时了吗?

    最近 xff0c 我的一篇文章 现在学Java的人都是傻子 引起了一些网友讨论 xff0c 都在说现在学Java过时了 xff0c Java市场趋于饱和了 xff0c 应该弃学Java xff0c xff0c 难道Java编程真的过时了 x
  • 什么是用户态和内核态?用户态和内核态是如何切换的?

    3 什么是用户态和内核态 xff1f 用户态和内核态是操作系统的两种运行状态 xff0c 操作系统主要是为了对访问能力进行限制 xff0c 用户态的权限较低 xff0c 而内核态的权限较高 用户态 xff1a 用户态运行的程序只能受限地访问
  • ubuntu安装Clamav

    一 简介 Clam AntiVirus是一个类UNIX系统上使用的反病毒软件包 主要应用于邮件服务器 xff0c 采用多线程后台操作 xff0c 可以自动升级病毒库 ClamAV是一个在命令行下查毒软件 xff0c 因为它不将杀毒作为主要功
  • 什么是上下文切换?

    上下文切换指的是内核操作系统的核心在CPU上对进程或者线程进行切换 搞清楚上下文切换需要先搞清楚什么是上下文 CPU在开始执行任务时需要先知道从哪里去加载任务 xff0c 从哪里开始执行 xff0c 上下文的作用就是告诉CPU这些 xff0
  • ubuntu16.04下,ROS+PX4+QGC安装

    ubuntu16 04下 xff0c ROS 43 PX4 43 QGC安装 ROS安装 xff1a 第一步 xff1a ROS安装前准备工作 1 在Ubuntu系统上 xff0c 确认git已经安装 span class token fu
  • TokenEndpoint : Handling Null Pointer Exception

    springboot oauth2 0生成token时报错 详细的日志没有打印出来 需要手动配置log 64 Override public void configure AuthorizationServerEndpointsConfig
  • linux(ubuntu)无法连接网络

    提示 xff1a 版本 xff1a ubuntu16 0 4 问题 xff1a 开机没有网络 xff0c 无法连接网络 xff0c 尝试了很多方法最终才可以 首先查看ifconfig 查看网卡信息 ifconfig 查看ip ip a 查看
  • 八皇后问题

    问题描述 在国际象棋中 xff0c 有一个非常强势的棋子 皇后 xff0c 他的走法可以在网上参考一下 xff0c 概括来说就是可以沿着行 列 与对角线平行的线走 而在计算机中有一个关于他的经典问题 xff0c 8皇后 xff0c 就是在8
  • ubuntu18.04.3如何在终端下切换到指定文件夹或根目录

    看到很多的新手 xff0c 不知道如何在终端切换到根目录的 xff0c 或者是指定的目录的 xff0c 下面介绍一下切换的方法 1 先按键盘 ctrl 43 alt 43 t 弹出终端 xff0c 那么你会看到终端上的提示当前目录为 这个就
  • MySql简单查询——单表查询

    一 DDL xff08 Data Definition Language xff09 xff1a 数据定义语言 xff0c 用来定义数据库对象 xff1a 库 表 列等 xff1b 相关字段 xff1a create drop alter
  • linux下可视化git工具git-cola安装与使用(HTTP方式)

    一 git cola为何物 很多小伙伴 xff0c 特别喜欢使用TortoiseGit xff0c 该软件是做什么的 xff0c 就不用多说吧 奈何 xff0c TortoiseGit只有windows版 xff0c 这让在linux上开发
  • 解决ubuntu下应用程序菜单不在程序的左上角

    测试版本 xff1a ubuntu16 04 问题 xff1a 应用程序菜单不在程序的左上角 xff0c 默认放在了桌面顶部的菜单栏上 如下 xff1a 解决办法 xff1a System Settings gt Appearance gt
  • linux下可视化git工具git-cola安装与使用(SSH方式)

    一 git cola为何物 很多小伙伴 xff0c 特别喜欢使用TortoiseGit xff0c 该软件是做什么的 xff0c 就不用多说吧 奈何 xff0c TortoiseGit只有windows版 xff0c 这让在linux上开发
  • CAS实现SSO单点登录原理

    yale cas可以百度一下 xff0c 这是学习cas后的一点总结 xff0c 以备日后使用 xff01 安全性 xff1a 用户只须在cas录入用户名和密码 xff0c 之后通过ticket绑定用户 xff0c 在cas客户端与cas校
  • 五种知网文献免费下载方式

    1 idata中国知网 网址 xff1a idata中国知网 进入系统 xff0c 注册账号 xff0c 登录即可 每天五篇额度 xff0c 基本够用 xff0c 可注册多个账号使用 2 上海研发公共服务平台 网址 xff1a 上海研发公共
  • 【FreeRTOS】二值信号量实现线程的同步

    FreeRTOS 二值信号量实现线程的同步 测试环境如下 stm32L431RCT6 MDK keil5 stm32cube 43 FreeRTOS 一 添加多个任务 1 引脚配置 LED使用的引脚PA8和PB2设置成output 将按键引