Main Content

Activate the Profiler Feature

Sample times specified in a Simulink® model define the schedule for executing generated code on hardware. If the hardware has enough computing power, the code executes as specified.

The profiler feature generates code that measures execution performance of algorithm code. You can use this feature in PIL simulation or in standalone execution. If the code runs on multicore hardware, the profiler feature can also analyze how generated code uses different cores.

The profiling code calculates execution times from the data that is obtained through profiling instructions that are inserted into generated code. These instructions depend on a hardware-specific profiling function to obtain the current time on hardware. If the supported hardware has multiple cores, this profiling function can store the ID of the core on which the code is executing. Your target must provide the profiling function and the code to configure the associated timer, if one is needed.

Note

This is an example work flow for activating the profiler feature of your target. You must create hardware specific functions to successfully complete the profiler feature.

  1. Create and add a new Profiler object, prof, to your Target object, tgt, by calling addNewProfiler with the name of the profiler, for example, 'My New Profiler'.

    prof = addNewProfiler(tgt,'My New Profiler');

    Do not delete the Profiler object from the MATLAB® workspace before you save the target.

  2. Confirm that the profiler 'My New Profiler' is added to your target.

    show(tgt);
                                  My ARM Cortex A Board
    Display Name                  My ARM Cortex A Board
    My New Deployer                        1
    Linux                                  1
    My New PIL                    My Ethernet Interface
    My New External Mode         	My Ethernet Interface
    My New Profiler                        0
    

    The profiler 'My New Profiler' is added to the target. However, the 0 indicates that the profiler is not used for the hardware 'My ARM Cortex A Board'.

  3. Map the Profiler object, prof, to the Hardware object, hw.

    map(tgt,hw,prof);
  4. Confirm that the profiler 'My New Profiler' is used for the hardware 'My ARM Cortex A Board'.

    show(tgt);
                                     My ARM Cortex A Board
    Display Name                     My ARM Cortex A Board
    My New Deployer                           1
    Linux                                     1
    My New PIL                       My Ethernet Interface
    My New External Mode             My Ethernet Interface
    My New Profiler                           1
    

    The profiler 'My New Profiler' is used for the hardware 'My ARM Cortex A Board' as shown by the 1 in the corresponding position for the hardware.

  5. View properties of the Profiler object.

    prof
    prof =
    			Profiler with properties:
                    Name: 'My New Profiler'
            TimerReadFcn: ''
              SourceFile: ''
             IncludeFile: ''
           TimerDataType: 'uint32'
     TimerTicksPerSecond: 1.0000e+09
         TimerUpcounting: 1
             StoreCoreID: 1
               PrintData: 1
          PrintInstantly: 0
              BufferName: 'profilingData'
              DataLength: 400
              GetDataFcn: ''
    
  6. Specify a function that returns elapsed time on hardware, also known as a profiling function, by setting the TimerReadFcn property of the Profiler object to, for example, 'profileReadTimer'.

    prof.TimerReadFcn = 'profileReadTimer';

    Note

    The function takes no arguments and returns the current time as an integer.

  7. Specify a source file that contains the definition of the profiling function by setting the SourceFile property of the Profiler object. For example:

    prof.SourceFile = '$(ARM_CORTEX_A_ROOT_DIR)/src/profile_timer.c';
  8. Specify a header file that contains the declaration of the profiling function by setting the IncludeFile property of the Profiler object. For example:

    prof.IncludeFile = '$(ARM_CORTEX_A_ROOT_DIR)/include/profile_timer.h';
  9. Specify the data type of the value returned by the profiling function by setting the TimerDataType property of the Profiler object. For example:

    prof.TimerDataType = 'uint32';
  10. Specify the resolution, in ticks per second, of the value returned by the profiling function by setting the TimerTicksPerSecond property of the Profiler object. For example:

    prof.TimerTicksPerSecond = 100000000;
  11. Specify whether the value returned by the profiling function is increasing or decreasing, that is, counting up or counting down, by setting the TimerUpcounting property of the Profiler object. For example, if the profiling function is counting up, set TimerUpcounting to 1.

    prof.TimerUpcounting = 1;

    If the profiling function is counting down, set this property to 0 instead.

  12. Specify whether the profiling function also collects information on the processor core that executes generated code by setting the StoreCoreID property of the Profiler object. For example, if the profiling function collects information on the processor core that executes generated code, set StoreCoreID to 1.

    prof.StoreCoreID = 1;

    If your hardware has a single core or if the profiling function does not collect information on the processor core that executes generated code, set StoreCoreID to 0.

  13. Specify whether the profiling function should print profiling data by setting the PrintData property of the Profiler object. For example:

    prof.PrintData = 1;

    If you do not want to print the profiling data, set PrintData to 1. You can print data only on hardware that uses a file system, for example, the hardware running Linux®.

  14. Specify whether the profiling data prints instantly while the code is running by setting the PrintInstantly property of the Profiler object to, for example, 0.

    prof.PrintInstantly = 0;

    Note

    When you set PrintInstantly to 0, the data is printed only when generated code stops executing. The data is printed and saved to the file named modelname.txt, where modelname is the name of the Simulink model.

  15. Specify the function that copies the profiling data from the hardware to the MATLAB host computer by setting the GetDataFcn property of the Profiler object. For example:

    prof.GetDataFcn = 'codertarget.arm_cortex_a.internal.getProfileData';
  16. Set the name of the buffer in the generated code that stores the profiling data by setting the BufferName property of the Profiler object. For example:

    prof.BufferName = 'profilingData';
  17. Set the size of the buffer that stores the profiling data by setting the DataLength property of the Profiler object. For example:

    prof.DataLength = 400;

    Note

    Data is collected from the start of the code execution until the buffer fills up, unless you specify that the data prints instantly.

  18. If you are using the profiling function of the reference target, proceed to step 22 in this section. Otherwise, create an empty file that will hold the profiling function. The file name and location must be the same name as specified in the SourceFile property, for example $(ARM_CORTEX_A_ROOT_DIR)/src/profile_timer.c.

  19. Add the profiling function template shown below to the file you created.

    #include "rtwtypes.h"
    extern uint32_T profileReadTimer(void);
    /* _tmwrunningCoreID symbol declared only for standalone execution profiler */
    #ifdef MW_STANDALONE_EXECUTION_PROFILER_ON
    extern unsigned int _tmwrunningCoreID;
    #endif
    uint32_T profileReadTimer(void)
    {
             uint32_T ret = (uint32_T) counterfcn();
              /* _tmwrunningCoreID symbol declared only for standalone execution profiler */
             #ifdef MW_STANDALONE_EXECUTION_PROFILER_ON
                       _tmwrunningCoreID = coreidfcn();
             #endif
             return(ret);
    }
    
  20. Modify the profiling function template, as necessary, such that:

    1. The function name, profileReadTimer, matches the TimerReadFcn property.

    2. Replace counterfcn with the function that returns the timer value for the hardware.

    3. Replace coreidfcn with the function that returns the core id for your hardware.

    4. Replace uint32_T with the C/C++ equivalent to the data type specified in the TimerDataType property.

  21. Create a file named 'myprofile_timer.h' that contains the definition of the function that obtains time in the include folder of your target’s root folder.

    #define _PROFILER_TIMER_H_
    #ifdef __cplusplus
    extern "C"
    {
              #endif
              extern uint32_T profileReadTimer(void);
              #ifdef __cplusplus
    }
    #endif
    
  22. Save the information that describes a target to its framework.

    saveTarget(tgt);
  23. Test that the profiler works correctly.

    testTarget(tgt,'profiler');

    Upon completion of the test, a summary result is displayed.

