Программирование DSP Сторожевой таймер ADSP-BF538 Fri, March 29 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Сторожевой таймер ADSP-BF538 Печать
Добавил(а) microsin   

В процессор встроен 32-битный таймер, который можно использовать для реализации сторожевого таймера, контролирующего работу программы (software watchdog). Это позволяет повысить надежность работы системы путем генерации события для ядра процессоре, если значение таймера истекло до того, как оно было обновлено программой. В зависимости от того, как запрограммирован сторожевой таймер, это событие может генерировать сброс (reset), не маскируемое прерывание (non-maskable interrupt, NMI) или обычное прерывание (general-purpose interrupt). Сторожевой таймер (watchdog) тактируется от системной тактовой частоты (SCLK).

Чтобы использовать сторожевой таймер:

1. Установите значение счетчика для таймера watchdog путем записи значения в регистр счетчика (watchdog count register, WDOG_CNT). Имейте в виду, что загрузка регистра WDOG_CNT, когда таймер watchdog не разрешен, также выполнит предварительную загрузку регистра WDOG_STAT.

Время срабатывания сторожевого таймера высчитывается по формуле (T это время в секундах, SCLK это тактовая частота системной шины в Гц):

T = WDOG_CNT / SCLK

Отсюда необходимое значение для WDOG_CNT можно вычислить как

WDOG_CNT = T · SCLK

Например, при частоте системной шины SCLK = 131072 кГц максимально возможный таймаут (когда в WDOG_CNT записано значение 0xFFFFFFFF) составит приблизительно 32.7 секунды.

2. В регистре управления (watchdog control register, WDOG_CTL), выберите событие (event), которое будет генерироваться таймаутом счетчика.

3. Разрешите таймер watchdog через регистр WDOG_CTL. После этого таймер watchdog начнет считать вниз, декрементируя значение в регистре WDOG_STAT. Когда регистр WDOG_STAT достигнет 0, будет сгенерировано запрограммированное событие. Чтобы предотвратить генерацию события, программа должна перезагружать значение счетчика из WDOG_CNT в WDOG_STAT путем выполнения записи (любого значения) в WDOG_STAT, либо должна запретить таймер watchdog программированием регистра WDOG_CTL. Программа эта должна сделать до того, как истечет таймаут таймера watchdog (до того, как WDOG_CNT достигнет нуля).

В таблице перечислены регистры сторожевого таймера:

Регистр Адрес После сброса Разр. Доступ Назначение
WDOG_CTL 0xFFC00200 0x0AD0 16 R/W Регистр управления
WDOG_CNT 0xFFC00204 0x00000000 32 R/W Счетчик сторожевого таймера
WDOG_STAT 0xFFC00208 0x00000000 32 R/W Состояние (значение) счетчика таймера

Регистр WDOG_CNT. Регистр счетчика сторожевого таймера (WDOG_CNT) содержит 32-битное значение без знака. К регистру WDOG_CNT должен осуществляться доступ только через 32-битные операции чтения/записи.

ADSP BF538 watchdog WDOG CNT

Рис. 16-30. Watchdog Count Register (WDOG_CNT).

Регистр WDOG_CNT содержит программируемое значение счетчика. Запись в регистр WDOG_CNT также перезагрузит счетчик таймера watchdog. Для улучшения безопасности регистр WDOG_CNT может быть обновлен только тогда, когда, когда таймер watchdog запрещен. Запись в регистр счетчика, когда таймер watchdog разрешен, не обновит содержимое этого регистра.

Регистр WDOG_STAT. 32-битный регистр состояния сторожевого таймера (watchdog status register, WDOG_STAT) содержит текущее значение счетчика сторожевого таймера. Чтение WDOG_STAT вернет текущее значение счетчика. Когда таймер watchdog разрешен, WDOG_STAT декрементируется на 1 на каждом такте SCLK. Когда WDOG_STAT достигает 0, таймер watchdog прекращает счет, и генерируется событие, выбранное в регистре управления сторожевым таймером (WDOG_CTL).

ADSP BF538 watchdog WDOG STAT

Рис. 16-31. Watchdog Status Register (WDOG_STAT).

Значения не могут непосредственно сохраняться в WDOG_STAT, они вместо этого копируются из WDOG_CNT. Это происходит двумя способами:

• Когда таймер watchdog запрещен, запись в регистр WDOG_CNT перезагружает регистр WDOG_STAT.
• Когда таймер watchdog разрешен, запись в регистр WDOG_STAT загружает его значение в WDOG_CNT.

Когда процессор выполняет запись (произвольного значения) в WDOG_STAT, значение из WDOG_CNT копируется в регистр WDOG_STAT. Обычно программа устанавливает значение WDOG_CNT при инициализации, и затем периодически делает записи в WDOG_STAT до того, как истечет задержка сторожевого таймера. Это перезагружает таймер watchdog значением из WDOG_CNT, и предотвращает генерацию выбранного события.

Регистр WDOG_STAT является 32-битным, отображенным на адресное пространство регистром, к которыми должен осуществляться доступ 32-битными операциями чтения и записи.

