章节10 集成向导 - Segger SystemView使用手册(译文)

本文博客链接:http://blog.csdn.net/bjr2016,作者:bjr2016,未经允许不得转载。

章节10 集成向导


本节介绍如何将SEGGER SystemView集成到操作系统或中间件模块中,以记录其执行情况。

10.1 在操作系统中集成SEGGER SystemView

SEGGER SystemView可以集成在任何(实时)操作系统中,用于获取关于任务执行、OS内部活动(如调度程序)和OS API调用的信息。对于以下的RTOS,已经完成了这个集成,并且可以在盒子外使用。

  • SEGGER embOS(V4.12a 或者更高版本)
  • Micrium uC/OS-III(即将到来的V3.06)
  • FreeRTOS(使用V8.2.3测试)

要集成到其他操作系统中,请与操作系统分销商联系,或者按照本节中的说明进行集成。

本节中的示例是用来说明何时调用特定的SystemView函数的伪代码。为了让跟踪检测工具对这些函数进行通用集成,可以将这些函数集成为函数宏,或者通过可配置的跟踪API来集成。

集成到操作系统核心
为了能够记录任务执行和上下文切换,操作系统核心必须被检测用来在适当的核心函数中生成SystemView事件。
在大多数情况下,中断执行也是由操作系统处理的。这允许在输入和退出中断的情况下对操作系统进行检测,否则将在应用程序中对每个ISR进行处理。
操作操作系统核心的第三个方面是提供运行时信息,以便进行更详细的分析。该信息包括系统时间,允许SystemView显示相对于应用程序开始时的时间戳,而不是开始记录的时间,并且任务列表被SystemView使用,以显示任务名称、堆栈信息和按优先级排序任务。

10.1.1 记录任务活动

SystemView可以记录系统和操作系统活动主要信息(如任务执行)的预定义系统事件集合。这些事件应该由操作系统在相应的函数中生成。
预定义的事件有:

事件描述SystemView API
Task Create创建了新任务SEGGER_SYSVIEW_OnTaskCreate
Task Start Ready任务被标记为准备好启动或者恢复执行SEGGER_SYSVIEW_OnTaskStartReady
Task Start Exec任务被激活(启动或者恢复执行)SEGGER_SYSVIEW_OnTaskStart
Task Stop Ready任务被阻塞或暂停SEGGER_SYSVIEW_OnTaskStopReady
Task Stop Exec任务终止SEGGER_SYSVIEW_OnTaskStopExec
System Idle没有任务执行,系统进入空闲状态SEGGER_SYSVIEW_OnIdle
10.1.1.1 Task Create任务创建

任务创建事件发生在系统创建一个任务时。
在任务创建事件调用带有新任务的Id的SEGGER_SYSVIEW_OnTaskCreate()函数。此外,建议使用SEGGER_SYSVIEW_SendTaskInfo()记录新任务的任务信息。

示例

void OS_CreateTask(TaskFunc* pF, unsigned Prio, const char* sName, void* pStack) {
    SEGGER_SYSVIEW_TASKINFO Info;
    OS_TASK* pTask; // Pseudo struct to be replaced
    [OS specific code ...]
    SEGGER_SYSVIEW_OnTaskCreate((unsigned)pTask);
    memset(&Info, 0, sizeof(Info));
    //
    // Fill elements with current task information
    //
    Info.TaskID = (U32)pTask;
    Info.sName = pTask->Name;
    Info.Prio = pTask->Priority;
    Info.StackBase = (U32)pTask->pStack;
    Info.StackSize = pTask->StackSize;
    SEGGER_SYSVIEW_SendTaskInfo(&Info);
}
10.1.1.2 Task Start Ready 任务准备好启动或者恢复执行

当任务的延迟时间结束,或者当任务等待的资源可用,或者当事件触发时,任务开始准备事件可以发生。
在使用Task Start Ready事件时,将调用带有已准备就绪的任务的Id的SEGGER_SYSVIEW_OnTaskStartReady()函数。

示例

int OS_HandleTick(void) {
    int TaskReady = 0; // Pseudo variable indicating a task is ready
    [OS specific code ...]
    if (TaskReady) {
        SEGGER_SYSVIEW_OnTaskStartReady((unsigned)pTask);
    }
}
10.1.1.3 Task Start Exec

Task Start Exec事件发生发生在上下文即将被切换到激活任务。这通常是调度程序在有准备好的任务时完成的。
调用带有将要执行的任务的Id的SEGGER_SYSVIEW_OnTaskStartExec()函数,创建Task Start Exec事件。

