FreeRTOS系列|低功耗管理

2023-05-16

低功耗管理

很多应用场合对于空耗的要求很严格,比如可穿戴低功耗产品、物联网低功耗产品等。一般MCU都有相应的低功耗模式,裸机开发时可以使用MCU的低功耗模式。FreeRTOS也提供了一个叫Tickless的低功耗模式,方便带FreeRTOS操作系统的应用开发

1. 低功耗管理介绍

1.1 STM32低功耗模式

STM32本身就支持低功耗模式,以STM32F1为例,其有三种低功耗模式:睡眠(Sleep)模式停止(Stop)模式待机(Standby)模式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
三种模式的对比如下图示:
在这里插入图片描述

STM32的电源管理系统主要分为以下三个部分:1为备份域;2为调压器供电电路;3为ADC电源电路

在这里插入图片描述

1.2 FreeRTOS Tickless低功耗模式

简单应用中处理器大量的时间都在处理空闲任务,所以可以考虑当处理器处理空闲任务时进入低功耗模式,当需要处理应用层代码时再将处理器从低功耗模式唤醒。一般采用基于时间片轮转的抢占式任务调度机制的低功耗设计思路为:当idle任务运行时,进入低功耗模式;在适当的条件下,通过中断或外部事件唤醒MCU

但是该设计的缺陷是每当OS系统定时器产生中断时,也会将MCU从低功耗模式中唤醒,而频繁的进入/唤醒低功耗模式使得MCU无法进入深度睡眠,对于低功耗设计而言是不合理的。FreeRTOS中设计的低功耗模式------Tickless Idle Mode,可以让MCU更长时间的处于低功耗模式

在这里插入图片描述
Tickless Idle Mode的设计思想在于尽可能的在MCU空闲时使其进入低功耗模式,因此需要解决以下问题:

  • 合理的进入低功耗模式,避免频繁使MCU在低功耗和运行模式下进行不必要的切换。RTOS的系统时钟源于硬件的某个周期性定时器(Cotex-M内核多数采用SysTick),RTOS的任务调度器可以预期到下一个周期性任务(或定时器任务)的触发时间,从而调整系统时钟定时器中断触发时间,以避免RTOS进入不必要的时间中断,从而更长时间停留在低功耗模式中。此时RTOS的时钟不再是周期的而是动态的(在原有的时钟基准时将不再产生中断,即Tickless)
  • 当MCU被唤醒时,通过某种方式为系统时钟提供补偿。MCU可能被动态调整过的系统时钟中断或突发性的外部事件所唤醒,都可以通过运行在低功耗模式下的某种定时器来计算出MCU处于低功耗模式下的时间,在MCU唤醒后对系统时间进行软件补偿
  • 软件实现时,根据具体的应用情景和MCU低功耗特性来处理问题。尤其是MCU的低功耗特性,不同MCU处于不同的低功耗模式下所能使用的外设(主要是定时器)是不同的,RTOS的系统时钟可以进行适当的调整

2. Tickless低功耗模式实现

2.1 宏 configUSE_TICKLESS_IDLE

要想使用Tickless模式,必须将FreeRTOSConfig.h中的如下宏置1;FreeRTOS只提供了个别的硬件平台模式,STM32采用模式1即可,如果采用其他模式,配置为2

#define configUSE_TICKLESS_IDLE		1	//启用低功耗Tickless模式
2.2 宏 portSUPPRESS_TICKS_AND_SLEEP

使能了Tickless模式后,当空闲任务是唯一可运行的任务(其他任务都处于阻塞或挂起态)以及系统处于低功耗模式的时间大于configEXPECTED_IDLE_TIME_BEFORE_SLEEP个时钟节拍时,FreeRTOS内核就会调用宏portSUPPRESS_TICKS_AND_SLEEP来处理低功耗相关的工作

#ifndef portSUPPRESS_TICKS_AND_SLEEP		\
extern void vPortSuppressTicksAndSleep(TickType_t  xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) 	\
vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif
//参数 xExpectedIdleTime 表示处理器将要在低功耗模式运行的时长

函数 vPortSuppressTicksAndSleep 是实际的低功耗执行代码,本来需要用户自己实现,但是针对STM32平台,FreeRTOS已经帮我们实现了,其源码如下示

