当前位置: 首页 > news >正文

如何在百度做网站湖南手机响应式网站建设企业

如何在百度做网站,湖南手机响应式网站建设企业,网站seo优化综合服务公司哪家好,如何自己设计一个网站1. FreeRTOS 任务调度器:核心概念与机制FreeRTOS 调度器是实时操作系统的核心,负责确定哪个任务在何时获得 CPU 执行权。其设计遵循严格的优先级驱动规则。1.1 调度器类型FreeRTOS 支持三种调度器,通过 FreeRTOSConfig.h 中的宏进行配置&…

1. FreeRTOS 任务调度器:核心概念与机制

FreeRTOS 调度器是实时操作系统的核心,负责确定哪个任务在何时获得 CPU 执行权。其设计遵循严格的优先级驱动规则。

1.1 调度器类型

FreeRTOS 支持三种调度器,通过 FreeRTOSConfig.h 中的宏进行配置:

  1. 抢占式调度器 (Preemptive Scheduler)

    • 机制:这是最常用的模式。调度器始终运行最高优先级的就绪态任务。如果一个比当前运行任务优先级更高的任务进入就绪态,调度器会立即暂停当前任务,切换到更高优先级的任务。

    • 配置:此模式是默认模式,无需特殊配置。

  2. 协作式调度器 (Co-operative Scheduler)

    • 机制:任务调度发生在以下两种情况下:

      • 一个任务显式地调用 taskYIELD()

      • 一个任务进入阻塞状态(例如调用 vTaskDelay()xQueueReceive() 等)。

    • 特点:低优先级任务不会被高优先级任务抢占,除非它主动放弃 CPU。这能提供更可预测的执行流程,但实时性较差。

    • 配置:在 FreeRTOSConfig.h 中定义 configUSE_PREEMPTION 为 0

  3. 带时间片的抢占式调度器 (Preemptive with Time Slicing)

    • 机制:在抢占式调度的基础上,为相同优先级的任务引入时间片概念。多个相同优先级的任务将以时间片为单位共享 CPU 时间。

    • 时间片:长度由系统心跳中断 (configTICK_RATE_HZ) 定义。例如,如果 configTICK_RATE_HZ 为 1000 (1kHz),则一个时间片为 1ms。

    • 行为:调度器在每个 tick 中断 (xPortSysTickHandler) 中检查是否需要进行任务切换。如果当前任务的时间片用完,并且存在相同优先级的就绪任务,则会触发一次上下文切换。

    • 配置:这是默认行为。确保 configUSE_PREEMPTION 和 configUSE_TIME_SLICING 均为 1

1.2 任务状态

一个任务在任何时刻都处于以下状态之一:

  • 运行态 (Running):任务正在 CPU 上执行。

  • 就绪态 (Ready):任务已准备就绪,可以运行,但有一个更高或同等优先级的任务正在运行。

  • 阻塞态 (Blocked):任务正在等待某个事件(如定时器到期、队列数据、信号量、通知等)。任务在阻塞状态下不消耗 CPU 时间。

  • 挂起态 (Suspended):任务被显式地挂起(vTaskSuspend())。它无法进入就绪态,直到被显式恢复(vTaskResume())。它不参与调度。


2. 任务管理相关函数详解

2.1 任务创建 (xTaskCreate / xTaskCreateStatic)

c

BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,        // 任务函数指针const char * const pcName,        // 任务描述名(用于调试)configSTACK_DEPTH_TYPE usStackDepth, // 任务堆栈深度(字数,非字节)void *pvParameters,               // 传递给任务函数的参数UBaseType_t uxPriority,           // 任务优先级 (0 to configMAX_PRIORITIES-1)TaskHandle_t *pxCreatedTask );    // 可选的用于传递任务句柄的指针
  • 堆栈深度:需要根据函数调用深度和局部变量大小谨慎设置。可通过 uxTaskGetStackHighWaterMark() 函数监控堆栈使用峰值。

  • 优先级:数值越高,优先级越高。configMAX_PRIORITIES 在 FreeRTOSConfig.h 中定义,最大允许值为 32(受架构限制)。

  • 返回值pdPASS 表示成功,errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY 表示堆栈空间分配失败。