示例

void OS_Switch(void) {
    [OS specific code ...]
    //
    // If a task is activated
    //
    SEGGER_SYSVIEW_OnTaskStartExec((unsigned)pTask);
    //
    // Else no task activated, go into idle state
    //
    SEGGER_SYSVIEW_OnIdle()
}
10.1.1.4 Task Stop Ready

任务被阻塞或暂停。
当任务被暂停或阻塞时, Task Stop Ready事件发生。例如因为它延迟了一个特定的时间,或者当它试图声明一个资源正在被另一个任务使用,或者当它等待事件发生时。当任务被暂停或阻塞时,调度器将激活另一个任务或进入空闲状态。
调用SEGGER_SYSVIEW_OnTaskStopReady()函数,并传入被阻塞的任务的Id,以及一个可以指示为什么任务被阻塞的理由,来创建Task Stop Ready事件。

示例

void OS_Delay(unsigned NumTicks) {
    [OS specific code ...]
    SEGGER_SYSVIEW_OnTaskStopReady(OS_Global.pCurrentTask, OS_CAUSE_WAITING);
}
10.1.1.5 Task Stop Exec

任务终止。
当任务最终停止执行时,例如当它完成任务并终止执行时,Task Stop Exec事件发生。
在Task Stop Ready事件中,调用SEGGER_SYSVIEW_OnTaskStopExec()来记录当前任务的停止状态。

示例

void OS_TerminateTask(void) {
    [OS specific code ...]
    SEGGER_SYSVIEW_OnTaskStopExec();
}
10.1.1.6 System Idle

没有任务执行时,系统进入空闲状态。
System Idle事件是当一个任务被暂停或停止时,而没有其他任务准备好时发生的。系统可以切换到一个空闲状态以节省电力,等待中断或任务准备就绪。
在某些操作系统中,空闲是由另一个任务处理的。在这种情况下,当空闲任务被激活时,建议记录系统空闲事件。
在SystemView中,空闲状态时间被显示为不是CPU负载。
在系统空闲事件中调用SEGGER_SYSVIEW_OnIdle()。

示例

void OS_Switch(void) {
    [OS specific code ...]
    //
    // If a task is activated
    //
    SEGGER_SYSVIEW_OnTaskStartExec((unsigned)pTask);
    //
    // Else no task activated, go into idle state
    //
    SEGGER_SYSVIEW_OnIdle()
}

10.1.2 记录中断

SystemView可以记录进入和退出中断服务例程(ISRs)。SystemView API为这些事件提供了函数,当它提供用于标记中断执行的函数时,该函数应该添加到操作系统中。
当OS调度程序被中断控制时,例如SysTick中断,退出中断事件应该区分恢复正常执行还是切换到调度器,并调用适当的SystemView函数。

10.1.2.1 进入中断

当操作系统提供一个函数来通知OS,中断代码正在执行时,在中断服务函数(ISR)开始时调用,OS函数应该调用SEGGER_SYSVIEW_RecordEnterISR()来记录进入中断事件。
当操作系统没有提供进入中断函数,或者ISR没有调用它时,用户有必要调用SEGGER_SYSVIEW_RecordEnterISR()来记录中断执行。
segger_sysview_conf. h中的SEGGER_SYSVIEW_RecordEnterISR()函数通过SEGGER_SYSVIEW_GET_INTERRUPT_ID()函数宏自动检索中断ID。

示例

void OS_EnterInterrupt(void) {
    [OS specific code ...]
    SEGGER_SYSVIEW_RecordEnterISR();
}
10.1.2.2 Exit Interrupt

当操作系统提供一个函数来通知OS ,中断代码已经执行完时,该函数应该在中断服务函数结尾调用,OS函数应该调用:

  • SEGGER_SYSVIEW_RecordExitISR()。 当系统将恢复正常执行时
  • SEGGER_SYSVIEW_RecordExitISRToScheduler() 当中断引发一个上下文切换时。

示例

void OS_ExitInterrupt(void) {
    [OS specific code ...]
    //
    // If the interrupt will switch to the Scheduler
    //
    SEGGER_SYSVIEW_RecordExitISRToScheduler();
    //
    // Otherwise
    //
    SEGGER_SYSVIEW_RecordExitISR();
}
10.1.2.3 中断服务器函数举例

下面的两个例子展示了如何用OS中断处理和不使用OS中断来记录中断执行。

使用OS处理的例子

