Цитата(elektronshik @ Feb 13 2009, 10:22)

Дык помогите кто-нибудь по конкретнее (всмысле куском кода ). Не поверю что никто из читавших тему этого не делал.
Пока без коментариев, нет времени. Позднее, если будет необходимо, могу прокоментировать.
Фрагмент FreeRTOS_stats.h
Код
#if FREERTOS_TASK_STATS
#define traceTASK_INCREMENT_TICK(xTickCount) TraceIncrementTick(xTickCount)
#define traceTASK_SWITCHED_OUT() TraceSwitchedOut(pxCurrentTCB->uxTCBNumber, pxCurrentTCB)
#define traceTASK_SWITCHED_IN() TraceSwitchedIn(pxCurrentTCB->uxTCBNumber)
#define traceTASK_DELETE(xTCB) TraceTaskDelete(xTCB);
// Максимальное количество задач, для которых ведется статистика
#define MAX_TASK_STATS 15
// Период времени в тиках, на протяжении которого производится подсчет интервальной статистики
#define TIME_COUNTING_INTERVAL 1000
// Количество тиков PIT таймера на одно переполнение PIT таймера (т.е. на один тик системного таймера)
#define PIT_COUNTER_PERIOD (( ( ( configCPU_CLOCK_HZ / 16 ) / 1000UL ) * (1000 / configTICK_RATE_HZ) ) + 1)
// ------------------------------------------------------------------------------
// Статистика активности задачи
struct STFRTaskStat
{ unsigned RunningST; // Время работы задачи от момента старта (в системных тиках)
unsigned RunningPT; // Параметр уточняющий RunningST, значение в тиках PIT таймера (частота MCK/16)
unsigned Switches; // Количество переключений задачи от момента старта
unsigned STLastInterval; // Время работы задачи на предыдущем интервале измерения (в системных тиках)
unsigned PTLastInterval; // Параметр уточняющий STLastInterval, значение в тиках PIT таймера
unsigned SwitchesLastInterval; // Количество переключений задачи на предыдущем интервале времени
unsigned STCounter; // Время работы задачи от момента tasks_start_intervalST (в системных тиках)
unsigned PTCounter; // Параметр уточняющий STCounter, значение в тиках PIT таймера
unsigned SwitchesCounter; // Количество переключений задачи от момента StartTickCount
unsigned TaskEnterST; // Момент времени входа в задачу (в системных тиках)
unsigned TaskEnterPT; // Параметр уточняющий TaskEnterST, значение в тиках PIT таймера
char pcTaskName[ configMAX_TASK_NAME_LEN ]; // Имя задачи
void *xTask; // Дискриптор задачи
unsigned InitFlag; // Флаг инициализации структуры ос статистикаой
};
#endif /* FREERTOS_TASK_STATS */
#if FREERTOS_STATS
// ------------------------------------------------------------------------------
// Структура описания статистики
struct STFRStat
{
#if FREERTOS_TASK_STATS
struct STFRTaskStat tasks[MAX_TASK_STATS]; // Статистика задач
unsigned tasks_start_intervalST; // Момент начала интервала измерения (используется для вычисления STLastInterval)
#endif
};
extern struct STFRStat FreeRTOS_stats;
#endif /* FREERTOS_STATS */
Фрагемент FreeRTOS_stats.c
Код
// ver 1.02 (16.11.2008)
// Модуль предназначен для сбора, хранения и управления статистикой работы FreeRTOS
// и пользовательских задач в его окружении
// Также, модуль может выполнять контроль за переполнение стека задач
/* Library includes. */
#include <string.h>
#include <stdbool.h>
/* Hardware specific headers. */
#include "Board.h"
#include "AT91SAM7X256.h"
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "FreeRTOSConfig.h"
// Статистика FreeRTOS
#if FREERTOS_STATS
struct STFRStat FreeRTOS_stats;
#endif
// Счетчик тиков таймера
unsigned CurrentTickCount;
#if FREERTOS_TASK_STATS
// ------------------------------------------------------------------------------
// Функция вызывается системой FreeRTOS после обработки системного тика
inline void TraceIncrementTick(portTickType TickCount)
{ CurrentTickCount=TickCount;
}
// ------------------------------------------------------------------------------
// Функция вызывается системой FreeRTOS перед сменой планировщиком текущей задачи.
// Входные параметры:
// TaskNumber - номер задачи, которая прервана планировщиком
// hTask - дискриптор задачи (которая прервана планировщиком)
void TraceSwitchedOut(portBASE_TYPE TaskNumber, xTaskHandle xTask)
{ static unsigned PTPos;
static unsigned PTOv;
static long PTCount;
static struct STFRTaskStat *TaskStat;
if (TaskNumber< MAX_TASK_STATS)
{ // Запоминаем значение счетчика PIT таймера - параметра определяющего точное значение текущего времени
PTPos=AT91C_BASE_PITC->PITC_PIIR;
PTOv= (PTPos & AT91C_PITC_PICNT) >> 20;
PTPos &= AT91C_PITC_CPIV;
// Выделяем адрес структуры статистики текущей задачи (для увеличесния скорости доступа)
TaskStat= &FreeRTOS_stats.tasks[TaskNumber];
// Увеличесние счетчиков количества переключений задачи
TaskStat->Switches++;
TaskStat->SwitchesCounter++;
// Если код выполняется впервые - инициализируем
if (CurrentTickCount - TaskStat->TaskEnterST > 10)
{ TaskStat->TaskEnterST=CurrentTickCount;
TaskStat->TaskEnterPT=PTPos;
}
// Определение точного времени выполнения задачи
PTCount = (CurrentTickCount - TaskStat->TaskEnterST + PTOv) * PIT_COUNTER_PERIOD + (PTPos - TaskStat->TaskEnterPT);
if (PTCount < 0)
PTCount+=PIT_COUNTER_PERIOD;
// Увеличение счетчиков времени выполнения задачи
TaskStat->PTCounter+=PTCount;
while (TaskStat->PTCounter >= PIT_COUNTER_PERIOD)
{ TaskStat->STCounter++;
TaskStat->PTCounter -= PIT_COUNTER_PERIOD;
}
// Если задача вытесняется впервые - выполняем копирования имени задачи
if (TaskStat->InitFlag==false)
{ TaskStat->xTask=xTask;
TaskStat->InitFlag=true;
memcpy(TaskStat->pcTaskName, (char *)((unsigned)xTask+52),16);
}
// Если необходимо - подсчитываем параметры времени выполнения задач за предыдущий интервал (если он завершен)
if (CurrentTickCount - FreeRTOS_stats.tasks_start_intervalST >= TIME_COUNTING_INTERVAL)
{ for (int i=0;i < MAX_TASK_STATS; i++)
{ TaskStat=&FreeRTOS_stats.tasks[i];
// Увеличение счетчика времени выполнения задачи
TaskStat->RunningST += TaskStat->STCounter;
TaskStat->RunningPT += TaskStat->PTCounter;
while (TaskStat->RunningPT >= PIT_COUNTER_PERIOD)
{ TaskStat->RunningST++;
TaskStat->RunningPT -= PIT_COUNTER_PERIOD;
}
// Обновление данных о активности задачи за предыдущий интервал времени
TaskStat->STLastInterval = TaskStat->STCounter;
TaskStat->PTLastInterval = TaskStat->PTCounter;
TaskStat->SwitchesLastInterval = TaskStat->SwitchesCounter;
// Очистка текущих счетчиков
TaskStat->STCounter=0;
TaskStat->PTCounter=0;
TaskStat->SwitchesCounter=0;
}
// Стартовая метка времени начинающегося интервала
FreeRTOS_stats.tasks_start_intervalST=CurrentTickCount;
}
}
}
// ------------------------------------------------------------------------------
// Функция вызывается системой FreeRTOS после выбора планировщиком новой текущей задачи.
// Входные параметры:
// TaskNumber - номер задачи, которая сейчас будет запущена планировщиком
void TraceSwitchedIn(portBASE_TYPE TaskNumber)
{ if (TaskNumber< MAX_TASK_STATS)
{ FreeRTOS_stats.tasks[TaskNumber].TaskEnterST = CurrentTickCount;
FreeRTOS_stats.tasks[TaskNumber].TaskEnterPT = (AT91C_BASE_PITC->PITC_PIIR) & AT91C_PITC_CPIV;
}
}
// ------------------------------------------------------------------------------
// Функция вызывается системой при удалении задачи
// Входные параметры:
// xTCB - дискриптор удаляемой задачи
void TraceTaskDelete(xTaskHandle xTCB)
{ for (int i=0; i < MAX_TASK_STATS; i++)
if (FreeRTOS_stats.tasks[i].xTask==xTCB)
{ FreeRTOS_stats.tasks[i].xTask=NULL;
break;
}
}
#endif /* FREERTOS_TASK_STATS */