FreeRTOS开发笔记

来源:互联网 发布:淘宝二手网在哪里 编辑:程序博客网 时间:2024/06/05 15:49

目录

  • 目录
    • 系统节拍时钟
    • 系统如何实现低功耗管理
      • 参考
      • 实现
      • 设计思路
    • 系统如何管理中断优先级
    • 系统如何线程调度
    • 系统如何内存管理
      • 主堆栈MSP
      • 从堆栈PSP
      • 重载内存动态分配和释放
      • 任务栈大小的确定
    • 系统如何获取线程信息
    • project


系统节拍时钟

  • 时钟滴答

   心跳tick,时钟心跳的周期性中断用于,在每个时间片的结束时刻运行调度器,从而选择下一个要运行的线程。

  • 频率设置

    FreeRTOSConfig.h宏定义configSYSTICK_CLOCK_HZ。

  • 硬件配置

   在预设值低功耗模式下还能运行的硬件定时器作为时钟来源。


系统如何实现低功耗管理

参考

    http://www.tuicool.com/articles/EbIbYzn

实现

   OS的低功耗,一种是靠idle任务,一种是用户适当停止当前任务。

  1. idle

   FreeRTOSConfig.h宏定义configUSE_IDLE_HOOK配置为1。

  1. tickless

    系统是基于SysTick来运作的,任务调度器可以预期到下一个周期性任务的触发时间,但是突发任务却无法预测,要用户有自己的中断来触发唤醒,调整SysTick中断触发时间,可以少进入几次中断,少唤醒几次,也就是Tick less,从而更长的时间停留在低功耗模式中,这时候SysTick的RELOAD是变化的。

    此时,MCU可能被两种不同的情况唤醒,动态调整过的系统时钟中断或者突发性的外部事件,无论是哪一种情况,都可以通过运行在低功耗模式下的某种定时器来计算出 MCU 处于低功耗模式下的时间,这样在MCU唤醒后对系统时间进行软件补偿,不至于系统的一些时间周期错误,比如vTaskDelay可能因此误以为足够延迟等等。

    FreeRTOSConfig.h宏定义configUSE_TICKLESS_IDLE配置为1。

设计思路

    需要考虑问题,一种是系统由运行态进入到tickless模式,一种是系统由tickless模式唤醒。

    提供一种设计思路:创建一个功耗管理线程manager_thread,该线程优先级priority建议比空闲任务线程idle thread优先级高1级。需要实现以下功能:

1)不能运行在低功耗模式下外设,需要等待到空闲状态,才能睡眠,最后让系统自然地由运行态进入到tickless模式;

2)外部中断源唤醒tickless模式下的系统后,所有应用层线程在运行态时需要判断manager_thread是否被唤醒,如果睡眠需要通过特定信号量将其唤醒,并运行逻辑A


系统如何管理中断优先级

  • 参考

    http://blog.sina.com.cn/s/blog_7fbb077f0102wrb1.html

  • Kernel 级别:

    宏定义configKERNEL_INTERRUPT_PRIORITY

  • Syscall级别:

    宏定义configMAX_SYSCALL_INTERRUPT_PRIORITY

  • 系统可管理的中断优先级Syscall~Kernel,能够调用_ISR后缀名的API函数,不会被内核延迟并且可嵌套。

系统如何线程调度

  • 线程优先级

    可管理的线程最高优先级宏定义configMAX_PRIORITIES

  • 线程状态

    阻塞、挂起、就绪、运行

    特别指出,线程可以在阻塞状态等待一个事件,当事件发生时其将自动回到就绪态。事件有时间事件和同步事件。

    时间事件发生在某个特定的时刻,比如阻塞超时。时间事件通常用于周期性或超时行为。

    任务或中断服务例程往队列发送消息或发送任务一种信号量,都将触发同步事件。同步事件通常用于触发同步行为,比如某个外围的数据到达了。

  • 线程调度原则

    优先级抢占式调度,调度器总是在所有处于就绪态的线程中选择具有最高优先级的线程来执行。


系统如何内存管理

主堆栈MSP

  1. 内存大小:

    .s汇编启动代码定义Heap_Size堆大小和Stack_Size栈大小

  1. 分配方式:

   
microlib c库中实现了malloc和free

  1. 使用情景:

1) MCU上电复位启动之后,到系统调度器运行之前的所有内存来源从MSP分配。

2) MCU所有中断(包括SYSCALL级别以上的中断)处理函数中的内存来源从MSP分配。在这里注意,系统没提供这样一种从PSP分配的api接口。

从堆栈PSP

  1. 内存大小:

   FreeRTOSConfig.h宏定义configTOTAL_HEAP_SIZE

  1. 分配方式:

   FreeRTOS官方提供的heap实现了pvPortMalloc和vPortFree

  1. 使用情景:

   系统所有线程的内存来源从PSP分配。

重载内存动态分配和释放

  1. 提供一种设计思路:

1)malloc_overwrite可通过上下文的中断向量号来判断当前是否处于中断处理函数中。如果是在中断里,直接调用malloc(在这里,需要考虑中断抢占问题,先关闭总中断,调用malloc,使能总中断);否则,直接调用已经支持线程安全的pvPortMalloc。

2)free_overwrite可通过判断传入地址是否在系统pvPortMalloc分配的地址范围(&ucHeap[0]~&ucHeap[configTOTAL_HEAP_SIZE - 1])内。如果不是,则直接调用free(在这里,需要考虑中断抢占问题,先关闭总中断,调用free,使能总中断);否则,直接调用直接调用已经支持线程安全的vPortFree。

任务栈大小的确定

    在基于RTOS的应用设计中,每个任务都需要自己的栈空间,应用不同,每个任务需要的栈大小也是不同的。

    一般来说,用户可以事先给任务分配一个大的栈空间,然后通过第8章介绍的调试方法打印任务栈的使用情况,运行一段时间就会有个大概的范围了。这种方法比较简单且实用些。


系统如何获取线程信息

  • FreeRTOSConfig.h

   宏定义configUSE_TRACE_FACILITY

  • 获取任务总数目

    uxTaskGetNumberOfTasks

  • 获取每个任务的状态信息

   uxTaskGetSystemState

project

https://github.com/RunningChild/efm32_freertos_app

原创粉丝点击