2.2 任务删除 (vTaskDelete)

c

void vTaskDelete( TaskHandle_t xTaskToDelete );
  • 可以删除其他任务或自身(参数传 NULL)。

  • 被删除的任务的资源(堆栈、TCB)由空闲任务 (Idle Task) 负责回收。因此,删除大量任务时需确保空闲任务有执行时间。

2.3 任务延时 (vTaskDelay / vTaskDelayUntil)

c

void vTaskDelay( const TickType_t xTicksToDelay ); // 相对延时void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, // 指向一个变量,用于存储任务上次解除阻塞的时间const TickType_t xTimeIncrement ); // 固定的周期时间
  • vTaskDelay相对延时。调用该函数后,任务阻塞 xTicksToDelay 个 tick。不适用于精确定时,因为从任务就绪到再次被调度执行存在不确定性。

  • vTaskDelayUntil绝对延时。用于实现固定频率的周期性任务。它能补偿任务本身执行时间带来的误差,是更精确的选择。

2.4 优先级控制

c

void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask );
  • 可用于动态改变任务的优先级,实现诸如优先级继承协议 (Priority Inheritance Protocol) 或其他复杂调度策略。

2.5 任务挂起与恢复 (vTaskSuspend / vTaskResume)

c

void vTaskSuspend( TaskHandle_t xTaskToSuspend );
void vTaskResume( TaskHandle_t xTaskToResume );
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ); // 从中断中恢复
  • vTaskSuspend() 和 vTaskResume() 必须成对使用。

  • xTaskResumeFromISR() 专为中断服务程序设计,其返回值 pdTRUE 表示恢复的任务优先级更高,可能需要在中断退出前请求一次上下文切换(portYIELD_FROM_ISR())。


3. 内核实践与高级主题

3.1 空闲任务 (Idle Task) 与空闲钩子 (Idle Hook)

  • 空闲任务是在没有其他任务运行时自动运行的优先级为 0 的任务。

  • 可以定义一个 vApplicationIdleHook() 函数(需在 FreeRTOSConfig.h 中使能 configUSE_IDLE_HOOK)来让内核在空闲任务中执行后台功能,如低功耗处理(调用 WFI 指令)。

  • 警告:空闲钩子函数绝不能阻塞或挂起。

3.2 Tickless 低功耗模式

  • 在应用场景中,当系统空闲时,可以通过关闭 SysTick 中断来让 MCU 进入深度睡眠,显著降低功耗。

  • 通过配置 configUSE_TICKLESS_IDLE 为 1 或 2 来启用。需要根据具体 MCU 实现 portSUPPRESS_TICKS_AND_SLEEP() 函数。

3.3 调度器锁定 (vTaskSuspendAll / xTaskResumeAll)

  • 调用 vTaskSuspendAll() 可以临时挂起调度器,禁止任务切换,但中断仍然使能。

  • 调用 xTaskResumeAll() 恢复调度器。如果恢复过程中有更高优先级的任务就绪,会立即触发一次切换。

  • 用于保护非线程安全的代码段或执行精密的时序操作。应尽量缩短锁定时间


4. 综合应用实例:多任务系统与精确计时

以下实例创建了三个任务:一个高优先级任务,两个相同优先级的周期性任务。

c

