FreeRTOS Series 16th---visual tracking debugging

Source: Internet
Author: User
Tags benchmark

Using RTOS programming, allocating the stack space for each task is a technical work: allocating more wasted system resources, less allocation, and I'm afraid a stack overflow will occur. Because of the presence of interrupts and preemptive schedulers, it is very difficult to estimate how many stacks a task requires, and today we present a way to get the remaining stack space for each task. This paper takes NXP lpc177x_8x series microcontrollers as an example.

We have made this function a command that is added to the list of command interpretations described in the 15th article of the FreeRTOS series---Implementing the command-line interpreter using task notifications. After the program has been running for a period of time, we enter the command "task" in the SECURECRT software and we can see the task information shown in 1-1. There are only two tasks, where the number in the Stack column represents the remaining stack space for the corresponding task, in the stacktype_t type, which is defined in the porting layer and is generally defined as 4 bytes.


Figure 1-1: Task Information

1. Enable visualization of trace and run time statistics functions

As shown in 1-1, to implement stack usage information and CPU usage information, you must set the two macros in the FreeRTOSConfig.h file to 1:

         #define Configuse_trace_facility          1               #define CONFIGGENERATE_RUN_TIME_STATS 1

The first macro is used to enable the visual tracking function, and the second macro is used to enable the run time statistics function. If the second macro is set to 1, the following two macros must be defined:

    1. Portconfigure_timer_for_run_time_stats (): The user program needs to provide a reference clock function, function to complete the initialization of the base clock function, this function to be define to the macro Portconfigure_timer_for_ Run_time_stats (). This is because the run-time statistics require a benchmark timer that is higher in resolution than the system beat interrupt frequency, otherwise the statistics may not be accurate. The base timer interrupt frequency is 10~100 times faster than the system beat interrupt. The faster the base timer interrupts, the more accurate the statistics, but the shorter the run time of the statistics (for example, the benchmark timer 10ms interrupts once, 8-bit unsigned shaping variables can be counted to 2.55 seconds, but if the 1-second interrupt, 8-bit unsigned shaping variables can be counted to 255 seconds).
    2. Portget_run_time_counter_value (): The user program needs to provide a function that returns the current "time" of the base clock, which is define to the macro Portget_run_time_counter_value ().

We use the timer to generate the reference clock, and the Timer 1 initialization function is:

/*** Initialization Timer timer 1, for OS task run time statistics */void init_timer1_for_runtime_state (void) {    tim_timercfg_type timer0cfgtype;                    Timer0cfgtype.prescaleoption=tim_prescale_usval;        The unit of Prescaler is microsecond    timer0cfgtype.prescalevalue=500;                        500 microseconds after Prescaler,    tim_init (lpc_tim1,tim_timer_mode,&timer0cfgtype);       lpc_tim1->tcr=0x01;}

Timer 1 is configured to increase the TC register value by one every 500 microseconds. We use the TC register value of timer 1 as the current time of the reference clock. When the TC register value overflows, it takes about 24.8 days, which is enough for our application.

In FreeRTOSConfig.h, define the Initialize base timer macro and get the current time macro:

extern void Init_timer1_for_runtime_state (void), #define TIMER1_TC         (* (volatile uint32_t *) 0x40008008) #define P Ortconfigure_timer_for_run_time_stats () init_timer1_for_runtime_state () #define PORTGET_RUN_TIME_COUNTER_VALUE () Timer1_tc

2. Get task information and format it

The status information for each task is obtained using the API function Uxtaskgetsystemstate (), which is defined as:

Ubasetype_tuxtaskgetsystemstate (                       taskstatus_t * constpxtaskstatusarray,                       const ubasetype_tuxarraysize,                       unsigned long * constpultotalruntime);

The function uxtaskgetsystemstate () fills the taskstatus_t structure with relevant information, and the information for each task in the system can be populated into the taskstatus_t structure array, and the array size is specified by Uxarraysize. The structure taskstatus_t is defined as follows:

typedef struct xtask_status{/   * Task handle */   taskhandle_t xhandle;    /* Pointer, point to Task Name */   Const signed char *pctaskname;    /* task ID, is a unique number */   ubasetype_t xtasknumber;    /* When filling the structure, the current state of the task (run, ready, suspended, etc.) */   etaskstate ecurrentstate;    /* The priority of the task to run (or inherit) when the structure is populated. */   ubasetype_t uxcurrentpriority;    /* When a task changes precedence due to inheritance, the variable holds the initial priority of the task. Valid only if configuse_mutexes is defined as 1. */   ubasetype_t uxbasepriority;    /* The total elapsed time assigned to the task. Valid only if macro configgenerate_run_time_stats is 1 o'clock. */   unsigned long ulruntimecounter;    /* Starting from the task, the minimum amount remaining on the stack, the closer the value is to 0, the larger the stack overflow may be. */   unsigned short Usstackhighwatermark;} taskstatus_t;

