VDK API для получения информации инструментальной сборки
Добавил(а) microsin
Отладочная информация, которую собирает инструментальная сборка приложения VDK (эта информация отображается выбором пунктов меню View -> VDK Windows во время работы сессии отладки, см. [3, 4]), может быть доступна в коде приложения с помощью вызовов соответствующего API.
Функция
Краткое описание
Thread
Kernel
ISR
Startup
GetClockFrequency
Получение тактовой частоты ядра в МГц.
+
-
-
+
SetClockFrequency
Установка тактовой частоты ядра в МГц.
+
-
-
+
GetContextRecordSize
Показывает размер памяти для потока, необходимой для сохранения контекста при переключениях между потоками.
Получение информации по максимальному использованию стека потока.
+
-
-
-
GetThreadStack2Usage
То же самое, что и GetThreadStackUsage, только для потоков систем, где применяются процессоры с двумя стеками.
+
-
-
-
InstrumentStack
Запуск сбора статистики по стеку потока.
+
-
-
-
GetThreadStatus
Получение состояния потока (активен, заблокирован, готов к запуску).
+
-
-
-
GetTickPeriod
Получение длительности тика в миллисекундах.
+
+
+
+
SetTickPeriod
Установка длительности тика в миллисекундах.
+
-
-
+
GetUptime
Сколько система проработала времени, в тиках.
+
+
+
+
GetVersion
Получение информации о библиотеках VDK.
+
+
+
+
LogHistoryEvent
Запись в лог информации.
+
+
-
-
ReplaceHistorySubroutine
Замена встроенной процедуры записи в лог на пользовательскую функцию.
+
+
-
-
В столбцах Thread, Kernel, ISR и Startup показана доступность функции соответственно в коде потока, коде ядра, коде обработчика прерывания и коде начального запуска ("+" функцию можно использовать, "-" функция не доступна).
Возвращает тактовую частоту (в мегагерцах). Значение частоты указывается как часть конфигурации проекта VDK, и это значение можно поменять runtime вызовом функции SetClockFrequency(). В зоне ответственности разработчика гарантировать соответствие этой частоты используемому аппаратному обеспечению. Функция GetClockFrequency не вовлекает планировщик, и время выполнения этой функции фиксированное.
Примечание: реальное значение тактовой частоты процессора может не соответствовать значению, которое вернет функция GetClockFrequency. Например, если использовался библиотечный модуль управления питанием системных служб (services.h), и частота процессора была установлена вызовом функции adi_pwr_Init, то реальную частоту CPU и системной шины можно получить вызовом функции adi_pwr_GetFreq.
Установит тактовую частоту в мегагерцах, равной значению параметра inFrequency. Тактирование останавливается, параметры тактирования пересчитываются с использованием новой частоты тактирования, после чего тактирование возобновляется. В зоне ответственности разработчика гарантировать соответствие этой частоты используемому аппаратному обеспечению. Функция GetClockFrequency не вовлекает планировщик, и время выполнения этой функции не определенное.
Это API применимо только для процессоров Blackfin и SHARC. Функция вернет размер области памяти, требуемой для сохранения информации потоков во время переключения контекста.
Для любых приложений Blackfin, которые вручную выделяют память под стек потока, функция GetContextRecordSize() может использоваться для определения дополнительного количества памяти, которое нужно добавить к размеру стека.
Функция GetContextRecordSize не вызывает запуск планировщика, и её время выполнения фиксировано.
Транслирует идентификатор кучи HeapID (как он был сконфигурирован на закладке Kernel окна свойств проекта VDK) в индекс кучи, который можно передать функциям heap_malloc(), heap_calloc(), heap_realloc() и heap_free() [2].
Функция GetHeapIndex не вызывает запуск планировщика, и её время выполнения фиксировано.
Обработка ошибок с применением инструментальной сборки: значение ошибки kInvalidHeapID покажет, что inHeapID является недопустимым идентификатором кучи.
Вернет указатель на выделенный указатель данных на поток, определенный пользователем. Этот указатель может быть использован в потоках C или ассемблера для удержания локального состояния потока; например, через него может быть получен доступ к переменным потока (member variables).
Функция GetThreadHandle не вызывает запуск планировщика, и её время выполнения фиксировано.
Вернет идентификатор текущего работающего потока, или вернет VDK_KERNEL_LEVEL_, если функция отработала на уровне ядра. Функция не вызывает запуск планировщика, и её время выполнения фиксировано.
Получает информацию по максимальному использованию стека указанного потока в момент вызова функции (размер стека будет возвращен в 32-битных словах). Для приложений, которые были собраны с установкой "Full Instrumentation", будет возвращено максимальное использование стека либо с момента создания потока, либо с момента последнего API-вызова InstrumentStack(). Для приложений, которые были собраны не с установкой "Full Instrumentation", информация о стеке потоков по умолчанию недоступна. Таким образом, эта функция не вернет какую-либо значимую информацию в этих случаях, за исключением случая, когда ранее была вызвана функция InstrumentStack() для сбора инструментальной информации по стеку потоков.
Функция GetThreadStackUsage не вызывает запуск планировщика, и её время выполнения не определено.
Обработка ошибок с применением инструментальной сборки: значение ошибки kUnknownThread покажет, что в параметре был передан недопустимый идентификатор потока.
Вернет максимальное используемое пространство стека stack2 для указанного потока в момент вызова функции (размер стека будет возвращен в 32-битных словах). Для приложений, которые были собраны с установкой "Full Instrumentation", будет возвращено максимальное использование стека либо с момента создания потока, либо с момента последнего API-вызова InstrumentStack(). Для приложений, которые были собраны не с установкой "Full Instrumentation", информация о стеке потоков по умолчанию недоступна. Таким образом, эта функция не вернет какую-либо значимую информацию в этих случаях, за исключением случая, когда ранее была вызвана функция InstrumentStack() для сбора инструментальной информации по стеку потоков.
Примечание: это API применимо только к некоторым процессорам, которые используют два стека. В настоящий момент это семейство процессоров ADSP-TSxxx.
Функция GetThreadStack2Usage не вызывает запуск планировщика, и её время выполнения не определено.
Обработка ошибок с применением инструментальной сборки: значение ошибки kUnknownThread покажет, что в параметре был передан недопустимый идентификатор потока.
Запускает сбор информации по стеку вызвавшего потока, чтобы впоследствии можно было определить максимальный объем стека, который использовал поток. API-вызов GetThreadStackUsage() возвратит максимальное использование стека, для которого был запущен сбор инструментальной информации.
Если использовались библиотеки с полной поддержкой инструментальной информации, то вызывать функцию InstrumentStack не требуется, потому что запуск сбора инструментальной информации осуществляется в момент создания потока. В этом случае InstrumentStack() используется для сброса статистики по стеку, чтобы можно было охватить не используемые в настоящий момент области стека (например, когда надо определить, сколько стека использует выполнение определенной секции кода). Если использовались библиотеки без полной поддержки инструментальной информации, то по умолчанию статистика по сбору инструментальной информации стека не запущена, и нужно использовать InstrumentStack(), чтобы вызовы GetThreadStackUsage() давали корректную информацию.
Функция InstrumentStack не вызывает запуск планировщика, и её время выполнения не определено.
Устанавливает период типа в inPeriod миллисекунд. Тактирование останавливается, и параметры тактирования вычисляются заново для новой длительности тика, после чего тактирование возобновляется.
Функция SetTickPeriod не вызывает запуск планировщика, и её время выполнения не определено.
Тип VersionStruct это структура, содержащая 4 целых числа. Числа описывают системные параметры: номер версии VDK API, поддерживаемое семейство процессоров, базовый поддерживаемый процессор и номер сборки.
//Прототип C++:
typedefstruct
{
int mAPIVersion;
VDK::DSP_Family mFamily;
VDK::DSP_Product mProduct;
long mBuildNumber;
} VDK::VersionStruct;
mAPIVersion это целое число в формате 0xMMmmUURR, где MM это главный номер версии (major version number), mm это младший номер версии (minor version number), UU это номер обновления (update number), и RR зарезервировано для будущего использования. Поле mAPIVersion не меняется в любом релизе VisualDSP++, кроме случаев, когда меняется VDK API. Подробнее см. описание типов DSP_Family и DSP_Product.
Примечание: разные процессоры могут использовать общий набор библиотек VDK. По этой причине поле mProduct может не соответствовать процессору в конкретном приложении.
voidVDK_LogHistoryEvent(VDK_HistoryEnum inEnum, int inValue);
//Прототип C++:
void VDK::LogHistoryEvent(VDK::HistoryEnum inEnum, int inValue);
Добавляет запись в буфер истории (history buffer). Эта функция не выполняет никаких действий, если проект не был линкован на этапе сборки с библиотеками, поддерживающими полную инструментальную информацию (fully instrumented libraries).
Функция LogHistoryEvent не вызывает запуск планировщика, и её время выполнения фиксированное.
Параметр inEnum это значение перечисления, показывающее тип события. Параметр inValue, смысл которого зависит от значения перечисления.
Позволяет заменить механизм VDK для записи истории в лог (VDK history logging) на подпрограмму inFunc, которую определит пользователь.
Из-за того, что механизм записи в лог может быть использован из потока, ядра и обработчика прерывания, функция inFunc должна удовлетворять определенным требованиям (см. секцию "Замена механизма записи в лог истории").
Аргументы, передаваемые в функцию inFunc, являются полями структуры HistoryEvent. VDK устанавливает аргументы для inFunc в следующих регистрах, см. таблицу.
Таблица 3-1. В каких регистрах размещены аргументы подпрограммы записи в лог истории.
Аргумент
Тип
Blackfin
TigerSHARC
SHARC
Время
VDK::Ticks
R3
J7
R0
Тип события
VDK::HistoryEnum
R0
J4
R4
Значение
int
R1
J5
R8
Идентификатор потока
VDK::ThreadID
R2
J6
R12
Подпрограмма, определенная пользователем, может вызвать VDK_ISRAddHistoryEvent() для добавления событий в кольцевой буфер VDK, чтобы отобразить события в окне VDK History. VDK_ISRAddHistoryEvent() принимает те же самые аргументы, в тех же регистрах, что и inFunc. VDK_ISRAddHistoryEvent() вызывается библиотекой VDK по умолчанию, если не был заменен оригинальный механизм регистрации истории (VDK history mechanism). ReplaceHistorySoubroutine() может быть вызвана в момент старта приложения VDK (из кода startup) или в конструкторе глобальной переменной, и её вызов доступен только при полном наличии инструментальных библиотек в сборке приложения VDK (fully instrumented libraries).
Функция ReplaceHistorySubroutine не вызывает запуск планировщика, и её время выполнения фиксированное.
[Замена механизма записи в лог истории]
Механизм записи в лог истории (VDK history logging) сохраняет событие (history event) в кольцевой буфер с помощью API-вызова VDK_ISRAddHistoryEvent(). Пользователи могут поменять поведение этого механизма, заменив вызов VDK_ISRAddHistoryEvent() с помощью API-функции ReplaceHistorySubroutine() (см. описание этой функции в соответствующей врезке).
Новая функциональность позволит сделать более гибкой запись событий в момент их возникновения. VDK может записывать в лог информацию из кода уровня потока, ядра и обработчика прерывания, поэтому пользовательская подпрограмма записи в лог вызывается всегда в момент, когда прерывания запрещены, и эта функция должна удовлетворять определенным правилам:
• Она должна быть написана на ассемблере, и не может рассчитывать на наличие поддержки со стороны кода C при выполнении программы (C run-time environment недоступен). • Она не должна вызвать какие-либо функции, которые подразумевают наличие C run-time environment. • Она не должна вызывать никакие функции VDK API. • Одна должна сохранять на входе и восстанавливать на выходе все регистры, которые использует либо явно, либо косвенно. • Вызовы этой пользовательской функции для записи в лог не должны выполняться из какой-либо другой части приложения VDK. • Она должна использоваться только для трассировки/мониторинга активности системы с целью отладки или анализа поведения системы, и она не должна использоваться для построения функционала приложения, и не должна никак на него влиять.
Код, функции, которая пишет в лог, получает при вызове следующие аргументы:
• Время в тиках, когда произошло записываемое в лог событие. • Значение из перечисления HistoryEnum, которое описывает событие. • Целое число, используемое для сохранения в логе дополнительной информации о событии. • Идентификатор потока.
Аргументы, передаваемые в подпрограмму записи в лог, являются составляющими типа данных VDK (полями структуры) HistoryEvent.
Перед вызовом пользовательской функции истории аргументы для неё помещаются в соответствующие регистры (см. таблицу 3-1 во врезке с описанием функции ReplaceHistorySubroutine).
Пользователь может вызвать VDK_ISRAddHistoryEvent() из своего кода, который пишет в лог, если он хочет сохранить информацию в буфер VDK history. Процедура VDK_ISRAddHistoryEvent() должна вызываться только из пользовательской функции записи в лог, и она не должна вызваться ни из какой другой части приложения. VDK_ISRAddHistoryEvent() ожидает появления аргументов в тех же регистрах, что перечислены в таблице 3-1 (см. врезку с описанием функции ReplaceHistorySubroutine).
Примечание: может быть, что окно VDK History будет не в состоянии отобразить выполнение потоков, которые работают в приложении, если события kThreadSwitched или kThreadStatusChange были удалены, либо были использованы неправильно.