void Timer_Handler(void) {
    //
    // Inform OS about start of interrupt execution
    // (records SystemView Enter Interrupt event).
    //
    OS_EnterInterrupt();
    //
    // Interrupt functionality could be here
    //
    APP_TimerCnt++;
    //
    // Inform OS about end of interrupt execution
    // (records SystemView Exit Interrupt event).
    //
    OS_ExitInterrupt();
}

不使用OS处理的例子

void ADC_Handler(void) {
    //
    // Explicitly record SystemView Enter Interrupt event.
    // Should not be called in high-frequency interrupts.
    //
    SEGGER_SYSVIEW_RecordEnterISR();
    //
    // Interrupt functionality could be here
    //
    APP_ADCValue = ADC.Value;
    //
    // Explicitly record SystemView Exit Interrupt event.
    // Should not be called in high-frequency interrupts.
    //
    SEGGER_SYSVIEW_RecordExitISR();
}

10.1.3 记录运行时的信息

SystemView可以记录更详细的运行时的信息,如系统时间和任务信息。当SystemView运行时,记录开始并周期性地请求这些信息时,记录这些信息。
为了请求信息,在初始化时可以将带有操作系统特定函数的SEGGER_SYSVIEW_OS_API结构传递给SystemView。
SEGGER_SYSVIEW_OS_API设置是可选的,但建议允许SystemView显示更详细的信息。

SEGGER_SYSVIEW_OS_API

typedef struct {
    U64 (*pfGetTime) (void);
    void (*pfSendTaskList) (void);
} SEGGER_SYSVIEW_OS_API;

参数

参数描述
pfGetTime指向返回系统时间的函数
pfSendTaskList指向记录整个任务列表的函数
10.1.3.1 pfGetTime

描述
获取系统时间,也就是自系统启动后经过的时间,单位us。
如果pfGetTime为空,SystemView可以显示相对于记录开始时的时间戳。
原型

U64 (*pfGetTime) (void);

10.1.3.2 pfSendTaskList

描述
通过SEGGER_SYSVIEW_SendTaskInfo()记录整个任务列表。
如果pfSendTaskList为空,SystemView可能只会获取在记录时新创建任务的任务信息。当SystemView连接到当前任务列表时,将定期调用pfSendTaskList。
原型

void (*pfSendTaskList) (void);
例子

void cbSendTaskList(void) {
    SEGGER_SYSVIEW_TASKINFO Info;
    OS_TASK* pTask;
    OS_EnterRegion(); // Disable scheduling to make sure the task list does not change.
    for (pTask = OS_Global.pTask; pTask; pTask = pTask->pNext) {
        //
        // Fill all elements with 0 to allow extending the structure
        // in future version without breaking the code.
        //
        memset(&Info, 0, sizeof(Info));
        //
        // Fill elements with current task information
        //
        Info.TaskID = (U32)pTask;
        Info.sName = pTask->Name;
        Info.Prio = pTask->Priority;
        Info.StackBase = (U32)pTask->pStackBot;
        Info.StackSize = pTask->StackSize;
        //
        // Record current task information
        //
        SEGGER_SYSVIEW_SendTaskInfo(&Info);
    }
    OS_LeaveRegion(); // Enable scheduling again.
}

10.1.4 记录操作系统API调用

除了操作系统核心工具之外,SystemView还可以记录应用程序中的OS API调用。API函数可以像操作系统的核心一样被检测。
当传递简单参数时,或使用适当的SEGGER_SYSVIEW_EncodeXXX()函数创建SystemView事件并调用SEGGER_SYSVIEW_SendPacket()来记录它时,可以使用现成的SEGGER_SYSVIEW_RecordXXX()函数来完成记录API事件。
示例

/*********************************************************************
*
* OS_malloc()
*
* Function description
* API function to allocate memory on the heap.
*/
void OS_malloc(unsigned Size) {
    SEGGER_SYSVIEW_RecordU32(ID_OS_MALLOC, // Id of OS_malloc (>= 32)
    Size // First parameter
    );
    [OS specific code...]
}

为了记录API函数执行时间并记录其返回值的时间,API函数的返回也可以通过调用SEGGER_SYSVIEW_RecordEndCall来只记录返回值或者调用SEGGER_SYSVIEW_RecordEndCallReturnValue来记录退出事件以及返回值。

10.1.5 操作系统描述文件

为了使SystemView正确识别API调用,它需要在SystemView的 /description/ 目录中显示一个描述文件。文件的名称必须是SYSVIEW_<操作系统名>.txt,其中<操作系统名>是系统描述中发送的名称。

