如果想查看FreeRTOS任务的运行状态,可以使用下面两个函数:
1. vTaskList
vTaskList((char *)&pcWriteBuffer);
使用该函数前要在文件FreeRTOSConfig.h中,设置宏:
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
2. vTaskGetRunTimeStats
vTaskGetRunTimeStats((char *)&pcWriteBuffer);
使用该函数前要在文件FreeRTOSConfig.h中,设置宏define configGENERATE_RUN_TIME_STATS为1。
#define configGENERATE_RUN_TIME_STATS 1
configGENERATE_RUN_TIME_STATS打开,它只是某种计时器的计数器值。需要在FreeRTOSConfig.h中配置两个应用程序功能配置的宏:
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() AppConfigureTimerForRuntimeStats()
#define portGET_RUN_TIME_COUNTER_VALUE() AppGetRuntimeCounterValue()
第一个是在RTOS启动时配置Timer,第二个是返回实际的计时器计数器值。一般的经验法则是,用于测量任务的计时器应该比实际的滴答计数器快10倍。
3. STM32F107示例代码
3.1 配置定时器TIM6,每100us中断一次(速度是SysTick的10倍),定时中断累加runtimeCounter。
/*-----------------------------------------------------------------------------------*/
void MX_TIM6_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig;
htim6.Instance = TIM6;
htim6.Init.Prescaler = 72-1;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 100-1;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/* Start the TIM time Base generation in interrupt mode */
HAL_TIM_Base_Start_IT(&htim6);
}
/*-----------------------------------------------------------------------------------*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 1 */
if(htim->Instance == TIM6)
{
runtimeCounter++;
}
/* USER CODE END Callback 1 */
}
3.2 在FreeRTOSConfig.h文件中配置如下宏定义:
extern uint32_t runtimeCounter;
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
#define configGENERATE_RUN_TIME_STATS 1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() (runtimeCounter = 0)
#define portGET_RUN_TIME_COUNTER_VALUE() (runtimeCounter)
3.3 在UDP任务中接收tasklist, taskstatus命令查看任务状态
/*-----------------------------------------------------------------------------------*/
static void udpecho_thread(void *arg)
{
void *data;
u16_t len;
char tasks_buf[512];
err_t err, recv_err;
LWIP_UNUSED_ARG(arg);
conn = netconn_new(NETCONN_UDP);
if (conn!= NULL)
{
err = netconn_bind(conn, IP_ADDR_ANY, 8000);
if (err == ERR_OK)
{
while (1)
{
recv_err = netconn_recv(conn, &buf);
if (recv_err == ERR_OK)
{
netbuf_data(buf, &data, &len);
if (len >= 4)
{
if(strncmp(data, "tasklist", 8) == 0)
{
memset(tasks_buf, 0, 512);
strcat((char *)tasks_buf, "任务名称\t运行状态\t优先级\t剩余堆栈\t任务序号\r\n" );
strcat((char *)tasks_buf, "---------------------------------------------\r\n");
/* The list of tasks and their status */
vTaskList((char *)(tasks_buf + strlen(tasks_buf)));
strcat((char *)tasks_buf, "\r\n---------------------------------------------\r\n");
//strcat((char *)tasks_buf, "B : Blocked, R : Ready, D : Deleted, S : Suspended\r\n");
strcat((char *)tasks_buf, "B : 阻塞, R : 就绪, D : 删除, S : 暂停\r\n");
// Initialize a netbuf and reference tasks_buf.
sendbuf = netbuf_new();
if(sendbuf != NULL)
{
netbuf_ref(sendbuf, tasks_buf, strlen(tasks_buf));
}
}
else if(strncmp(data, "taskstatus", 10) == 0)
{
memset(tasks_buf, 0, 512);
strcat((char *)tasks_buf, "任务名称\t运行计数\t使用率\r\n" );
strcat((char *)tasks_buf, "---------------------------------------------\r\n");
/* displays the amount of time each task has spent in the Running state
* in both absolute and percentage terms. */
vTaskGetRunTimeStats((char *)(tasks_buf + strlen(tasks_buf)));
strcat((char *)tasks_buf, "\r\n");
// Initialize a netbuf and reference tasks_buf.
sendbuf = netbuf_new();
if(sendbuf != NULL)
{
netbuf_ref(sendbuf, tasks_buf, strlen(tasks_buf));
}
}
// Send result.
if(sendbuf != NULL)
{
addr = netbuf_fromaddr(buf);
port = netbuf_fromport(buf);
netconn_connect(conn, addr, port);
netconn_send(conn,sendbuf);
netbuf_delete(sendbuf);
}
else
{
// Allocate new netbuf failed.
}
}
netbuf_delete(buf);
}
}
}
else
{
netconn_delete(conn);
printf("can not bind netconn");
}
}
else
{
printf("can create new UDP netconn");
}
}
/*-----------------------------------------------------------------------------------*/
void udpecho_init(void)
{
sys_thread_new("udpecho_thread", udpecho_thread, NULL, DEFAULT_THREAD_STACKSIZE, UDPECHO_THREAD_PRIO );
}
运行效果:
STM32CubeMX工程,STM32F107+LwIP+FreeRTOS源码下载: freertos_lwip.rar
1. 源码下载地址:https://download.csdn.net/download/kezunhb/10407660
2. 免积分下载地址:https://www.etdev.net/thread-7-1-1.html