Try   HackMD

Lab3-Task_Monitor

contributed by <RusselCK >

tags: RusselCK

作業要求

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

給定下列 tasks,從 pxReadyTasksListspxDelayedTaskList 找出他們的 TCB ,並將其部分內容在 Console 呈現出來。

Task Name Priority
Lab03_Red_LED 1
Lab03_Green_LED 1
Lab03_Delay_App 14
Lab03_TaskMonitor_App 2

Pinout & Configuration

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

UART & TTL

UART

Using an USART to USB dongle from the market connected for instance to STM32F407 USART2 available on connector P1 pin 14 (PA2: USART2_TX) and P1 pin 13 (PA3: USART2_RX).

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

USBtoTTL

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

main.c

/* Private includes ----------------------------------------*/
/* USER CODE BEGIN Includes */
#include "FreeRTOS.h"
#include "task.h"
/* USER CODE END Includes */

Lab03_Red_LED

void Red_LED_App(void *pvParameters)
{
    uint32_t Redtimer = 500;
    while(1){
    	HAL_GPIO_TogglePin(GPIOD,Red_LED_Pin);
    	vTaskDelay(Redtimer);
    	Redtimer += 1;
    }
}

Lab03_Green_LED

void Green_LED_App(void *pvParameters)
{
    uint32_t Greentimer = 1000;
    while(1){
        HAL_GPIO_TogglePin(GPIOD,Green_LED_Pin);
        vTaskDelay(Greentimer);
        Greentimer += 2;
    }
}

Lab03_Delay_App

void Delay_App(void *pvParameters)
{
    while(1){
        vTaskDelay(15000);
    }
}

Lab03_TaskMonitor_App

void Taskmonitor(void);

void TaskMonitor_App(void *pvParameters)
{
    uint8_t i = 100;
    for(;;){
        Taskmonitor();
        i += 1;
        vTaskDelay(i);
        if( i == 500)
            i = 0 ;
    }
}

Lab03 最重要的任務就是完成 Taskmonitor()

Lab03_start

void vLab03_start (void *pvParameters)
{
    xTaskCreate(Red_LED_App, "Lab03_Red_LED", 1000, NULL, 1,  NULL);
    xTaskCreate(Green_LED_App, "Lab03_Green_LED", 1000, NULL, 1,  NULL);
    xTaskCreate(Delay_App, "Lab03_Delay_App", 1000, NULL, 14,  NULL);
    xTaskCreate(TaskMonitor_App, "Lab03_TaskMonitor_App", 1000, NULL, 2,  NULL);

    vTaskDelete(NULL);
}

int main (void) 
{
    /* USER CODE BEGIN 2 */
    xTaskCreate(vLab03_start, "Lab03_Start", 1000, NULL, 1,  NULL);
    vTaskStartScheduler();
    /* USER CODE END 2 */

}

TCB

TCB 的位置

pxReadyTaskLists[priority]

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

每個 priority 會有一條 pxReadyTaskList

pxDelayedTaskList

pxDelayedTaskList 只有一條,且結構與 pxReadyTaskList 相同

TCB 的結構

task.c

typrdef struct tskTaskControlBlock
{
    volatile StackType_t * pxTopOfStack;
    
    UBaseType_t uxPriority
    StackType_t * pxStack;
    char pcTaskName[ configMAX_TASK_NAME_LEN ];
    
    #if ( configUSE_MUTEXES == 1 )
        UBaseType_t uxBasePriority; 
        
    #endif
        ...
} tskTCB;

typedef tskTCB TCB_t

僅列出 Lab03 會用到的項目

Lists Macro

list.h

/* default */
#define listLIST_IS_EMPTY( pxList )	( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
#define listGET_OWNER_OF_HEAD_ENTRY( pxList )  ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner )
#define listCURRENT_LIST_LENGTH( pxList )	( ( pxList )->uxNumberOfItems )