__weak void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime){
  uint32_t ulReloadValue,ulCompleteTickPeriods,ulCompletedSysTickDecrements, ulSysTickCTRL;
  TickType_t xModifiableIdleTime;
  /* 判断系统最小时间片(systick定时器的Reload值)是否大于systick的最大装载周期 */
  if( xExpectedIdleTime > xMaximumPossibleSuppressedTicks ){
	/* MCU在低功耗模式运行的时长 */
	xExpectedIdleTime = xMaximumPossibleSuppressedTicks;
  }
  /* 关闭systick定时器 */
  portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT;
  /* systick重载值= 当前的systick计数值+单次系统tick装载值*(系统最小时间片-1)*/
  ulReloadValue = portNVIC_SYSTICK_CURRENT_VALUE_REG + ( ulTimerCountsForOneTick * ( xExpectedIdleTime - 1UL ) );
  /* 装载值若大于补偿周期,则要减去补偿周期 */
  if( ulReloadValue > ulStoppedTimerCompensation ){
	ulReloadValue -= ulStoppedTimerCompensation;
  }
  /* 关闭中断,虽然关闭了中断,但可以唤醒CPU,不进行中断处理	*/
  __disable_irq();
  __dsb( portSY_FULL_READ_WRITE );
  __isb( portSY_FULL_READ_WRITE );
  /* 是否有其他任务,进入了就绪态 */
  if( eTaskConfirmSleepModeStatus() == eAbortSleep ){
	/* 不能进入低功耗模式,并将当前的systick计数值放到systick装载寄存器中 */
	portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG;
	/* 重新启动systick */
	portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
	/* 重新赋值装载寄存器值为一个系统的tick周期. */
	portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
	/* 开启中断 */
	__enable_irq();
  }
  else{
	/* 可以进入低功耗模式,装载休眠systick装载值 */
	portNVIC_SYSTICK_LOAD_REG = ulReloadValue;
	/* 清除systick当前计数值 */
	portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
	/* 启动systick定时器*/
	portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
	xModifiableIdleTime = xExpectedIdleTime;
	/* 进入低功耗前要处理的事情,需要用户实现休眠处理,以进一步降低功耗 */
	configPRE_SLEEP_PROCESSING( &xModifiableIdleTime );
	if( xModifiableIdleTime > 0 ){
      /* 让CPU休眠 */
	  __dsb( portSY_FULL_READ_WRITE );
	  __wfi();
	  __isb( portSY_FULL_READ_WRITE );
	}
	/* 退出低功耗后要处理的事情,需要用户实现 */
	configPOST_SLEEP_PROCESSING( &xExpectedIdleTime );
	/* 停止systick定时器 */
	ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;
	portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );
	/* 使能中断 */
	__enable_irq();
	/* 判断是由外部中断还是systick定时器计时时间到唤醒的 */
	if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 ){//systick唤醒的
      uint32_t ulCalculatedLoadValue;
      /*systick恢复值= 单个tick周期值- (休眠装载值-当前systick计数值)*/
	  ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
      /* 保护处理:装载值很小或大,都赋值为1个tick周期 */
	  if( ( ulCalculatedLoadValue < ulStoppedTimerCompensation ) || ( ulCalculatedLoadValue > ulTimerCountsForOneTick ) ){
		ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL );
	  }
	  /* 装载恢复systick装载值 */
	  portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
      /* 休眠周期的补偿值,单位为tick */
	  ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
	}
	else{//外部中断唤醒的,需进行时间补偿
	  /* 休眠运行装载值= 休眠装载值-当前systick计数值)*/
	  ulCompletedSysTickDecrements = ( xExpectedIdleTime * ulTimerCountsForOneTick ) - portNVIC_SYSTICK_CURRENT_VALUE_REG;
      /* 休眠运行周期,单位为tick值 */
	  ulCompleteTickPeriods = ulCompletedSysTickDecrements / ulTimerCountsForOneTick;
      /* 装载恢复systick装载值 */
	  portNVIC_SYSTICK_LOAD_REG = ( ( ulCompleteTickPeriods + 1UL ) * ulTimerCountsForOneTick ) - ulCompletedSysTickDecrements;
	}
	/* 清除systick计数值,重启systick定时器,恢复systick周期为1个tick值 */
	portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
	portENTER_CRITICAL();
	{
	  portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
	  vTaskStepTick( ulCompleteTickPeriods );//补偿系统时钟
	  portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
	}
	portEXIT_CRITICAL();
  }
}
2.3 宏 configPRE_SLEEP_PROCESSING() 和 configPOST_SLEEP_PROCESSING()

