Adding tracing to existing project

In order to add the tracing feature of the PXROS-HR to an existing project, please follow the steps below.

If you want to add:

  • statically allocated buffer, start here

  • dynamically allocated buffer, start here

Statically allocated buffer

  1. Add trace configuration

    Code 1. Trace configuration defines and helping macro
    /* Size of one element in trace circular buffer */
    #define TRACE_ENTRY_SIZE        24
    
    /* Size of trace circular buffer */
    #define TRACE_BUFFER_ENTRIES    500
    
    /* Calculate size of trace circular buffer */
    #define TRACE_ARRAY_SIZE(x) ((x) * TRACE_ENTRY_SIZE)
  2. Allocate buffer to be read-write accessible by the kernel

    Code 2. Example allocation of buffer in the system memory on core 0
    #define TRACE_BUFFER_SIZE   \
        (TRACE_ARRAY_SIZE(TRACE_BUFFER_ENTRIES) + sizeof(PxAligned_t) - 1) / sizeof(PxAligned_t)
    
    /* Circular buffer must be read-write accessible by the kernel */
    #pragma section ".CPU0.systemmemory" 8 awB
    PxAligned_t traceBuffer_CPU0[TRACE_BUFFER_SIZE] PXMEM_ALIGNED;
    #pragma section
  3. Select a task that will register and configure the trace mechanism

    For this task, do the following

    • Add task access rights for using trace control function and registering trace function — PXACCESS_TRACECTRL, PXACCESS_SYSTEM_CONTROL

    • Add read or read-write permission to the trace buffer

      {
          (unsigned int) &traceBuffer_CPU0,
          (unsigned int) &traceBuffer_CPU0 + TRACE_ARRAY_SIZE(TRACE_BUFFER_ENTRIES),
          WRProtection
      },
  4. Continue with Common configuration and usage

Dynamically allocated buffer

  1. Add trace configuration

    Code 3. Trace configuration defines and helping macro
    /* Size of one element in trace circular buffer */
    #define TRACE_ENTRY_SIZE        24
    
    /* Size of trace circular buffer */
    #define TRACE_BUFFER_ENTRIES    500
    
    /* Calculate size of trace circular buffer */
    #define TRACE_ARRAY_SIZE(x) ((x) * TRACE_ENTRY_SIZE)
  2. Allocate buffer to be read-write accessible by the kernel

    • Enlarge the system memory area by adding space for the trace buffer to the system default memory class in the "system_cfg.c" file — add + TRACE_ARRAY_SIZE(TRACE_BUFFER_ENTRIES)

      Code 4. Enlarged system memory adrea on core 0 in "system_cfg.c"
       /* System memory (PXMcSystemdefault)
       * shall be large enough
       * - to allocate all core's task control block (TCB)
       * - memory taken from PXMcSystemdefault
       */
      #pragma section ".CPU0.systemmemory" 8 awB
      #define SYSMEMSIZE_CORE0 (PXMEM_ADJUST((NUM_OF_TASKS_CORE0) * (PXTASK_SIZE + PXMCVARSIZED_ADDON)) + TRACE_ARRAY_SIZE(TRACE_BUFFER_ENTRIES))
      PxMemAligned_t Sysmem_Core0[SYSMEMSIZE_CORE0 / sizeof(PxMemAligned_t)];
      #pragma section
    • Take block from the Systemdefault memory class

      /* Take a memory block for buffering */
      PxMptr_t traceBuffer = PxMcTakeBlk(PXMcSystemdefault, TRACE_ARRAY_SIZE(TRACE_BUFFER_ENTRIES));
      if(!traceBuffer)
          PxPanic();
      
      /* Clear buffer */
      PxBzero((PxUChar_t *)traceBuffer, TRACE_ARRAY_SIZE(TRACE_BUFFER_ENTRIES));
  3. Select a task that will register and configure the trace mechanism

    For this task, do the following

    • Add task access rights for using trace control function and registering trace function — PXACCESS_TRACECTRL, PXACCESS_SYSTEM_CONTROL

  4. Continue with Common configuration and usage

Common configuration and usage

  1. Write your tracing function — traceFunc in these steps (Example implementation)

    • You will probably need to include pxservices.h that contains enum with PXROS-HR services and pxtrace_internal.h with the internal PXROS-HR PxTrace API declarations.

      #include "pxtrace_internal.h"
      #include "pxservices.h"
  2. Configure trace according to your needs

    • Assign trace buffer

      /* Assign trace buffer */
      PxError_t error = PxTraceAssignBuffer(traceBuffer_CPU0,
                                            TRACE_BUFFER_ENTRIES,
                                            TRACE_ENTRY_SIZE);
      if (error != PXERR_NOERROR)
          PxPanic();
    • Set trace function

      /* Set trace function */
      if (PxSetTraceFunc((PxTraceFunc_t) traceFunc) != PXERR_NOERROR )
          PxPanic();

      or

      /* Set trace function */
      if (PxTraceCtrl(PXTraceSetTraceFunction, (PxArg_t) traceFunc) == -1)
          PxPanic();

      In the end, PxSetTraceFunc() is called in both cases.

    • Enable desired trace groups (all disabled by default)

      Code 5. Example of enabling only SCHEDULING and USER services
      /* Trace only services from group SCHEDULING and USER services */
      PxTraceCtrl(PXTraceSetGroupMask, (PxArg_t) (PXVT_SCHEDULING | PXVT_USER));
    • Other desired settings done by calling PxTraceCtrl()

    • Start tracing

      /* Start tracing */
      PxTraceCtrl(PXTraceStart, (PxArg_t) 0); /* Argument not used */
  3. Add user-defined services and trace them

    Code 6. Example tracing of LED toggling
    #define TRACE_USER_LED_TOGGLE       333
    
    ...
    
    PxTrace((PxInt_t) TRACE_USER_LED_TOGGLE,
            (PxArg_t) led_number,
            (PxArg_t) 0,    /* Argument not used */
            (PxError_t) PXERR_NOERROR);