10.1.5.1 API函数描述

描述文件包括所有可以由操作系统记录的API函数。文件中的每一行都是一个函数,格式如下:

<EventID> <FunctionName> <ParameterDescription> | <ReturnValueDescription>

EventID是为API函数记录的Id。取值范围:32~511。
FunctionName是API函数的名称,显示在SystemView的事件列中。它可以不包含空格。
ParameterDescription是用API函数记录的参数的描述字符串。
ReturnValueDescription是返回值的描述字符串,可以用SystemView进行记录。ReturnValueDescription是可选的。

参数显示可以通过一组修饰符来配置:

  • % b - 显示参数为二进制。
  • %B - 参数显示为十六进制字符串(例如00 AA FF…)。
  • %d - 显示参数为有符号的十进制整数。
  • %D - 显示参数为时间值。
  • %I - 显示参数作为资源名,如果资源id已知为SystemView。
  • %p - 显示参数为4字节十六进制整数(如0xAABBCCDD)。
  • %s - 显示参数为字符串。
  • %t - 显示参数作为任务名称,如果任务id已知为SystemView。
  • %u - 显示参数为无符号十进制整数。
  • %x - 显示参数为十六进制整数

例子
下面的例子显示了SYSVIEW_embOS.txt的部分内容

35      OS_CheckTimer           pGlobal=%p
42      OS_Delay                Delay=%u
43      OS_DelayUntil           Time=%u
44      OS_setPriority          Task=%t Pri=%u
45      OS_WakeTask             Task=%t
46      OS_CreateTask           Task=%t Pri=%u Stack=%p Size=%u

除了默认的修饰符,描述文件还可以定义NamedTypes来将数值映射到字符串,例如,可以用来显示枚举的文本值或错误代码。
NamedTypes有以下格式:

NamedType <TypeName> <Key>=<Value> [<Key1>=<Value1> ...]

NamedTypes可以在参数描述和返回值描述中使用。
示例

#
# Types for parameter formatters
#
NamedType OSErr 0=OS_ERR_NONE
NamedType OSErr 10000=OS_ERR_A 10001=OS_ERR_ACCEPT_ISR
NamedType OSErr 12000=OS_ERR_C 12001=OS_ERR_CREATE_ISR
NamedType OSErr 13000=OS_ERR_D 13001=OS_ERR_DEL_ISR
NamedType OSFlag 0=FLAG_NONE 1=FLAG_READ 2=FLAG_WRITE 3=FLAG_READ_WRITE
#
# API Functions
#
34 OSFunc Param=%OSFlag | Returns %OSErr
10.1.5.2 任务状态描述

当一个任务暂停执行时,它的状态被记录在SystemView事件中。
这个任务状态可以被转换为SystemView中的文本表示,并使用任务状态解析。
TaskState以下格式:

TaskState <Mask> <Key>=<Value>, [<Key1>=<Value1>, ...]

示例

#
# Task States
#
TaskState 0xFF 0=Ready, 1=Delayed or Timeout, 2=Pending, 3=Pending with Timeout,
4=Suspended, 5=Suspended with Timeout, 6=Suspended and Pending, 7=Suspended and
Pending with Timeout, 255=Deleted
10.1.5.3 Option 描述

在描述文件中也可以设置操作系统特定选项来配置SystemView。
目前可以在描述文件中插入的选项为:
Option ReversePriority:更高的任务优先级值等于较低的任务优先级。

10.1.6 操作系统集成示例

下面的代码展示了如何在基于伪代码片段的操作系统中集成SystemView,并可作为参考使用。

/********************************************************************* 
*               (c) SEGGER Microcontroller GmbH & Co. KG             * 
*                        The Embedded Experts                        * 
*                           www.segger.com                           * 
********************************************************************** 
-------------------------- END-OF-HEADER ----------------------------- 

Purpose : Pseudo-code OS with SEGGER SystemView integration. 
*/ 

/*********************************************************************  
* 
*       OS_CreateTask() 
* 
*  Function description 
*    Create a new task and add it to the system. 
*/ 
void OS_CreateTask (TaskFunc* pF, unsigned Prio, const char* sName, void* pStack) { 
  SEGGER_SYSVIEW_TASKINFO Info; 
  OS_TASK*                pTask;  // Pseudo struct to be replaced 

   [OS specific code ...] 

  SEGGER_SYSVIEW_OnTaskCreate ((unsigned)pTask); 
  memset (&Info, 0, sizeof(Info)); 
  // 
  // Fill elements with current task information 
  // 
  Info.TaskID     =  (U32)pTask; 
  Info.sName      = pTask->Name; 
  Info.Prio       = pTask->Priority; 
  Info.StackBase  =  (U32)pTask->pStack; 
  Info.StackSize  = pTask->StackSize; 
  SEGGER_SYSVIEW_SendTaskInfo (&Info); 
} 