/* add by your own */
#define listGET_ITEM_OF_HEAD_ENTRY( pxList )  ( (&( ( pxList )->xListEnd ))->pxNext )

僅列出 Lab03 會用到的部分

listGET_OWNER_OF_HEAD_ENTRY( pxList ) 會直接指向 List 的第一個 xListItem 的 TCB

  • 這樣一來就無法進入 List 的第二個 xListItem

listGET_ITEM_OF_HEAD_ENTRY( pxList ) 會指向 List 的一個 xListItem

  • 可以保有去 TCB 或下一個 xListItem 的選擇彈性

task.c

#include <stdio.h>

#include "stm32f4xx_hal.h"
UART_HandleTypeDef huart2; // for USART2

Uint32ConvertHex()

void Uint32ConvertHex(volatile StackType_t pStack, char *charTxScanTaskStack)
{
    uint32_t remainder,quotient;
    int index = 0;

    quotient = pStack;
    charTxScanTaskStack[index++] = 48; // ascii  number 0
    charTxScanTaskStack[index++] = 120; // ascii alphabet x
    while (quotient != 0)
    {
        remainder = quotient & 0xf; // quotient % 16
        if (remainder < 10)
            charTxScanTaskStack[index++] = '0' + remainder;
       	else
            charTxScanTaskStack[index++] = 55 + remainder; // A = 65;
            
        quotient = quotient >> 4; // quotient / 16
    }
    
    /* reverse */
    int end = index-1;
    for(int reversal = 2;reversal <= end; ++reversal, --end)
    { 
        charTxScanTaskStack[end] ^= charTxScanTaskStack[reversal];
        charTxScanTaskStack[reversal] ^= charTxScanTaskStack[end];
        charTxScanTaskStack[end] ^= charTxScanTaskStack[reversal];
    }
    charTxScanTaskStack[index++] = 0;
}

LongConvertCharArray()

void LongConvertCharArray(UBaseType_t TxScanTaskPriority, char *charTxScanTaskStack)
{
    uint32_t remainder,quotient;
    int index = 0;
    
    quotient = TxScanTaskPriority;
    if(quotient == 0)
    	charTxScanTaskStack[index++] = '0';
    while (quotient != 0){
       	remainder = quotient % 10;
       	charTxScanTaskStack[index++] = '0' + remainder;
        
       	quotient = quotient / 10;
    }

    /* reverse */
    if (index == 1) return;

    int end = index-1;
    for(int reversal = 0; reversal <= end; ++reversal, --end)
    { 
        charTxScanTaskStack[end] ^= charTxScanTaskStack[reversal];
        charTxScanTaskStack[reversal] ^= charTxScanTaskStack[end];
        charTxScanTaskStack[end] ^= charTxScanTaskStack[reversal];
    }
    charTxScanTaskStack[index++] = 0;
}

PrintTCBContext()

簡化版

void PrintTCBContext(TCB_t *taskTCB, char taskState[])
{
    /* get TCB contexts */
    char taskBasePriority[3];  memset(taskBasePriority,'\0',sizeof(taskBasePriority));
    LongConvertCharArray(taskTCB->uxBasePriority, taskBasePriority);
    char taskPriority[3];      memset(taskPriority,'\0',sizeof(taskPriority));
    LongConvertCharArray(taskTCB->uxPriority, taskPriority);
    char taskStack[11];        memset(taskStack,'\0',sizeof(taskStack));
    Uint32ConvertHex(taskTCB->pxStack, taskStack);
    char taskTOS[11];          memset(taskTOS,'\0',sizeof(taskTOS));
    Uint32ConvertHex(taskTCB->pxTopOfStack, taskTOS);

    /* ouput TCB contexts */
    char Monitor[150];         memset(Monitor,'\0',sizeof(Monitor));
    strcat(Monitor,taskTCB->pcTaskName);
    int taskNamelen = strlen(taskTCB->pcTaskName);
    strcat(Monitor,taskBasePriority);	
    strcat(Monitor,taskPriority);	
    strcat(Monitor,taskStack);		
    strcat(Monitor,taskTOS);		
    strcat(Monitor, taskState);	
    strcat(Monitor, "\n\r");
    HAL_UART_Transmit(&huart2,(uint8_t *)Monitor,strlen(Monitor),0xffff);
}