#include <FreeRTOS.h>
#include <task.h>
#include <stdio.h>// 任务句柄
TaskHandle_t xPeriodicTaskHandle1, xPeriodicTaskHandle2;// 高优先级任务
void vHighPriorityTask(void *pvParameters) {while(1) {printf("[HP Task] Running...\n");vTaskDelay( pdMS_TO_TICKS(500) ); // 每500ms执行一次}
}// 周期性任务1 (使用 vTaskDelayUntil)
void vPeriodicTask1(void *pvParameters) {TickType_t xLastWakeTime;const TickType_t xFrequency = pdMS_TO_TICKS(1000); // 周期1000msxLastWakeTime = xTaskGetTickCount(); // 初始化基准时间while(1) {printf("[Task1] Tick at %lu\n", xTaskGetTickCount());// 绝对延时,精确保证1000ms周期vTaskDelayUntil(&xLastWakeTime, xFrequency);}
}// 周期性任务2 (使用 vTaskDelay)
void vPeriodicTask2(void *pvParameters) {while(1) {printf("[Task2] Tick at %lu\n", xTaskGetTickCount());vTaskDelay( pdMS_TO_TICKS(1000) ); // 相对延时1000ms}
}void main(void) {// 创建高优先级任务xTaskCreate(vHighPriorityTask, "HP Task", 1024, NULL, 3, NULL);// 创建两个相同优先级的周期性任务xTaskCreate(vPeriodicTask1, "Periodic1", 1024, NULL, 2, &xPeriodicTaskHandle1);xTaskCreate(vPeriodicTask2, "Periodic2", 1024, NULL, 2, &xPeriodicTaskHandle2);// 启动调度器vTaskStartScheduler();// 如果调度器启动成功,不会运行到这里while(1);
}

运行分析与预期输出

  1. 高优先级任务(优先级3)将抢占两个周期性任务(优先级2)。

  2. 每500ms,高优先级任务会运行一次,打印消息。

  3. 在两个周期性任务中:

    • Task1 使用 vTaskDelayUntil,其打印间隔会非常稳定地接近 1000ms,因为它补偿了执行和调度延迟。

    • Task2 使用 vTaskDelay,其打印间隔会是 1000ms + 执行延迟 + 被高优先级任务抢占的时间,因此间隔会长于且不稳定

  4. 当 Task1 和 Task2 同时就绪时,由于优先级相同,它们将共享时间片,你会在一个大概的 1000ms 周期内看到两条打印信息交错出现。

http://www.dtcms.com/a/436669.html

相关文章:

  • 初学者拟建网站平台制作专业网站制作
  • 力网站票网站开发福州高端品牌网站建设
  • 高质量的合肥网站建设织梦如何一个后台做两个网站
  • 扁平化高端网站模板编程开发工具大全
  • 织梦cms如何搭建网站国外网站视觉设计趋势
  • 手机网站导航条公众平台推广
  • 如何设定网站关键词快速搭建论坛
  • 专业平台建设网站关了吗蝌蚪窝一个释放做网站
  • 南昌专业制作网站设计织梦网站搭建
  • 网站的排版包括什么学seo需要多久
  • 提供网站备案信息文库网站开发教程
  • 【RocketMQ 生产者和消费者】- 延时消息的使用
  • 做网站一般用什么字体网站建设实例教程 pdf
  • 网站功能建设模块做一个网站怎么做
  • 专业的国内网站建设公司胶州建网站
  • 做的好的淘宝客网站网站建设的技能有哪些方面
  • 贷款网站模版wordpress 如何迁移
  • 蒙文网站建设情况汇报网站建设网址导航网
  • 网络教育做的好的网站举一个网络营销的例子
  • dede网站怎么做单页面网络营销的具体措施
  • 微信无法分享wordpress广元网站建设优化
  • 设计网站公司哪里好厦门 网站建设公司
  • 深圳做网站多少费用市场推广工作内容
  • 淘客怎么样做网站网页版传奇合击版
  • 青岛做网站多少钱wordpress文章分类统计
  • 网站开发及推广是怎么回事沈阳网络教育
  • win2008怎么做网站wordpress 外部链接跳转
  • 移动网站开发语言河源市做网站
  • 建站开发公司网站域名如何申请
  • 网站建设平台市场泰安网站建设哪家专业