/*********************************************************************  
* 
*       OS_TerminateTask() 
* 
*  Function description 
*    Terminate a task and remove it from the system. 
*/ 
void OS_TerminateTask (void) { 

   [OS specific code ...] 

  SEGGER_SYSVIEW_OnTaskStopExec (); 
} 

/*********************************************************************  
* 
*       OS_Delay() 
* 
*  Function description 
*    Delay and suspend a task for the given time. 
*/ 
void OS_Delay (unsigned NumTicks) { 

   [OS specific code ...] 

  SEGGER_SYSVIEW_OnTaskStopReady (OS_Global.pCurrentTask, OS_CAUSE_WAITING); 
} 

/*********************************************************************  
* 
*       OS_HandleTick() 
* 
*  Function description 
*    OS System Tick handler. 
*/ 
int OS_HandleTick (void) { 
  int TaskReady = 0;   // Pseudo variable indicating a task is ready 

   [OS specific code ...] 

  if  (TaskReady) { 
    SEGGER_SYSVIEW_OnTaskStartReady ((unsigned)pTask); 
  } 
} 

/*********************************************************************  
* 
*       OS_Switch() 
* 
*  Function description 
*    Switch to the next ready task or go to idle. 
*/ 
void OS_Switch (void) { 

   [OS specific code ...] 

  // 
  // If a task is activated 
  // 
  SEGGER_SYSVIEW_OnTaskStartExec ((unsigned)pTask); 
  // 
  // Else no task activated, go into idle state 
  // 
  SEGGER_SYSVIEW_OnIdle () 
} 

/*********************************************************************  
* 
*       OS_EnterInterrupt() 
* 
*  Function description 
*    Inform the OS about start of interrupt execution. 
*/ 
void OS_EnterInterrupt (void) { 

   [OS specific code ...] 

  SEGGER_SYSVIEW_RecordEnterISR (); 
} 
/*********************************************************************  
* 
*       OS_ExitInterrupt() 
* 
*  Function description 
*    Inform the OS about end of interrupt execution and switch to  
*    Scheduler if necessary. 
*/ 
void OS_ExitInterrupt (void) { 

   [OS specific code ...] 
  // 
  // If the interrupt will switch to the Scheduler 
  // 
  SEGGER_SYSVIEW_RecordExitISRToScheduler (); 
  // 
  // Otherwise 
  // 
  SEGGER_SYSVIEW_RecordExitISR (); 
} 

10.2 在中间层模块集成SEGGER SystemView

SEGGER SystemView还可以集成到中间件模块,甚至是应用程序模块中,以获取关于这些模块的执行的信息,比如API调用或中断触发事件。此集成用于在SEGGER embOS/IP中使用,以监视通过IP和SEGGER emFile发送和接收数据包,以记录API调用。
要集成到其他模块,请与您的分销商联系,或者按照本节中的说明进行集成。

10.2.1 注册模块

为了能够记录中间件模块事件,模块必须通过SEGGER_SYSVIEW_RegisterModule()在SystemView进行注册。
该模块传递一个SEGGER_SYSVIEW_MODULE 结构体指针,该指针包含有关模块的信息,并接收模块可以生成的事件id的事件偏移量。
在注册时,必须在SEGGER_SYSVIEW_MODULE结构中设置sDescription和NumEvents。也可以设置pfSendModuleDesc。
当SEGGER_SYSVIEW_RegisterModule()返回时,SEGGER_SYSVIEW_MODULE结构中的EventOffset被设置为模块可能生成的最低的事件Id,而pNext将指向下一个注册模块,以创建一个链表。因此,SEGGER_SYSVIEW_MODULE结构必须是可写的,并且可能不会在堆栈上分配。

SEGGER_SYSVIEW_MODULE

struct SEGGER_SYSVIEW_MODULE { 
        const char*                   sModule; 
              U32                     NumEvents; 
              U32                     EventOffset; 
              void                     (*pfSendModuleDesc)(void); 
              SEGGER_SYSVIEW_MODULE*  pNext; 
}; 

参数