Note that this function is only used to tune the trial, and calling this function suspends all tasks until the end of the function resumes the suspended task, so the task may be suspended for a long time. In file FreeRTOSConfig.h, the macro configuse_trace_facility must be set to 1 for this function to be valid.

Since we do not use dynamic memory allocation policies, the implementation defines the maximum number of tasks and pre-allocates an array that stores the task state information:

#defineMAX_TASK_NUM        5taskstatus_tpxtaskstatusarray[max_task_num];

When the function uxtaskgetsystemstate () is called correctly, the information of the task is placed in the taskstatus_t structure, and we need to format the information in an easy-to-read form and print it to the screen in a common way. The function that completes these functions is called get_task_state (), and the code is as follows:

/* Get OS Task Information */voidget_task_state (int32_t argc,void *cmd_arg) {const chartask_state[]={' r ', ' R ', ' B ', ' S ', ' D '};    Volatile ubasetype_t uxarraysize, X;     uint32_t ultotalruntime,ulstatsaspercentage;   /* Get total number of tasks */uxarraysize = Uxtaskgetnumberoftasks (); if (uxarraysize>max_task_num) {MY_DEBUGF (Cmd_line_debug, "the current number of tasks is too large!    \ n "));     }/* Gets status information for each task */uxarraysize = Uxtaskgetsystemstate (Pxtaskstatusarray, Uxarraysize, &ultotalruntime);     #if (configgenerate_run_time_stats==1) MY_DEBUGF (Cmd_line_debug, ("Task Name status ID priority stack CPU usage \ n")); /* Avoid removing the 0 error */if (Ultotalruntime > 0) {/* will get each part of the task state information into the programmer's easy-to-recognize string format */for (x = 0; x < u Xarraysize;                       X + +) {char tmp[128]; /* Calculates the percentage of the task run time and total elapsed time.             */Ulstatsaspercentage = (uint64_t) (pxtaskstatusarray[x].ulruntimecounter) *100/ultotalruntime; if (Ulstatsaspercentage > 0UL) {sprintf (TMP, "%-12s%-6c%-6d%-8d%-8d%d%%", pxtaskstatusarray[x].pctaskname,task_state[pxtaskstatusarray[x].eCurrentState] , pxtaskstatusarray[x].xtasknumber,pxtaskstatusarr ay[x].uxcurrentpriority, pxtaskstatusarray[x].uss            Tackhighwatermark,ulstatsaspercentage); } else {/* 1%*/sprintf (tmp, "%-12s%-6c%-6d%-8d%-8dt<" for which the task runs for less than the total elapsed time                                                                       1%% ", pxtaskstatusarray[x].pctaskname,task_state[pxtaskstatusarray[x].ecurrentstate],                                                                       pxtaskstatusarray[x].xtasknumber,pxtaskstatusarray[x].uxcurrentpriority,                           pxtaskstatusarray[x].usstackhighwatermark);        } MY_DEBUGF (Cmd_line_debug, ("%s\n", TMP)); }} MY_DEBUGF (Cmd_line_debug,("Task Status: R-run R-Ready B-block S-hang D-remove \ n")); #endif//#if (Configgenerate_run_time_stats==1)}

3. Adding to the command interpreter list

In the article "FreeRTOS Series 15th---Implementing the command-line interpreter using task notifications" We talked about the command table, where you just add the Get_task_state () function to the list of commands, and the command is set to "task", and the code looks like this:

/* Command table */const cmd_list_structcmd_list[]={/*   Command    parameter number    processing function        Help information */       {"?",       0,     handle _help,     "?                                  -Print Help Info "},                     {" Reset ",   0,     handle_reset,    " Reset                              -Reboot Controller "},    {" arg ",     8,     Handle_arg,      "arg<arg1> <arg2>               ... -Test with, print input parameters "},    {" Hello ",   0,     Printf_hello,    " Hello                              -Print helloworld! "},    {" Task ",    0,     get_task_state,  "task                               -Get task Information"},};

FreeRTOS Series 16th---visual tracking debugging

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.