Если пользователь не перезагрузил счетчик до того, как прошло время SCLK · N (здесь N это запрограммированное значение счетчика), будет сгенерировано прерывание watchdog или сброс, и установится бит TRO в регистре управления (WDOG_CTL). Когда это происходит, счетчик прекращает свое декрементирование, и остается в нулевом состоянии.

Если счетчик разрешен, когда в счетчик загружено значение 0, то немедленно установится бит TRO в регистре управления, и счетчик останется в состоянии нуля, и не будет декрементироваться.

Регистр WDOG_CTL. Регистр управления сторожевым таймером (watchdog control register, WDOG_CTL) является 16-битным регистром, отображенным на адресное пространство процессора. Он используется для управления поведением сторожевого таймера.

ADSP BF538 watchdog WDMOG CTL

Рис. 16-32. Watchdog Control Register (WDOG_CTL).

Поле ICTL[1:0] используется для выбора события, которое генерируется, когда истекает таймаут таймера watchdog. Обратите внимание, что если выбрана опция генерации обычного прерывания (general-purpose interrupt), то должен быть соответствующим образом сконфигурирован системный регистр маски прерывания (system interrupt mask register, SIC_IMASKx), чтобы демаскировать это прерывание. Если событий watchdog запрещена, то таймер watchdog работает так же, как описано, за исключением того, что не будет генерироваться событие таймера watchdog, когда истекает его таймаут (когда счетчик watchdog достигает нуля).

Поле TMR_EN[7:0] используется для разрешения или запрета таймера watchdog. Запись в него любого значения, отличающегося от значения запрета 0xAD, разрешает работу таймера watchdog timer. Специальное многобитное значение запрета работает как ключ, минимизирующий шанс случайного нежелательного запрета сторожевого таймера.

Программное обеспечение может определить, досчитал ли таймер до нуля путем опроса бита TRO в регистре управления watchdog. Это sticky-бит, который устанавливается всякий раз, когда счетчик таймера watchdog достигает 0, и очищается только путем запрета таймера watchdog и последующей записи в этот бит значения 1.

Обратите внимание, что когда процессор работает в режиме эмуляции (под отладчиком), счетчик сторожевого таймера не декрементируется, даже если он разрешен.

[Примеры программирования сторожевого таймера Blackfin]

Watchdog Blackfin можно программировать с помощью библиотеки системных служб таймеров (модули исходного кода adi_tmr.c и adi_tmr.h [2]), поставляющейся вместе со средой разработки VisualDSP. Примеры использования легко найти в папке VisualDSP 5.0\Blackfin\Examples, если запустить поиск по файлам вызовов функций, имена которых начинаются с adi_tmr_.

Можно программировать и использовать таймер и без специального драйвера, потому что это довольно просто. Ниже показан пример модуля с функциями управления сторожевым таймером Blackfin.

Заголовочный файл wdog.h:

#ifndef __WDOG__
#define __WDOG__
 
#include < cdefBF538.h>
#include < ccblkfn.h>
 
// Раскомментировать WDTPERIOD, если будет использоваться сторожевой
// таймер Blackfin. Здесь SLCK определена как частота системной
// шины в килогерцах, а константа 5000 задает время в миллисекундах
// таймаута сторожевого таймера:
#define WDTPERIOD (5000*SCLK)
 
#ifdef WDTPERIOD
  void WDOGinit (void);
  void WDOGreload (void);
#else
  #define WDOGinit()
  #define WDOGreload()
#endif

#endif  //__WDOG__

Модуль wdog.c:

#include "wdog.h"
 
#ifdef WDTPERIOD
void WDOGinit (void)
{
   // Запрет сторожевого таймера:
   *pWDOG_CTL = WDDIS;
   ssync();
   // Инициализация счетчика:
   *pWDOG_CNT = WDTPERIOD;
   ssync();
   // Разрешение сторожевого таймера, генерировать сброс
   // при срабатывании сторожевого таймера:
   *pWDOG_CTL = WDEN | WDEV_RESET;
   ssync();
}
 
void WDOGreload (void)
{
   // Сброс (откладывание срабатывания) сторожевого таймера:
   *pWDOG_STAT = 0;
}
#endif

Здесь определены 2 функции: WDOGinit и WDOGreload. WDOGinit нужно вызвать в момент инициализации программы (обычно перед входом в главный цикл main). В этом примере таймаут сторожевого таймера задан на 5000 мс, т. е. 5 секунд. Чтобы отменить перезагрузку по сторожевому таймеру, функция WDOGreload должна вызываться не реже, чем каждые 5 секунд. Обычно вызов WDOGreload вставляется в тело цикла main, если его прокрутки всегда гарантированно происходят чаще 5 секунд.

Если сторожевой таймер не нужен, то следует закомментировать строку, где определена константа WDTPERIOD:

//#define WDTPERIOD (5000*SCLK)

[Ссылки]

1. ADSP-BF538: таймеры.
2VDK: служба таймеров.

 

Добавить комментарий


Защитный код
Обновить

Top of Page