Homepage  

跟踪钩子宏

[FreeRTOS 基础]

说明

引入到 FreeRTOS.org V5.0.0 的跟踪钩子宏功能非常强大,允许你搜集你的嵌入式系统程序行为的数据。

兴趣要点在 FreeRTOS.org 源代码中包含一些程序可以重定义的空白宏,目的是用于验证指定的跟踪设备。系统只需要执行感兴趣的那些宏 - 而没有用到的宏仍然保留为空,不会占用系统时间。

 

例子

下面是使用这些宏的一些例子:

例子 1

FreeRTOS.org 任务标签功能提供了一种简单的机制通过数字或者模拟输出建立记录。例如,标签值可以设置为对于任务是唯一的电压。traceSWITCHED_IN() 宏可以简单定义成与任务切换相关的模拟输出。例如:
    */ First task sets its tag value to 1. */
    void vTask1( void *pvParameters )
    {
        */ This task is going to be represented by a voltage scale of 1. */
        vTaskSetApplicationTaskTag( NULL, ( void * ) 1 );    
    
        for( ;; )
        {
            */ Task code goes here. */
        }
    }
    /*************************************************/
    
    */ Second task sets its tag value to 2. */
    void vTask1( void *pvParameters )
    {
        */ This task is going to be represented by a voltage scale of 2. */
        vTaskSetApplicationTaskTag( NULL, ( void * ) 2 );    
    
        for( ;; )
        {
            */ Task code goes here. */
        }
    }
    /*************************************************/
	    
    */ Define the traceTASK_SWITCHED_IN() macro to output the voltage associated
    with the task being selected to run on port 0. */
    #define traceTASK_SWICTHED_IN() vSetAnalogueOutput( 0, ( int ) pxCurrentTCB->pxTaskTag )

 

例子 2

API 调用记录可以用于记录发生切换的原因。内核调用记录可以用于记录任务执行的顺序。例如:
/* traceBLOCKING_ON_QUEUE_RECEIVE() is just one of the macros that can be used to record why
a context switch is about to occur. */
#define traceBLOCKING_ON_QUEUE_RECEIVE(pxQueue)     \
    ulSwitchReason = reasonBLOCKING_ON_QUEUE_READ;

/* log_event() is an application defined function that logs which tasks ran when, and why. */
#define traceTASK_SWITCHED_OUT()                    \
    log_event( pxCurrentTCB, ulSwitchReason );

 

定义

宏被称为内中断,也特别称作节拍中断,必须被快速执行,而不是使用很多堆栈空间。设置变量,写入跟踪寄存器,或者输出到端口。试图用 fprintf() 记录数据到低速磁盘是无法工作的!

宏定义之前必须包含 FreeRTOS.h 头文件。最早定义跟踪宏的位置是在 FreeRTOSConfig.h 底部,或者在 FreeRTOSConfig.h 底部包含单独一个头文件。

下面的表格描述了可用的宏,宏的参数说明记录关联事件的任务、队列、信号灯或互斥。

宏定义
说明
traceTASK_INCREMENT_TICK()在节拍中断调用。
traceTASK_SWITCHED_OUT()在选择新任务运行前调用。这时 pxCurrentTCB 包含了将脱离运行状态任务的句柄。
traceTASK_SWITCHED_IN()在选择运行任务后运行。这时 pxCurrentTCB 包含了即将进入运行状态任务的局部。
traceBLOCKING_ON_QUEUE_RECEIVE(pxQueue)代表当前运行任务被阻塞因为试图读取空队列,或者试图'获取'空信号或互斥。
traceBLOCKING_ON_QUEUE_SEND(pxQueue)代表当前任务被阻塞因为试图写入一个已经满的队列。
traceGIVE_MUTEX_RECURSIVE(pxMutex)如果队列创建成功在 xSemaphoreGiveRecursive() 中调用。
traceQUEUE_CREATE()在 xQueueCreate() 中调用。
traceQUEUE_CREATE_FAILED()如果队列因为堆内存不足而创建不成功在 xQueueCreate() 中调用。
traceCREATE_MUTEX()如果互斥创建成功在 xSemaphoreCreateMutex() 中调用。
traceCREATE_MUTEX_FAILED()如果互斥因为堆内存不足而创建不成功在 xSemaphoreCreateMutex() 中调用。
traceGIVE_MUTEX_RECURSIVE(pxMutex)如果'获取'互斥成功在 xSemaphoreGiveRecursive() 中调用。
traceGIVE_MUTEX_RECURSIVE_FAILED(pxMutex)如果调用者不是互斥所有者在 xSemaphoreGiveRecursive() 中调用。
traceTAKE_MUTEX_RECURSIVE(pxMutex)在 xQueueTakeMutexRecursive() 中调用。
traceCREATE_COUNTING_SEMAPHORE()如果信号灯创建成功在 xSemaphoreCreateCounting() 中调用。
traceCREATE_COUNTING_SEMAPHORE_FAILED()如果信号灯因为堆内存不足创建不成功时在 xSemaphoreCreateCounting() 中调用。
traceQUEUE_SEND(pxQueue)当队列发送成功时,在 xQueueSend(), xQueueSendToFront(), xQueueSendToBack(), 或任何信号灯 '给出'函数中调用。
traceQUEUE_SEND_FAILED(pxQueue)当因为队列满(在达到指定阻塞时间)造成发送失败后在 xQueueSend(), xQueueSendToFront(), xQueueSendToBack(), 或其他信号灯 '给出' 函数中调用。
traceQUEUE_RECEIVE(pxQueue)当队列接收成功后在 xQueueReceive() 或其他信号灯 '获取'函数中调用。
traceQUEUE_RECEIVE_FAILED()在因为队列空(在达到指定阻塞时间后)造成接收失败后,在 xQueueReceive() 或其他信号灯 '获取' 函数中调用。
traceQUEUE_PEEK()在 xQueuePeek() 中调用。
traceQUEUE_SEND_FROM_ISR(pxQueue)当发送成功时在 xQueueSendFromISR() 中调用。
traceQUEUE_SEND_FROM_ISR_FAILED(pxQueue)当因为队列满造成发送失败时在 xQueueSendFromISR() 中调用。
traceQUEUE_RECEIVE_FROM_ISR(pxQueue)当接收成功时在 xQueueReceiveFromISR() 中调用。
traceQUEUE_RECEIVE_FROM_ISR_FAILED(pxQueue)当因为队列空造成接收失败时在 xQueueReceiveFromISR() 中调用。
traceQUEUE_DELETE(pxQueue)在 vQueueDelete() 中调用。
traceTASK_CREATE(pxTask)当任务创建成功时在 xTaskCreate() 中调用。
traceTASK_CREATE_FAILED()当任务因为堆空间不足创建失败时在 xTaskCreate() 中调用。
traceTASK_DELETE(pxTask)在 vTaskDelete() 中调用。
traceTASK_DELAY_UNTIL()在 vTaskDelayUntil() 中调用。
traceTASK_DELAY()在 vTaskDelay() 中调用。
traceTASK_PRIORITY_SET(pxTask,uxNewPriority)在 vTaskPrioritySet() 中调用。
traceTASK_SUSPEND(pxTask)在 vTaskSuspend() 中调用。
traceTASK_RESUME(pxTask)在 vTaskResume() 中调用。
traceTASK_RESUME_FROM_ISR(pxTask)在 xTaskResumeFromISR() 中调用。
 

 

翻译:   邵子扬
EMail:   shaoziyang@126.com
Blog:    http://blog.ednchina.com/shaoziyang
2008年10月

 

Site Meter