在低功耗设计中不仅是将处理器设置到低功耗模式就行了,有时还需要做一些其他处理,比如将处理器降低到合适的频率、修改时钟源(切换到内部时钟源)、关闭外设时钟以及关闭其他功能模块电源等

#if configUSE_TICKLESS_IDLE == 1 
#define configPRE_SLEEP_PROCESSING   PreSleepProcessing//进入低功耗前要处理的事情
#define configPOST_SLEEP_PROCESSING  PostSleepProcessing//退出低功耗后要处理的事情
#endif /* configUSE_TICKLESS_IDLE == 1 */

弱符号函数PreSleepProcessing和PostSleepProcessing需要用户自已根据需要编写

2.4 宏configEXPECTED_IDLE_TIME_BEFORE_SLEEP

处理器工作在低功耗模式的时间没有任何限制,可以等于1个时钟节拍,但是时间太短的话就没有意义,比如1个时钟节拍,刚进入低功耗模式就要退出低功耗模式。因此需要对工作在低功耗模式的时间加一个限制,宏configEXPECTED_IDLE_TIME_BEFORE_SLEEP就是用来完成此功能的

默认情况下此宏设置为2个时钟节拍,且最小不能小于2个时钟节拍

#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP
	#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP	2
#endif
#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2
	#error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2
#endif

3. Tickless低功耗模式实例

本实例介绍如何使用FreeRTOS的低功耗Tickless模式。本例程是在二值信号量例程的基础上增加了低功耗模式

使用STM32CubeMX将FreeRTOS移植到工程中,创建两个任务、一个二值信号量,开启串口中断。

LED_Task:闪烁LED1,提示系统运行正常
CMDprocess_Task:根据串口收到的指令,控制不同的LED2/LED3的亮灭
二值信号量:用于串口中断和CMDprocess_Task任务间的同步

3.1 STM32CubeMX设置
  • RCC设置外接HSE,时钟设置为72M
  • PC0/PC1/PC2设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平
  • USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位;开启串口中断
  • 激活FreeRTOS,添加任务,设置任务名称、优先级、堆栈大小、函数名称等参数

在这里插入图片描述

  • 动态创建二值信号量

在这里插入图片描述

  • 启用低功耗Tickless模式

在这里插入图片描述

  • 使用FreeRTOS操作系统,需要将HAL库的Timebase Source从SysTick改为其他定时器,选好定时器后,系统会自动配置TIM
  • 输入工程名,选择路径(不要有中文),选择MDK-ARM V5;勾选Generated periphera initialization as a pair of ‘.c/.h’ files per IP ;点击GENERATE CODE,生成工程代码
3.2 MDK-ARM软件编程
  • 添加低功耗相关函数
__weak void PreSleepProcessing(uint32_t *ulExpectedIdleTime){
  __HAL_RCC_GPIOB_CLK_DISABLE(); 
  __HAL_RCC_GPIOC_CLK_DISABLE();  
  __HAL_RCC_GPIOD_CLK_DISABLE();  
  __HAL_RCC_GPIOE_CLK_DISABLE();  
  __HAL_RCC_GPIOF_CLK_DISABLE();
  __HAL_RCC_GPIOG_CLK_DISABLE();
}
__weak void PostSleepProcessing(uint32_t *ulExpectedIdleTime){
  __HAL_RCC_GPIOB_CLK_ENABLE(); 
  __HAL_RCC_GPIOC_CLK_ENABLE();  
  __HAL_RCC_GPIOD_CLK_ENABLE();  
  __HAL_RCC_GPIOE_CLK_ENABLE();  
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOG_CLK_ENABLE();
}
  • 添加LEDTask、CMDprocessTask任务函数代码
