VDK: служба таймеров |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
В этой статье приведен перевод раздела "Timer Service" из документации "VisualDSP++ 5.0 Device Drivers and System Services Manual for Blackfin® Processors" [1]. Описывается Служба Таймеров, предоставляющая простой в использовании интерфейс программирования (API) для доступа к таймеру ядра, сторожевому таймеру (watchdog), таймерам общего назначения процессора Blackfin. Рассматриваются следующие вопросы: • Общее описание работы Службы Таймеров Используя возможности других системных служб, Служба Таймеров позволяет клиенту управлять всеми таймерами и координировать их работой стандартным способом, независимо от используемого целевого процессора. Служба Таймеров также предоставляет для клиентов такую функцию, как callback, позволяющую оповещать о событиях истечения заданного времени таймера. Прим. переводчика: под "клиентом" подразумевается код программы приложения или код потока (для многопоточных приложений). Для поддержки всех функций Службы Таймеров требуется использование Менеджера Прерываний [2] и Менеджера DCB [3]. Если вызовы callback-функций делаются не откладываемыми, а немедленно исполняемыми в обработчике прерывания таймера, то Менеджер DCB не нужен. Если callback-функции не нужны, то тогда не нужен ни Менеджер Прерываний, ни Менеджер DCB. Чтобы уменьшить необходимое количество ножек корпуса процессора, выводы таймеров иногда совмещаются на тех же выводах, которые используют другие периферийные устройства. Служба Таймеров не предоставляет функционал арбитража для управления мультиплексированием вывода процессора. Поэтому программа клиента должна гарантировать, чтобы периферийное устройство и Служба Таймеров не использовали один и тот же вывод одновременно. Для процессоров ADSP-BF531, ADSP-BF532, ADSP-BF533 и процессоров ADSP-BF561, это требует гарантии корректной установки соответствующих регистров управления периферийными устройствами. Для ADSP-BF534, ADSP-BF536, ADSP-BF537 (и будущих) процессоров Служба Таймеров автоматически привлекает службу управления портами, чтобы повлиять на любые изменения в мультиплексоре вывода. При этом никакое вмешательство пользователя не требуется. Служба Таймеров использует недвусмысленное соглашение об именовании, обеспечивающее отсутствие конфликтов имен с другими программными библиотеками от Analog Devices или других источников кода. Все значения перечислений и операторы typedef используют префикс ADI_TMR_, и функции и глобальные переменные используют эквивалентный префикс в нижнем регистре adi_tmr_. Каждая функция в интерфейсе программирования (API) Службы Таймеров возвратит код ошибки из перечисления типа ADI_TMR_RESULT. Как и у всех системных служб, возвращаемое значение 0 (ADI_TMR_RESULT_SUCCESS) показывает отсутствие ошибок. Не нулевое значение показывает ошибку. Как и у всех системных служб, коды ошибок Службы Таймеров являются уникальными, отличающимися от всех других системных служб. Подключаемый файл adi_tmr.h перечисляет все коды ошибки, которые возвращает Служба Таймеров. Проверка параметров в отладочных версиях библиотеки Системных Служб предоставляют более полный тест параметров API-функции и условий, которые могут привести к ошибкам. Компания Analog Devices настоятельно рекомендует разрабатывать приложения с помощью debug-версий библиотеки Системных Служб, и заключительное тестирование и окончательную разработку следует выполнять на release-версии библиотеки. [Общее описание работы Службы Таймеров] В этом разделе описаны общие принципы работы Службы Таймеров. Подробное описание каждой функции см. в разделе "Интерфейс программирования (API) Службы Таймеров". Инициализация Службы Таймеров. Перед использованием Службы Таймеров клиент должен должен сначала её инициализировать. Для этого клиент передает функции инициализации adi_tmr_Init() параметр, который передается функции критического региона, чтобы защитить регион кода. Также опционально в функцию инициализации передается непрерывный блок памяти, чтобы служба могла использовать функции обратного вызова (callback). Если клиент задал использование callback-функции, то её вызов будет срабатывать, когда время таймера истекло. См. секцию "Функции обратного вызова (callback)" для получения дополнительной информации о функционировании callback-ов. В отличие от других системных служб, когда клиент предоставляет службе память, чтобы она могла работать, Служба Таймеров не требует никакой дополнительной памяти. Завершение работы Службы Таймеров. Когда клиенту больше не нужна функциональность Службы Таймеров, вызывается функция завершения adi_tmr_Terminate(). Эта функция деинсталлирует все инсталлируемые callback-и таймеров и закрывает все открытые таймеры. Идентификаторы таймеров (Timer ID). Всем функциям API Службы таймеров, кроме функций инициализации и завершения, передается параметр, который идентифицирует управляемый таймер. Подключаемый файл для службы таймеров adi_tmr.h, задает идентификаторы таймеров, поддерживаемые используемым процессором. Параметр timer ID определен как тип u32, но это не простое значение перечисления. В действительности timer ID это комплексное значение, которое содержит информацию, специфичную для таймера, и которую можно объединить операцией ИЛИ таким образом, что несколько таймеров можно разрешить или запретить одновременно. Базовые функции таймеров. Функции, описанные в этом разделе, являются общими для всех типов таймеров: таймеры общего назначения, таймер ядра, сторожевой таймер. В эти функции может быть передан любой индивидуальный идентификатор таймера (timer ID), независимо от того, к какому таймеру этот идентификатор относится - таймеру общего назначения, таймеру ядра или сторожевому таймеру. adi_tmr_Open. Функция adi_tmr_Open() вызывается, чтобы открыть таймер. В зависимости от используемого процессора Blackfin, эта функция инициализирует аппаратуру, необходимую для работы таймера. Эта функция также сбрасывает таймер в его настройки по умолчанию. См. также описание функции во врезке adi_tmr_Open. adi_tmr_Close. Когда таймер больше не нужен вызывается функция adi_tmr_Close(), чтобы закрыть и выключить таймер. В настоящее время для всех процессоров Blackfin эта функция ничего не делает, а только возвращает управление в вызывающий код. Будущие типы процессоров Blackfin могут потребовать от этой функции каких-нибудь манипуляций с аппаратурой, когда закрывается таймер. См. также описание функции во врезке adi_tmr_Close. adi_tmr_Reset. Если приложение должно сбросить таймер в настройки по умолчанию в любое время, а не когда таймер открывается, оно использует функцию adi_tmr_Reset(). Регистры конфигурации таймера сбрасываются в свое значение по умолчанию, которое устанавливается при включении питания, статус ошибки очищается, и т. д. См. также описание функции во врезке adi_tmr_Reset. Функции таймеров общего назначения. В этой секции описаны функции, применяемые только для обычных таймеров. Как правило, в процессоре Blackfin таких таймеров несколько. Эти функции вернут ошибку, если в них будет передан неправильный идентификатор таймера, такой как core timer ID или watchdog timer ID. adi_tmr_GPControl. Функция adi_tmr_GPControl() конфигурирует таймер общего назначения. В эту функцию передается timer ID, идентификатор команды (command ID), указывающий адресуемый параметр функции, и параметр, зависящий от команды. Список идентификаторов команд, применимый для таймеров общего назначения и соответствующие командам параметры описаны во врезке ADI_TMR_GP_CMD. См. также описание функции во врезке adi_tmr_GPControl. adi_tmr_GPGroupEnable. Функция adi_tmr_GPGroupEnable() разрешает или запрещает таймер общего назначения или сразу группу таймеров общего назначения. В эту функцию передается параметр, в котором задан либо один идентификатор таймера, либо сразу несколько, объединенных друг с другом операцией ИЛИ. Также передается флаг, показывающий, что нужно сделать с таймером или группой таймеров - разрешить (если значение флага TRUE) или запретить (если значение флага FALSE). Эта функция предпринимает все возможные меры, чтобы одновременно разрешить или запретить группу таймеров. Если нижележащая аппаратура определенного процессора Blackfin позволяет для таймеров одновременное управление, то функция предпринимает необходимые действия для одновременного разрешения или запрета таймеров. Если же нижележащая аппаратура не позволяет для указанного таймера одновременное управление, то функция пытается разрешить или запретить таймеры максимально быстро, как это только возможно. См. также описание функции во врезке adi_tmr_GPGroupEnable. Функции таймера ядра. Описанные в этой секции функции используются только для таймера ядра (core timer). adi_tmr_CoreControl. Функция adi_tmr_CoreControl() используется для конфигурирования таймера ядра. Аналогично функции управления таймерами общего назначения, эта функция принимает идентификатор команды, указывающую адресуемый параметр функции, и параметр, зависящий от команды. Список команд, применимых к таймеру ядра, и соответствующих зависящих от команды параметров описан во врезке ADI_TMR_CORE_CMD. См. также описание функции во врезке adi_tmr_CoreControl. Функции сторожевого таймера. Описанные в этой секции функции используются только для сторожевого таймера (watchdog timer). adi_tmr_WatchdogControl. Функция adi_tmr_WatchdogControl() конфигурирует сторожевой таймер. Аналогично функциям управления таймерами общего назначения и таймером ядра, эта функция принимает идентификатор команды, указывающую адресуемый параметр функции, и параметр, зависящий от команды. См. также описание функции во врезке adi_tmr_WatchdogControl. Список команд, применимых к сторожевому таймеру, и соответствующих зависящих от команды параметров описан во врезке ADI_TMR_WDOG_CMD. Функции таймеров периферийного устройства. Функции, описанные в этой секции, используются только для таймеров общего назначения и сторожевого таймера. Передача идентификатора таймера ядра в эти функции приведет к ошибке, которая будет возвращена в вызывающий код. adi_tmr_GetPeripheralID. Функция adi_tmr_GetPeripheralID() может быть вызвана, чтобы определить идентификатор периферийного устройства (peripheral ID) для указанного таймера. Хотя эта функция обычно не нужна, она все-таки может быть полезна, если требуется более изощренная логика управления прерыванием, чем может быть предоставлена Службой Таймеров. Значение peripheral ID может быть передано в функции обслуживания прерывания. Имейте в виду, что таймер ядра не имеет связанного peripheral ID, потому что таймер ядра привязан к фиксированному уровню IVG. Несмотря на это, идентификатор таймера ядра может быть передан в эту функцию, и она не возвратит код ошибки. См. также описание функции во врезке adi_tmr_GetPeripheralID. Функции обратного вызова (callback). Как и другие системные службы, Служба Таймеров использует механизм callback-ов, чтобы оповещать клиента об асинхронных событиях, таких как истечение времени таймера. Callback-и могут использоваться для всех типов таймеров: таймеры общего назначения, таймер ядра, сторожевой таймер. Таймеры процессора Blackfin могут конфигурироваться для генерации прерываний. Служба Таймеров предоставляет внутренний обработчик прерывания (ISR), который обрабатывает прерывания от аппаратуры таймеров. Этот ISR делает соответствующие вызовы в callback-функции клиентского приложения. Когда клиент устанавливает callback на таймер, параметр для функции установки диктует, как будет использоваться callback-немедленно (live) или его выполнение будет отложено (deferred). Live callback-и выполняются прямо в контексте обработчика прерывания, а отложенные callback-и выполняются после завершения ISR, с меньшим приоритетом, с помощью Службы DCB [3]. Когда используется возможность callback для Службы Таймеров, клиентам не надо предпринимать никакие программные действия вне API Службы Таймеров. Не требуется делать вызовы Менеджера Прерываний [2] или Службы DCB [3], кроме инициализации этих служб при необходимости. Обратите внимание, что для клиентов доступны все возможности Службы Таймеров, и можно не использовать любую из возможностей callback-функции. adi_tmr_InstallCallback. Функция adi_tmr_InstallCallback() используется для установки callback для указанного таймера. В дополнение к идентификатору таймера (timer ID), клиент предоставляет флаг пробуждения (wakeup flag), адрес callback-функции, хендл клиента и хендл Службы DCB. Флаг пробуждения задает, должен ли процессор выходить из состояния пониженного энергопотребления (low-power state), когда происходит событие таймера. Адрес callback-функции задает функцию обратного вызова типа ADI_DCB_CALLBACK_FN (см. описание Менеджера DCB [3] для получения подробной информации). Будучи вызванной, callback-функция получает следующие 3 параметра: • ClientHandle – значение, предоставленное клиентом при инсталляции callback Когда функции установки callback adi_tmr_InstallCallback был передан параметр хендла Службы DCB, равный NULL, callback-функция будет выполняться немедленно (live), прямо в коде ISR. Если же хендл Службы DCB не NULL, то Служба Таймеров использует Службу DCB для запуска callback-функции. Одна callback-функция может быть установлена и использована для любого количества таймеров; при этом callback-функция может использовать параметр TimerID, чтобы определить, какой таймер сгенерировал callback. Однако обратите внимание, что что на определенный таймер может быть инсталлирована только одна callback-функция. Функция установки callback не изменяет управление таймером. Подробнее см. описание функции во врезке adi_tmr_InstallCallback. adi_tmr_RemoveCallback. Функция adi_tmr_RemoveCallback() используется при удалении callback-а для указанного таймера. Эта функция запрещает генерацию для таймера и удаляет callback из внутренних таблиц. Для этого таймера больше не будут срабатывать callback-и, пока не будет выполнена повторная установка callback. Функция удаления callback не меняет управление таймером. Подробнее см. описание функции во врезке adi_tmr_RemoveCallback. В этой врезке приведены примеры кода, иллюстрирующие, как получить доступ к таймерам и использовать их функционал через Службу Таймеров. Этот пример инициализирует Службу Таймеров, конфигурирует несколько таймеров общего назначения, таймер ядра и сторожевой таймер. Также показано использование callback-ов. Все функции Службы Таймеров возвращают коды ошибки, которые на практике должны быть проверены, чтобы убедиться в успешном завершении функции. Приведенные здесь примеры кода не делают этих проверок. Инициализация. Перед использованием Службы Таймеров она должна быть инициализирована. Следующий фрагмент инициализирует эту службу. ADI_TMR_RESULT Result; // возвращаемое значение Result = adi_tmr_Init(NULL); После завершения этой функции Служба Таймеров инсталлирована и готова к использованию. Эта функция не меняет ничего в настройках таймеров, она просто инициализирует внутренние структуры данных. Открытие таймера. После того, как служба инициализирована, можно открыть любые таймеры, которые нужны. В этом примере кода будут открыты 2 таймера общего назначения, таймер ядра и сторожевой таймер. Result = adi_tmr_Open(ADI_TMR_GP_TIMER_0); Result = adi_tmr_Open(ADI_TMR_GP_TIMER_1); Result = adi_tmr_Open(ADI_TMR_CORE_TIMER); Result = adi_tmr_Open(ADI_TMR_WDOG_TIMER); Функция открытия сбросит таймер в настройки по умолчанию, какие таймер получает после включения питания или сброса процессора, с очисткой любых ожидающих обработки состояний и т. д. Конфигурирование таймера. После того, как таймер открыт, его можно сконфигурировать. Функции adi_tmr_GPControl(), adi_tmr_CoreControl() и adi_tmr_WatchdogControl() используются для конфигурирования таймеров общего назначения, таймера ядра и сторожевого таймера соответственно. Каждой из этих функций предоставляется идентификатор команды, обычно задающей параметр для управления и значение параметра. Обратите внимание, что функции, управляющей таймером общего назначения, передается также и идентификатор таймера (потому что таймеров общего назначения в процессоре несколько). Команды для таймеров могут быть заданы индивидуально или совместно, как таблица. Следующий фрагмент кода иллюстрирует оба метода. ADI_TMR_CORE_CMD_VALUE_PAIR CoreTable [] = { { ADI_TMR_CORE_CMD_SET_COUNT, (void *)0x12345678 }, { ADI_TMR_CORE_CMD_SET_PERIOD, (void *)0xabcdef }, { ADI_TMR_CORE_CMD_SET_SCALE, (void *)0x10 }, { ADI_TMR_CORE_CMD_SET_ACTIVE_MODE, (void *)TRUE }, { ADI_TMR_CORE_CMD_END, NULL }, }; Result = adi_tmr_CoreControl(ADI_TMR_CORE_CMD_TABLE, CoreTable); Result = adi_tmr_GPControl(ADI_TMR_GP_TIMER_0, ADI_TMR_GP_CMD_SET_PERIOD, (void *)0x800000); Result = adi_tmr_GPControl(ADI_TMR_GP_TIMER_0, ADI_TMR_GP_CMD_SET_WIDTH, (void *)0x400000); Result = adi_tmr_GPControl(ADI_TMR_GP_TIMER_0, ADI_TMR_GP_CMD_SET_TIMER_MODE, (void *)0x1); Result = adi_tmr_GPControl(ADI_TMR_GP_TIMER_1, ADI_TMR_GP_CMD_SET_PERIOD, (void *)0x800000); Result = adi_tmr_GPControl(ADI_TMR_GP_TIMER_1, ADI_TMR_GP_CMD_SET_WIDTH, (void *)0x400000); Result = adi_tmr_GPControl(ADI_TMR_GP_TIMER_1, ADI_TMR_GP_CMD_SET_TIMER_MODE, (void *)0x1); Result = adi_tmr_WatchdogControl(ADI_TMR_WDOG_CMD_EVENT_SELECT, (void *)0x0); Result = adi_tmr_WatchdogControl(ADI_TMR_WDOG_CMD_SET_COUNT, (void *)0x12345678); Обратите внимание, что в вышеприведенном фрагменте был разрешен таймер ядра и сразу будучи сконфигурированным, и таймеры общего назначения, и сторожевой таймер разрешены не были. Любой таймер может быть разрешен через таблицу команд, обычно последней записью в таблице. В целях иллюстративного примера разрешение сторожевого таймера и таймеров общего назначения показаны отдельно в секции "Разрешение и запрет таймеров". Разрешение и запрет таймеров. После того, как таймер был сконфигурирован, его можно разрешить. Когда используется таблица команд, таймер может быть разрешен через команду в таблице, как показано в секции "Конфигурирование таймера". Обычно команда для разрешения таймера будет последней в таблице. Альтернативно таймеры могут быть разрешены отдельным вызовом подходящей управляющей функции. Далее таймеры общего назначения могут быть разрешены и запрещены группой. Следующий фрагмент показывает, как разрешить сторожевой таймер и затем одновременно (группой) разрешить таймеры общего назначения 0 и 1. Result = adi_tmr_WatchdogControl(ADI_TMR_WDOG_CMD_ENABLE_TIMER, (void *)TRUE); Result = adi_tmr_GPGroupEnable(ADI_TMR_GP_TIMER_0 | ADI_TMR_GP_TIMER_1, TRUE); Когда таймер запрещен, он может быть запрещен как часть таблицы команд (хотя это маловероятно). Чаще таймеры запрещаются через один вызов управляющей функции. Также , как и было в разрешении таймеров общего назначения, эти таймеры могут быть запрещены одновременно (группой). Следующий фрагмент кода иллюстрирует, как запретить сторожевой таймер и одновременно запретить сразу 2 таймера 0 и 1. Result = adi_tmr_WatchdogControl(ADI_TMR_WDOG_CMD_ENABLE_TIMER, (void *)FALSE); Result = adi_tmr_GPGroupEnable(ADI_TMR_GP_TIMER_0 | ADI_TMR_GP_TIMER_1, FALSE); Установка callback-функции. Хотя приложения могут установить аппаратные обработчики прерывания (ISR), чтобы напрямую обработать прерывания от таймеров (см. описание Менеджера Прерываний [2]), Служба Таймеров предоставляет простой, легкий в использовании механизм callback-функций, предоставляющий эквивалентный функционал. Следующий фрагмент кода иллюстрирует, как инсталлировать callback-функцию. Можно использовать отдельные функции для каждого таймера, или можно использовать одну callback-функцию для любого количества таймеров. Этот фрагмент показывает установку одной callback-функции для двух таймеров общего назначения, таймера ядра и сторожевого таймера. Оператор switch в callback-функции идентифицирует, какой таймер сгенерировал вызов callback-функции. ... Result = adi_tmr_InstallCallback(ADI_TMR_GP_TIMER_0, TRUE, (void *)0x00000000, NULL, Callback); Result = adi_tmr_InstallCallback(ADI_TMR_GP_TIMER_1, TRUE, (void *)0x11111111, NULL, Callback); Result = adi_tmr_InstallCallback(ADI_TMR_CORE_TIMER, TRUE, (void *)0x22222222, NULL, Callback); Result = adi_tmr_InstallCallback(ADI_TMR_WDOG_TIMER, TRUE, (void *)0x33333333, NULL, Callback); ... void Callback(void *ClientHandle, u32 Event, void *pArg) { // Event = ADI_TMR_EVENT_TIMER_EXPIRED switch ((u32)pArg) { case ADI_TMR_GP_TIMER_0: // Здесь делается обработка события истечения времени таймера общего назначения 0. // ClientHandle = 0x00000000 break; case ADI_TMR_GP_TIMER_1: // Здесь делается обработка события истечения времени таймера общего назначения 1. // ClientHandle = 0x11111111 break; case ADI_TMR_CORE_TIMER: // Здесь делается обработка события истечения времени таймера ядра. // ClientHandle = 0x22222222 break; case ADI_TMR_WDOG_TIMER: // Здесь делается обработка события истечения времени сторожевого таймера. // ClientHandle = 0x33333333 break; } } Когда запускается callback-функция, её параметр ClientHandle получает значение, заданное при установке callback-а, параметр Event равен ADI_TMR_EVENT_TIMER_EXPIRED, и параметр pArg содержит идентификатор таймера, который вызвал срабатывание callback-а. Этот пример передает NULL для хендла Службы DCB, чем задается немедленный (live) вызов callback-а для таймеров. Удаление callback-ов. Когда приложению больше не нужен callback, его можно удалить без влияния на другие настройки таймера. Следующий фрагмент кода иллюстрирует, как удалять callback-и. Result = adi_tmr_RemoveCallback(ADI_TMR_GP_TIMER_0); Result = adi_tmr_RemoveCallback(ADI_TMR_GP_TIMER_1); Result = adi_tmr_RemoveCallback(ADI_TMR_CORE_TIMER); Result = adi_tmr_RemoveCallback(ADI_TMR_WDOG_TIMER); Вызовы callback-функции больше не будут производиться, и функции callback сами по себе будут удалены их Службы Таймеров. Завершение. Когда больше не требуется функциональность, предоставляемая Службой Таймеров, приложение завершает эту службу. Следующий фрагмент кода завершает работу Службы Таймеров. Result = adi_tmr_Terminate();
После завершения Служба Таймеров должна быть инициализирована повторно, если снова нужно вызвать какую-нибудь её функцию. [Интерфейс программирования (API)] В этом разделе предоставлено описание интерфейса программирования Службы Таймеров (API). ! Приведенная здесь информация была точна на момент создания этого документа. Однако следует проверить содержимое подключаемого файла adi_tmr.h Службы Таймеров, чтобы получить текущую версию информации. Функция adi_tmr_Init() инициализирует внутреннюю структуру данных Службы Таймеров. Эта функция должна быть вызвана один раз на ядро процессора. ADI_TMR_RESULT adi_tmr_Init (void *pCriticalRegionArg); Аргумент:
Возвращаемые значения:
Функция adi_tmr_Open() открывает таймер. Регистры таймера сбрасываются в свои значения по умолчанию (power-up values, которые они получают при включении питания или сбросе процессора), условия информации состояния очищаются, и т. д. Будущие модели Blackfin могут потребовать эту функцию для выполнения дополнительных действий по некоторым манипуляциям аппаратурой при открытии таймера. ! На многоядерных процессорах Blackfin каждое ядро имеет собственный таймер ядра. Однако сторожевой таймер и таймеры общего назначения являются общими для ядер. Когда Служба Таймеров работает на многоядерных процессорах, убедитесь, что несколько ядер не пытаются одновременно использовать один и тот же сторожевой таймер и один и тот же таймер общего назначения. ADI_TMR_RESULT adi_tmr_Open (u32 TimerID);
Аргумент:
Возвращаемые значения:
Функция adi_tmr_Terminate() закрывает Службу Таймеров. Любые установленные callback-и удаляются. После завершения службы функция инициализации должна быть вызвана повторно, чтобы снова стали доступны функции Службы Таймеров. ADI_TMR_RESULT adi_tmr_Terminate (void); Возвращаемые значения:
Функция adi_tmr_Close() вызывается приложением, когда таймер больше не нужен. В настоящее время эта функция ничего не делает (это просто заглушка, немедленно возвращающая управление). Будущие модели процессоров Blackfin могут потребовать от этой функции неких манипуляций над аппаратурой при закрытии таймера. ADI_TMR_RESULT adi_tmr_Close (u32 TimerID);
Аргумент:
Возвращаемые значения:
Функция adi_tmr_Reset() сбрасывает регистры таймера в их значения по умолчанию (power-up values, которые получают регистры таймера при включении питания или сбросе процессора). При этом будут очищены любые индикаторы статуса, ожидающие обработки (флаги прерываний и т. д.). Поскольку функция adi_tmr_Reset вызывается внутри функции adi_tmr_Open, приложению редко когда нужно вызывать adi_tmr_Reset. ADI_TMR_RESULT adi_tmr_Reset (u32 TimerID);
Аргумент:
Возвращаемые значения:
Функция adi_tmr_CoreControl() посылает команду управления таймеру ядра. Она конфигурирует таймер ядра и меняет его настройки. ADI_TMR_RESULT adi_tmr_CoreControl (ADI_TMR_CORE_CMD Command, void *Value); Аргументы:
Возвращаемые значения:
Функция adi_tmr_WatchdogControl() посылает команду управления сторожевому таймеру. Она конфигурирует сторожевой таймер и меняет его настройки. ADI_TMR_RESULT adi_tmr_WatchdogControl (ADI_TMR_WDOG_CMD Command, void *Value); Аргументы:
Возвращаемые значения:
Функция adi_tmr_GPControl() посылает команду управления таймеру общего назначения. Она конфигурирует таймер и меняет его настройки. ADI_TMR_RESULT adi_tmr_GPControl (u32 TimerID, ADI_TMR_GP_CMD Command, void *Value); Аргументы:
Возвращаемые значения:
Функция adi_tmr_GPGroupEnable() одновременно разрешает или запрещает сразу несколько таймеров общего назначения (групповая операция). Эта функция предпринимает все усилия для того, чтобы одновременно разрешить или запретить группу таймеров. Если нижележащая аппаратура какого-либо определенного процессора Blackfin позволяет управлять одновременно сразу всеми указанными таймерами, то это будет сделано. Если же аппаратура не позволяет одновременного управления указанными таймерами, то такое управление таймерами будет выполнено по очереди, максимально быстро, как только это возможно. Обратите внимание, что в зависимости от определенного процессора Blackfin, когда разрешается таймер (таймеры), эта функция дополнительно конфигурирует мультиплексирование портов, основываясь на конфигурационных настройках таймера. Например, на процессорах ADSP-BF534, ADSP-BF536, ADSP-BF537 (и будущих моделях), если таймер общего назначения сконфигурирован как таймер PWM (ШИМ) с активным выходным выводом, то эта функция конфигурирует логику управления порта через службу управления портами, чтобы разрешить аппаратное функционирования вывода TMRx. На процессорах ADSP-BF531, ADSP-BF532, ADSP-BF533 и ADSP-BF561 processors, не требуется управлять логикой управления портами. От пользователя не требуется никаких действий со службой управления портами. ADI_TMR_RESULT adi_tmr_GPGroupEnable (u32 TimerID, u32 EnableFlag);
Аргументы:
Возвращаемые значения:
Функция adi_tmr_InstallCallback() устанавливает callback-функцию, которая будет запущена, когда истечет время таймера. Обратите внимание, что функция, предоставленная клиентом, это именно callback-функция, на обработчик прерывания (не ISR). Функция установки callback никак не меняет конфигурацию таймера, его значения и т. п. ADI_TMR_RESULT adi_tmr_InstallCallback (u32 TimerID, u32 WakeupFlag, void *ClientHandle, ADI_DCB_HANDLE DCBHandle, ADI_DCB_CALLBACK_FN ClientCallback); Аргументы:
Возвращаемые значения:
Функция adi_tmr_RemoveCallback() удаляет callback от указанного таймера. Эта функция никак не меняет конфигурацию таймера, значение его счетчика и регистров, и т. д. ! Вызов adi_tmr_RemoveCallback из тела callback-функции не поддерживается и может привести к непредсказуемому поведению. ADI_TMR_RESULT adi_tmr_RemoveCallback (u32 TimerID);
Аргумент:
Возвращаемые значения:
Функция adi_tmr_GetPeripheralID() может быть вызвана для определения идентификатора периферийного устройства (peripheral ID) для указанного таймера. Хотя эта функция обычно не требуется, она может быть полезной для реализации более изощренной логики управления прерыванием, чем предоставляет Служба Таймеров. Идентификатор периферийного устройства может быть передан в функции из тела обработчика прерывания. Обратите внимание, что таймер ядра не имеет связанного с ним идентификатора периферийного устройства, потому что таймер ядра привязан к жестко заданному уровню IVG. Однако в эту функцию может быть передан идентификатор таймера ядра, и функция не вернет кода ошибки. ADI_TMR_RESULT adi_tmr_GetPeripheralID (u32 TimerID, ADI_INT_PERIPHERAL_ID *pPeripheralID); Аргументы:
Возвращаемые значения:
[Публичные типы данных, перечисления и макросы] В этом разделе приведены определения структур данных и перечислений, используемых Службой Таймеров. ! Всегда проверяйте содержимое файла подключаемого заголовка adi_tmr.h, чтобы получить самую актуальную информацию. Идентификаторы таймеров (Timer ID). Служба Таймеров предоставляет уникальный идентификатор для каждого таймера. Timer ID это 32-битные значения, которые не просто индекс; вместо этого они представляют комбинацию из двух информационных частей. Биты 31..27 в timer ID это индекс, перечисляющий каждый таймер в системе, включая таймеры общего назначения, таймер ядра и сторожевой таймер. Биты 26..0 используются только для таймеров общего назначения, формируя маску, чтобы можно было их разрешать и запрещать одновременно, групповой операцией. В файле adi_tmr.h предоставлены макросы для создания timer ID, для доступа к значениям бит 26..0 и для доступа к значениям бит 31..27. Эти макросы используются внутри Службы Таймеров, и обычно они не нужны для применения в приложениях. Однако, когда приложению нужно опросить все таймеры общего назначения, идентификаторы timer ID могут быть созданы макросом ADI_TMR_CREATE_GP_TIMER_ID(x), где x это число от 0 до числа ADI_TMR_GP_TIMER_COUNT-1. Например, следующий фрагмент кода иллюстрирует, как открыть все таймеры общего назначения. u32 i, TimerID; ADI_TMR_RESULT Result; for (i = 0; i < ADI_TMR_GP_TIMER_COUNT; i++) { TimerID = ADI_TMR_CREATE_GP_TIMER_ID(i); Result = adi_tmr_Open(TimerID); } Для большинства функций в API Службы Таймеров значение timer ID передается в функцию для идентификации адресуемого таймера. Однако функция adi_tmr_GPGroupEnable() может в качестве параметра получить одно значение timer ID, или сразу несколько значений timer ID, объединенных друг с другом операцией ИЛИ. Структура значений timer ID позволяет в одном передаваемом параметре для функции идентифицировать сразу несколько таймеров общего назначения. Связанные макросы. Эти макросы определены для использования Службой Таймеров.
Каждый вызов API-функции Службы Таймеров возвратит значение из перечисления типа ADI_TMR_RESULT в качестве кода возврата. Подобно всем системным службам, код успешного завершения определен как 0, и код обычной ошибки определен как 1. Это позволяет вызывающей функции быстро оценить код возврата проверкой его на нулевое или не нулевое значение. Полное описание кодов возврата для Службы Таймеров начинается со значения ADI_TMR_ENUMERATION_START, чтобы упростить идентификацию.
Перечисление ADI_TMR_EVENT определяет тип произошедшего события callback. Имеется только одно значение, ADI_TMR_EVENT_TIMER_EXPIRED. Этот тип перечисления отличается от всех других типов событий системных служб, благодаря для всех системных служб можно использовать только один универсальный callback, независимо от того, какое событие обрабатывается. Коды событий для Службы Таймеров начинается со значения ADI_TMR_ENUMERATION_START, чтобы упростить идентификацию.
В таблице 8-1 перечислены команды, которые можно выполнить для таймера ядра. Эти идентификаторы команды (command ID) передаются как параметр в функцию adi_tmr_CoreCommand(). В дополнение к command ID, параметр Value (типа void *) также передается в функцию. Смысл параметра Value зависит от передаваемого значения идентификатора команды. Таблица 8-1 также описывает параметр Value для каждого идентификатора команды. Таблица 8-1. Команды, выполняемые для Core Timer.
В таблице 8-2 перечислены команды, которые можно выполнить для сторожевого таймера. Эти идентификаторы команды (command ID) передаются как параметр в функцию adi_tmr_WatchdogCommand(). В дополнение к command ID, параметр Value (типа void *) также передается в функцию. Смысл параметра Value зависит от передаваемого значения идентификатора команды. Таблица 8-2 также описывает параметр Value для каждого идентификатора команды. Таблица 8-2. Команды, выполняемые для Watchdog Timer.
В таблице 8-3 перечислены команды, которые можно выполнить для таймеров общего назначения. Эти идентификаторы команды (command ID) передаются как параметр в функцию adi_tmr_GPCommand(). В дополнение к command ID, параметр Value (типа void *) также передается в функцию. Смысл параметра Value зависит от передаваемого значения идентификатора команды. Таблица 8-3 также описывает параметр Value для каждого идентификатора команды. Таблица 8-3. Команды, выполняемые для General-Purpose Timer-ов.
[Ссылки] 1. VisualDSP++ 5.0 Device Drivers and System Services Manual for Blackfin® Processors site:analog.com. |