参数描述
sModule指向包含模块名称和模块事件描述的字符串的指针。
NumEvents模块需要注册的事件数
EventOffset事件id的偏移量。输出参数,由这个函数设置。调用此函数后不修改
pfSendModuleDesc回调函数指针,向SystemView发送更详细的模块描述。
pNext指向下一个注册模块的指针。输出参数,由这个函数设置。调用此函数后不修改

示例

SEGGER_SYSVIEW_MODULE IPModule = { 
  "M=embOSIP, " \ 
  "0 SendPacket IFace=%u NumBytes=%u, " \ 
  "1 ReceivePacket Iface=%d NumBytes=%u", // sModule 
  2,                                      // NumEvents 
  0,                                     
  // EventOffset, Set by SEGGER_SYSVIEW_RegisterModule() 
  NULL,                                  
  // pfSendModuleDesc, NULL: No additional module description 
  NULL,                                  
  // pNext, Set by SEGGER_SYSVIEW_RegisterModule() 
};

static void _IPTraceConfig (void) { 
 // 
 // Register embOS/IP at SystemView. 
 // SystemView has to be initialized before. 
 // 
 SEGGER_SYSVIEW_RegisterModule (&IPModule); 
} 

10.2.2 记录模块活动

为了能够记录模块的活动,模块必须被检测以在适当的函数中生成SystemView事件。
通过对SystemView函数进行直接集成,可以通过可配置的宏函数或API结构来实现对模块的检测,这些功能可以通过SystemView来填充和设置。
当传递简单参数时,或使用适当的SEGGER_SYSVIEW_EncodeXXX()函数创建SystemView事件,并调用SEGGER_SYSVIEW_SendPacket()来记录该事件时,可以使用随时可用的SEGGER_SYSVIEW_RecordXXX()函数来完成记录事件。

示例

int SendPacket (IP_PACKET *pPacket) { 
 // 
 // The IP stack sends a packet. 
 // Record it according to the module description of SendPacket. 
 // 
 SEGGER_SYSVIEW_RecordU32x2 ( 
 // Id of SendPacket (0) + Offset for the registered module 
                            ID_SENDPACKET + IPModule.EventOffset, 
 // First parameter  (displayed as event parameter IFace) 
                            pPacket->Interface,                     
 // Second parameter (displayed as event parameter NumBytes) 
                            pPacket->NumBytes                       
                           ); 

  [Module specific code...] 
} 

有关更多信息,请参阅第108页上的OS API调用和第117页的API引用。
与操作系统一样,可以在描述文件中使用模块的名称(M=的值)提供中间件模块描述。参见第108页的OS描述文件。

10.2.3 提供模块描述

SEGGER_SYSVIEW_MODULE.sModule指向一个包含注册模块的基本信息的字符串,该模块是一个逗号分隔的列表,可以包含以下内容:

标识举例
模块名称M“M=embOSIP”
模块令牌T“T=IP”
描述S“S=’embOS/IP V12.09’”
模块事件 “0 SendPacket IFace=%u NumBytes=%u”

字符串长度不能超过SEGGER_SYSVIEW_MAX_STRING_LEN,默认情况下是128。

要发送额外的描述字符串,并发送由模块所使用和记录的资源的名称,在注册模块时可以设置SEGGER_SYSVIEW_MODULE.fSendModuleDesc。

SEGGER_SYSVIEW_MODULE.pfSendModuleDesc在SystemView连接时被周期性调用。它可以调用SEGGER_SYSVIEW_RecordModuleDescription()和SEGGER_SYSVIEW_NameResource()。

示例

static void _cbSendIPModuleDesc (void) { 
  SEGGER_SYSVIEW_NameResource ((U32)&(RxPacketFifo), "Rx FIFO"); 
  SEGGER_SYSVIEW_NameResource ((U32)&(TxPacketFifo), "Tx FIFO"); 
  SEGGER_SYSVIEW_RecordModuleDescription (&IPModule, "T=IP, S='embOS/IP V12.09'"); 
} 

SEGGER_SYSVIEW_MODULE IPModule = { 
  "M=embOSIP, " \ 
  "0 SendPacket IFace=%u NumBytes=%u, " \ 
  "1 ReceivePacket Iface=%d NumBytes=%u", // sModule 
  2,                                      // NumEvents 
  0,                                      // EventOffset, Set by RegisterModule() 
  _cbSendIPModuleDesc,                    // pfSendModuleDesc 
  NULL,                                   // pNext, Set by RegisterModule() 
}; 
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值