/******************LEDTask**************************/
void LEDTask(void const * argument){
  for(;;){
	HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);
    osDelay(500);
  }
}
/******************CMDprocessTask*******************/
void CMDprocessTask(void const * argument){
  BaseType_t err = pdFALSE;
  for(;;){
    if(BinarySemHandle != 0){
	  err = xSemaphoreTake(BinarySemHandle,portMAX_DELAY);
	  if(err == pdPASS){
		printf("CMDprocessTask take the binary Semaphore!\r\n");
		printf("Received CMD is:");
		for(int i =0;i<8;i++)
		  printf("%c",RxBuff[i]);
		printf("\n");
				
		if(strncmp((char *)RxBuff,"LED2on",6) == 0)
		  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_RESET);		
		else if(strncmp((char *)RxBuff,"LED2off",6) == 0)
		  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET);	
		else if(strncmp((char *)RxBuff,"LED3on",6) == 0)
		  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_RESET);	
		else if(strncmp((char *)RxBuff,"LED3off",6) == 0)
		  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_SET);	
		else
		  printf("invalid CMD,please input LED2on LED2off LED3on or LED3off\r\n");
				
	  }
	  else
		osDelay(10);
	}
  }
}
  • 添加串口中断回调函数:串口接收完命令后释放二值信号量
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){  
  RxBuff[Rx_Count++]=RxByte;	
  if((RxByte==0x0A)&&(BinarySemHandle!=0)){
	xSemaphoreGiveFromISR(BinarySemHandle,NULL);	
	printf("Semaphore Give FromISR succesed!\r\n");
	Rx_Count=0;
  }
	
  if(Rx_Count > 8){
	printf("Wrong CMD, Please Check...!\r\n");
	memset(RxBuff,0,sizeof(RxBuff));
	Rx_Count=0;
  }	
  while(HAL_UART_Receive_IT(&huart1,&RxByte,1)==HAL_OK);
}
  • 在main.c中开启串口接收中断
int main(void){
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  printf("BinarySemaphore test....\r\n");
  if(HAL_OK == HAL_UART_Receive_IT(&huart1,&RxByte,1))
	printf("UART_Receive_IT successed!\r\n");
  else 
	printf("UART_Receive_IT failed!\r\n");
  /* USER CODE END 2 */
  MX_FREERTOS_Init(); 
  osKernelStart();
  while (1)
  {
  }
}
3.3 下载验证

编译无误下载到开发板后,打开串口调试助手,通过串口命令可以控制LED2/LED3的亮灭

使用USB电流计可以观察到开启了Tickless模式后,系统的工作电流会有所降低

在这里插入图片描述

关注我的公众号,在公众号里发如下消息,即可获取相应的工程源代码:

FreeRTOS低功耗管理实例

在这里插入图片描述

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