調整排版

void PrintTCBContext(TCB_t *taskTCB, char taskState[])
{
    /* get TCB contexts */
    char taskBasePriority[3];  memset(taskBasePriority,'\0',sizeof(taskBasePriority));
    LongConvertCharArray(taskTCB->uxBasePriority, taskBasePriority);
    char taskPriority[3];      memset(taskPriority,'\0',sizeof(taskPriority));
    LongConvertCharArray(taskTCB->uxPriority, taskPriority);
    char taskStack[11];        memset(taskStack,'\0',sizeof(taskStack));
    Uint32ConvertHex(taskTCB->pxStack, taskStack);
    char taskTOS[11];          memset(taskTOS,'\0',sizeof(taskTOS));
    Uint32ConvertHex(taskTCB->pxTopOfStack, taskTOS);

    /* ouput TCB contexts */
    char Monitor[150];         memset(Monitor,'\0',sizeof(Monitor));
    strcat(Monitor,taskTCB->pcTaskName);
    int taskNamelen = strlen(taskTCB->pcTaskName);
    for(int t = 0; t < (30-taskNamelen); ++t)
    	strcat(Monitor," ");
    strcat(Monitor,taskBasePriority);	strcat(Monitor, "/");
    strcat(Monitor,taskPriority);	strcat(Monitor,"			");
    strcat(Monitor,taskStack);		strcat(Monitor,"	");
    strcat(Monitor,taskTOS);		strcat(Monitor,"	");
    strcat(Monitor, taskState);	strcat(Monitor, "\n\r");
    HAL_UART_Transmit(&huart2,(uint8_t *)Monitor,strlen(Monitor),0xffff);
}

Taskmonitor()

void Taskmonitor(void)
{
    /* output Title */
    char *str="Name                         |Piority (Base/Actual)    |pxStack	       |pxTopOfStack   |State	\n\r";
    HAL_UART_Transmit(&huart2,(uint8_t *)str,strlen(str),0xffff);

    /* traversal ReadyTaskLists */
    for (UBaseType_t i = 0; i < configMAX_PRIORITIES; ++i)
    {
        if (listLIST_IS_EMPTY( &pxReadyTasksLists[i] ) == pdFALSE)
        {
            ListItem_t *tasklist = listGET_ITEM_OF_HEAD_ENTRY( &pxReadyTasksLists[i] );
            UBaseType_t tasklistlen = listCURRENT_LIST_LENGTH( &pxReadyTasksLists[i] );

            for (UBaseType_t j = 0; j < tasklistlen; tasklist = tasklist->pxNext, ++j)
            {
                TCB_t *taskTCB = tasklist->pvOwner;
                char taskState[6] = "Ready";
                
                PrintTCBContext (taskTCB, taskState);
            }
        }
    }

    /* traversal DelayedTaskList */
    if (listLIST_IS_EMPTY( &pxDelayedTaskList[0] ) == pdFALSE)
    {
        ListItem_t *tasklist = listGET_ITEM_OF_HEAD_ENTRY( &pxDelayedTaskList[0] );
        UBaseType_t tasklistlen = listCURRENT_LIST_LENGTH( &pxDelayedTaskList[0] );

        for (UBaseType_t j = 0; j < tasklistlen; tasklist = tasklist->pxNext, ++j)
        {
            TCB_t *taskTCB = tasklist->pvOwner;
            char taskState[6] = "Delay";
            
            PrintTCBContext (taskTCB, taskState);
        }
    }
}