Confirm the Operation of the Profiler Feature in PIL Simulation

  1. Create a blank Simulink model named test.

  2. In the model, select Modeling > Model Settings.

  3. In the Configuration Parameters dialog box, select Solver pane.

  4. From the Type list, select Fixed-step. From the Solver list, select auto.

  5. In the Configuration Parameters dialog box, on the Hardware Implementation pane, set Hardware board to the hardware you registered, for example, 'My ARM Cortex A Board'.

  6. In the Model Configuration Parameters dialog box, select Code Generation > Verification.

  7. Select Advanced parameters > Create block and set it to PIL.

  8. Enable Code execution time profiling > Measure task execution time and set Measure function execution times to Coarse (referenced models and subsystems only).

  9. Set the Save options to All data. Verify the name of the Workspace variable: executionProfile. Click OK.

  10. Open the Simulink Library Browser and from the Sources library, add the Constant block to your model.

  11. From the Math Operations library, add the Gain block to your model. Connect the Constant and the Gain block.

  12. From the Math Operations library, add the Subtract block to your model.

  13. Connect the Gain block and the first input port of the Subtract block.

  14. Right-click the Gain block and select Build Subsystem from Selection.

  15. Right-click the Subsystem block and select C/C++ Code > Build This Subsystem. Click Build in the dialog box that opens.

    A library containing the PIL Subsystem block is created. This block is gateway to the generated code that will run on the hardware.

  16. Copy the PIL Subsystem block to your model and connect it to the Constant and the Subtract block.

  17. From theSinks Library, add the Scope block to your model. Connect the Subtract and the Scope block.

  18. Open the Scope block and run the model.

    After the PIL simulation completes, the executionProfile variable appears in the MATLAB workspace.

  19. Obtain the profiling report and analyze different turnaround and execution times.

    report(executionProfile)

Confirm the Operation of the Profiler Feature in Standalone Execution

  1. Create a blank Simulink model named test.

  2. In the model, select Modeling > Model Settings.

  3. In the Configuration Parameters dialog box, select Solver pane.

  4. From the Type list, select Fixed-step. From the Solver list, select auto.

  5. In the Configuration Parameters dialog box, on the Hardware Implementation, set Hardware board to the hardware you registered, for example, 'My ARM Cortex A Board'.

  6. On the Solver pane, enable Treat each discrete rate as a separate task and Stop time to 5.

  7. On the Optimization pane, clear Block reduction.

  8. On the Code Generation > Interface pane, check MAT-file logging.

  9. Enable Code execution time profiling > Measure task execution time and set Measure function execution times to Coarse (referenced models and subsystems only).

  10. Set the Save options to All data. Click OK.

  11. Open the Simulink Library Browser and from the Sources library, add the Constant block to the model. Double-click the Constant block and set the Sample time to 0.01.

  12. Add a copy of this Constant block to the model. In the copy, set the Sample time to 0.02 and the Constant value to 2.

  13. From the Sinks library, add two To Workspace blocks to your model.

  14. Connect each Constant block to a To Workspace block.

  15. In your model, click Build Model. After the build completes, the application runs on your hardware for 5 seconds and then stops.

  16. Get the profiling data into MATLAB workspace.

    codertarget.profile.getData('test')
  17. Obtain the profiling report and analyze different turnaround and execution times.

    report(executionProfile)
  18. Visualize the scheduling of tasks.

    schedule(executionProfile)