FreeRTOS系列|低功耗管理 的相关文章

  • FreeRTOS系列

    1 多任务系统 1 1 前后台系统 单片机裸机开发时 一般都是在main函数里面用while 1 做一个大循环来完成所有的处理 循环中调用相应的函数完成所需的处理 有时也需要在中断中完成一些处理 相对于多任务系统而言 这就是单人单任务系统也
  • 详解FreeRTOS中的软件定时器

    软件定时器用于让某个任务定时执行 或者周期性执行 比如设定某个时间后执行某个函数 或者每隔一段时间执行某个函数 由软件定时器执行的函数称为软件定时器的回调函数 参考资料 Mastering the FreeRTOS Real Time Ke
  • STM32CubeMX+FreeRTOS学习笔记(一)

    嵌入式实时操作系统FreeRTOS 基本概述 在嵌入式领域当中 实时操作系统的应用越来越广泛了 目前嵌入式操作系统种类很多 例如 Clinux C OS II C OS III FreeRTOS RT Thread等等 这篇文章所记录的就是
  • FreeRTOS-内核控制函数

    FreeRTOS 内核控制函数 FreeRTOS中有一些内核函数 一般来说这些内核函数在应用层不会使用 但是内核控制函数是理解FreeRTOS中断的基础 接下来我们逐一分析这些内核函数 taskYIELD 该函数的作用是进行任务切换 这是一
  • 解决错误“ #error “include FreeRTOS.h“ must appear in source files before “include event_groups.““例子分享

    今天来给大家分享一下 关于之前自己在学习FreeRTOS过程中遇到的一个错误提示 话不多说 我们直接来看 错误分析 首先 我们看一下错误的提示 error 35 error directive include FreeRTOS h must
  • FreeRTOS ------- 任务(task)

    在学习RTOS的时候 个人觉得带着问题去学习 会了解到更多 1 什么是任务 在FreeRTOS中 每个执行线程都被称为 任务 每个任务都是在自己权限范围内的一个小程序 其具有程序入口每个任务都是在自己权限范围内的一个小程序 其具有程序入口通
  • FreeRTOS记录(九、一个裸机工程转FreeRTOS的实例)

    记录一下一个实际项目由裸机程序改成FreeRTOS 以前产品的平台还是C8051单片机上面的程序 硬件平台改成了STM32L051 同时使用STM32CubeMX生成的工程 使用FreeRTOS系统 EEPROM数据存储读取函数修改更新 2
  • freeRTOS使用uxTaskGetStackHighWaterMark函数查看任务堆栈空间的使用情况

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

    目录 一 Cortex M 中断 1 1中断简介 1 2中断管理简介 1 3优先级分组定义 1 4优先级设置 1 5用于中断屏蔽的特殊寄存器 1 5 1PRIMASK 和 FAULTMASK 寄存器 1 5 2BASEPRI 寄存器 二 F
  • FreeRTOS临界段和开关中断

    http blog sina com cn s blog 98ee3a930102wg5u html 本章教程为大家讲解两个重要的概念 FreeRTOS的临界段和开关中断 本章教程配套的例子含Cortex M3内核的STM32F103和Co
  • FreeRTOS基础五:软件定时器

    软件定时器简介 软件定时器的作用 在指定的时间到来时执行指定的函数 或者以某个频率周期性地执行某个函数 被执行的函数叫做软件定时器回调函数 软件定时器由FreeRTOS内核实现 不需要硬件支持 软件定时器只有在软件定时器回调函数被调用时才需
  • stm32f103zet6移植标准库的sdio驱动

    sdio移植 st官网给的标准库有给一个用于st出的评估板的sdio外设实现 但一是文件结构有点复杂 二是相比于国内正点原子和野火的板子也有点不同 因此还是需要移植下才能使用 当然也可以直接使用正点原子或野火提供的实例 但为了熟悉下sdio
  • Arduino IDE将FreeRTOS用于STM32

    介绍 适用于STM32F103C8的FreeRTOS STM32F103C是一种能够使用FreeRTOS的ARM Cortex M3处理器 我们直接在Arduino IDE中开始使用STM32F103C8的FreeRTOS 我们也可以使用K
  • 【FreeRTOS 事件】任务通知事件

    普通任务通知事件创建创建及运行 参阅安富莱电子demo define BIT 0 1 lt lt 0 define BIT 1 1 lt lt 1 static TaskHandle t xHandleTaskUserIF NULL sta
  • 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
  • FreeRTOS之系统配置

    1 FreeRTOS的系统配置文件为FreeRTOSConfig h 在此配置文件中可以完成FreeRTOS的裁剪和配置 在官方的demo中 每个工程都有一个该文件 2 先说一下 INCLUDE 开始的宏 使用 INCLUDE 开头的宏用来
  • C++ freeRTOS任务,非静态成员函数的无效使用

    哪里有问题 void MyClass task void pvParameter while 1 this gt update void MyClass startTask xTaskCreate this gt task Task 204
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

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

