FreeRTOS 작업 추적
6722 단어 FreeRTOS
FreeRTOS trace macros
제가 뭘 할 수 있을까요?
나는 어떤 임무, 언제, 얼마나 오래 운행하고 있는지 알고 싶다!!
예를 들어 다음과 같은 느낌이 있다.
맨 위에서부터 오더,task1,task2,tasuk3의 시간을 순서대로 표시하고,task1은 4마이크로초 정도의 소처리를 한다.이어task3은 63us 정도의 처리를 하고,task2는 122us 정도의 처리를 한다.오더는 남은 시간을 소모하고 1ms 주기로 이런 절차를 반복하면 알 수 있다.
이 예에서 단순히 1ms 주기 처리를 보았을 뿐이지만 더 복잡한 처리에서도 특정 임무에서 터치하면 이동 빈도가 낮은 임무 처리의 시기를 알 수 있다.
물론 논리 분석기에서도 이 작업이 시작될 때 입력한 신호와 이 작업이 출력된 신호를 볼 수 있다.작은 백으로 촉발하면 시뮬레이션 신호를 동시에 볼 수 있다.
문서에 따르면 임무의 행위를 추적할 수 있을 뿐만 아니라 대열, 무더기, 다양한 행위도 추적할 수 있다.어떤 대열이 언제 조작되었는지, 그때 어떤 임무가 움직이고 있는지 감시할 수 있다.
어떻게 쓰는 거지?
작업을 추적할 때 정의
#define traceTASK_SWITCHED_OUT()
와 #define traceTASK_SWITCHED_IN()
두 개의 매크로(어떤 실현은 OUT가 필요하지 않음)를 사용합니다.RTOS 설치에서 참조되기 때문에 상당히 높은 위치에서 정의해야 합니다.이번에는 STM32 CubeMX에서 생성된 FreertosConfig입니다.구문을 사용합니다.
아래의 느낌입니다.
IN/OUT 주변 추적
/* USER CODE BEGIN Defines */
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
#define configUSE_APPLICATION_TASK_TAG 1
#include <stm32f4xx.h>
#define traceTASK_SWITCHED_OUT() \
{ \
GPIOB->BSRR = (uint32_t)(GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11) << 16; \
}
#define traceTASK_SWITCHED_IN() \
{ \
switch ((uint32_t)pxCurrentTCB->pxTaskTag) \
{ \
default: \
GPIOB->BSRR = (uint32_t)(GPIO_PIN_8); \
break; \
case 1: \
GPIOB->BSRR = (uint32_t)(GPIO_PIN_9); \
break; \
case 2: \
GPIOB->BSRR = (uint32_t)(GPIO_PIN_10); \
break; \
case 3: \
GPIOB->BSRR = (uint32_t)(GPIO_PIN_11); \
break; \
} \
}
/* USER CODE END Defines */
GPIO의 출력 대상을 선택하는 데 사용되기 때문에 TASKTAG를 유효화합니다.그런 다음 STM32 라이브러리를 읽은 후 OUT/IN에서 GPIO를 실행합니다.처리를 마치면 OUT에서 GPIO 비트를 지우고 작업을 시작할 때 IN에서 GPIO 비트를 설정합니다.또한 IN은 pxTaskTag을 사용하여 설정한 비트를 선택합니다.
매크로가 정의되면 임의로 불릴 수 있지만 GPIO의 초기화와 표시의 설정이 필요합니다.
GPIO의 초기화는
MX_GPIO_Init();
이후 또는 적절한 장소에서 수행됩니다.GPIO 초기화
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {
.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11,
.Mode = GPIO_MODE_OUTPUT_PP,
.Pull = GPIO_NOPULL,
.Speed = GPIO_SPEED_FREQ_VERY_HIGH,
};
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
감시하고 싶은 작업 중 vTaskSetApplicationTaskTag(NULL, (void *)1);
처럼 표시를 설정합니다.예를 들면 아래의 느낌.
void StartDefaultTask(void const *argument)
{
/* USER CODE BEGIN 5 */
vTaskSetApplicationTaskTag(NULL, (void *)1);
/* Infinite loop */
for (;;)
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, (HAL_GetTick() % 1000) < 100 ? GPIO_PIN_SET : GPIO_PIN_RESET);
osDelay(1);
}
/* USER CODE END 5 */
}
이 경우 HAL은 1ms 간격으로GetTick을 읽으면 PD2에 너비 10% 주기 1sec의 펄스가 발생하고 실행 중task1의 핀이 설정됩니다(이번 예는 PB9).주의점
확인되지 않았으나 심한 처리를 중단하면 정상적으로 감시할 수 없을 것 같습니다. (중단은 RTOS의 관할 범위에 속하지 않기 때문에 OUT/IN 처리를 할 수 없습니다.)
새치기를 포함한 시점을 확인하려면 새치기나 출타 시점에 책임을 지고 GPIO를 돌릴 필요가 있다.
이번에는 가끔 시동을 걸 때 다운된다.
pxCurrentTCB
는 NULL에서 초기화된 것으로 RTOS가 실행되기 전에 SysTick이 상하문 스위치를 호출하여 traceTASK_SWITCHED_IN
에서 NULL을 참조하면 떨어질 것 같다.대책으로는
traceTASK_SWITCHED_IN
에서 NULL이 아닌 것을 확인하거나, RTOS를 시작하기 전에 SysTick을 중지하는 방법 등을 고려할 수 있다.응용 프로그램
이번에는 각 임무에 대해 GPIO를 할당했고 다른 방법도 사용할 수 있다.예를 들어 정식 문서에서 DAC로 출력하고 오실로그래프로 전압을 보고 임무를 식별한다.이 외에도 빠른 출력(SPI 등) 방법을 사용할 수 있습니다.이 방법이라면 비교적 적은 GPIO로 많은 정보(8비트와 16비트)를 출력할 수 있다.
Reference
이 문제에 관하여(FreeRTOS 작업 추적), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/amutou/items/8930168ea2bcdfa1d759텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)