随机推荐

  • Windows下执行Linux命令

    常用的工具 Cygwin xff08 http www cygwin com xff09 Cygwin是一个在windows平台上运行的类UNIX模拟环境 xff0c 详细参见百度百科 xff1a https baike baidu com
  • Linux网络编程 - 多线程服务器端的实现(1)

    引言 本来 xff0c 线程在 Windows 中的应用比在 Linux 平台中的应用更广泛 但 Web 服务的发展迫使 UNIX 系列的操作系统开始重视线程 由于 Web 服务器端协议本身具有的特点 xff0c 经常需要同时向多个客户端提
  • 访问带有用户名、密码保护的 URL

    一 URL xff0c 统一资源定位器 指向互联网上的 资源 xff0c 可协议名 主机 端口和资源组成 如 http username password 64 host 8080 directory file query ref Comp
  • 【RT-Thread】STM32F1片内Flash实现Bootloader

    目录 前言1 开发环境搭建2 Bootloader制作3 APP程序制作4 OTA固件打包5 Ymodem升级小结 前言 RT Thread官网对于Bootloader的实现方案有非常详细的描述 xff0c 目前支持F1 F4 L4系列单片
  • SDVOE和传统矩阵的区别

    SDVOE最显著的特点 xff1a 分辨率高 xff0c 最高支持4KP60 4 4 4 图像质量好 xff0c 完全可以达到无压缩效果延时小 xff0c Genlock模式下4K30延时只有不到0 1ms xff0c 链路上嵌入千兆网络
  • GD32的DMA配置

    参考 GD32F4xx 用户手册 DMA 控制器由 4 部分组成 xff1a AHB 从接口配置 DMA xff1b 两个 AHB 主接口进行数据传输 xff1b 两个仲裁器进行 DMA 请求的优先级管理 xff1b 数据处理和计数 DMA
  • nuttx杂记

    1 设置自启动应用 修改deconfig文件下的 CONFIG INIT ENTRYPOINT 参数即可 2 消息队列使用 以下是Nuttx系统中使用queue create函数创建队列的示例代码 xff1a include lt stdi
  • linux下使用jlink 调试 stm32的破事

    安装libusb sudo apt get install libusb 安装readline wget c ftp ftp gnu org gnu readline readline 6 2 tar gz tar zxvf readlin
  • FreeRTOS系列|软件定时器

    软件定时器 MCU一般都自带定时器 xff0c 属于硬件定时器 xff0c 但是不同的MCU其硬件定时器数量不同 xff0c 有时需要考虑成本的问题 在硬件定时器不够用的时候 xff0c FreeRTOS也提供了定时器功能 xff0c 不过
  • 视频芯片选择

    常用的视频芯片记录 HDMI TI ITE Explore Silicon image ADI semtech https www semtech com Realtek MACRO http www mitinc co kr module
  • 眼图里的那些破事

    1 眼图基本概念 1 1 眼图的形成原理 眼图是一系列数字信号在示波器上累积而显示的图形 xff0c 它包含了丰富的信息 xff0c 从眼图上可以观察出码间串扰和噪声的影响 xff0c 体现了数字信号整体的特征 xff0c 从而估计系统优劣
  • IIC的地址

    7位寻址 在7位寻址过程中 xff0c 从机地址在启动信号后的第一个字节开始传输 xff0c 该字节的前7位为从机地址 xff0c 第8位为读写位 xff0c 其中0表示写 xff0c 1表示读 图1 xff1a 7位寻址 I2C总线规范规
  • ODR, BSRR, BRR的差别

    ODR寄存器可读可写 xff1a 既能控制管脚为高电平 xff0c 也能控制管脚为低电平 管脚对于位写1 gpio 管脚为高电平 xff0c 写 0 为低电平 BSRR 只写寄存器 xff1a color 61 Red 既能控制管脚为高电平
  • ACAP究竟是什么

    Xilinx推出Versal系列 xff0c 号称业界首款ACAP xff0c 自适应计算加速平台 ACAP不仅是一个新的处理器 xff0c 而且是新的产品类型 作为率先推出ACAP这样类型产品的公司 xff0c 这也是赛灵思的核心竞争力所
  • ISE 14.7 调试错误笔记

    1 ERROR Pack 2530 The dual data rate register 34 U sys ctl ODDR2 inst 2 34 failed to join an OLOGIC component as require
  • HDMI 4K分辨率 时序

    参考 HDMI1 4标准 High Definition Multimedia Interface Specification 这份文件放在百度网盘共享了 xff0c 上传到文档平台会被封禁 xff0c 如果侵权 xff0c 麻烦联系我删除
  • 深度学习CPU,GPU,NPU,TPU以及其计算能力单位

    处理器运算能力单位 TOPS是Tera Operations Per Second的缩写 xff0c 1TOPS代表处理器每秒钟可进行一万亿次 xff08 10 12 xff09 操作 与此对应的还有GOPS xff08 Giga Oper
  • SSD数据集增强方法

    coding utf 8 import numpy as np import random import cv2 import glob import os import xml etree cElementTree as ET def r
  • 目标检测图像增强

    https blog csdn net wei guo xd article details 74199729 常用的图像扩充方式有 xff1a 水平翻转 xff0c 裁剪 xff0c 视角变换 xff0c jpeg压缩 xff0c 尺度变
  • FreeRTOS系列|低功耗管理

    低功耗管理 很多应用场合对于空耗的要求很严格 xff0c 比如可穿戴低功耗产品 物联网低功耗产品等 一般MCU都有相应的低功耗模式 xff0c 裸机开发时可以使用MCU的低功耗模式 FreeRTOS也提供了一个叫Tickless的低功耗模式