Использование прерываний в программе на языке С
Пример программы на языке С для процессорной системы «DЕ2-70 Media Computer», в которой используются прерывания, приведен в листинге 11. Эта программа выполняет точно такие же действия, что и программа, описанная в предыдущем разделе.
Для разрешения прерываний процессорной системы в программе в листинге 11 используется макрос, который обеспечивает доступ к регистрам состояния и регистрам управления процессора Nios II. Набор таких макросов, которые могут быть использованы в любой программе на С, приведен в листинге 12.
Обработчики сброса и исключений для основной программы, представленной в листинге 11, приведены в листинге 13. Первая функция называется the_reset. Она обеспечивает простой механизм сброса посредством выполнения перехода к основной программе. Функция the_exception представляет обработчик общих исключений, который может быть использован в любой программе. Он включает код на языке ассемблер для того, чтобы проверить, является ли прерывание внешним, и если да, то вызывает программу, названную interrupt_hundler. Эта программа затем может выполнить какие-либо действия, необходимые для некоторого приложения. Фрагмент кода в листинге 13 interrupt_hundler во-первых определяет какое прерывание произошло, посредством использования макроса из листинга 12, который читает содержимое регистра произошедших прерываний. Программа обслуживания прерываний, которая вызывается интервальным таймером, приведена в листинге 14 и программа обслуживания прерываний от кнопок приведена в листинге 15. Файлы с исходными кодами рассмотренных программ распространяются как часть AMP. Они могут быть найдены в разделе «Sample programs» под именем Interrupt Example.
Листинг 11. Пример программы на С, в которой используются прерывания
#include "nios2_ctrl_reg_macros.h"
#include "key_codes.h"
volatile int key_pressed = KEY2;
volatile int pattern = 0x0000000F;
/*****************************************************************************
* Эта программа демонстрирует использование прерываний на стенде
* DE2-70 Media Computer. Вначале запускается таймер, который генерирует
* прерывания каждые 33 мс. Затем разрешаются прерывания от таймера и кнопок.
* Процедура обработки прерывания таймера отображает текст на 7-сегментных
* индикаторах и сдвигает его влево или вправо. Направление сдвига определяется
* кнопками. При нажатии кнопки key1 текст сдвигается вправо, при нажатии
* key2 – влево, при нажатии key3 изменяется текст, используя данные с переключателей.
*****************************************************************************/
int main(void)
{
volatile int * interval_timer_ptr = (int *) 0x10002000; //базовый адрес интервального таймера
volatile int * KEY_ptr = (int *) 0x10000050; //базовый адрес кнопок
/* устанавливаем период срабатывания интервального таймера */
int counter = 0x190000; // 1/(50 MHz) x (0x190000) = 33 msec
*(interval_timer_ptr + 0x2) = (counter & 0xFFFF);
*(interval_timer_ptr + 0x3) = (counter >> 16) & 0xFFFF;
/* запускаем таймер и разрешаем формирование прерываний от него */
*(interval_timer_ptr + 1) = 0x7; // STOP = 0, START = 1, CONT = 1, ITO = 1
*(KEY_ptr + 2) = 0xE; //разрешаем формирование прерываний от трех кнопок
NIOS2_WRITE_IENABLE( 0x3 ); //разрешаем прерывания Nios II процессора от кнопок и таймера
NIOS2_WRITE_STATUS( 1 ); //разрешаем прерывания Nios II процессора
while(1); //бесконечный цикл
}
Листинг 12. Макросы для доступа к регистрам состояния и управления Nios II
#ifndef __NIOS2_CTRL_REG_MACROS__
#define __NIOS2_CTRL_REG_MACROS__
/*****************************************************************************/
/* Макросы для доступа к управляющим регистрам */
/*****************************************************************************/
#define NIOS2_READ_STATUS(dest) \
do { dest = __builtin_rdctl(0); } while (0)
#define NIOS2_WRITE_STATUS(src) \
do { __builtin_wrctl(0, src); } while (0)
#define NIOS2_READ_ESTATUS(dest) \
do { dest = __builtin_rdctl(1); } while (0)
#define NIOS2_READ_BSTATUS(dest) \
do { dest = __builtin_rdctl(2); } while (0)
#define NIOS2_READ_IENABLE(dest) \
do { dest = __builtin_rdctl(3); } while (0)
#define NIOS2_WRITE_IENABLE(src) \
do { __builtin_wrctl(3, src); } while (0)
#define NIOS2_READ_IPENDING(dest) \
do { dest = __builtin_rdctl(4); } while (0)
#define NIOS2_READ_CPUID(dest) \
do { dest = __builtin_rdctl(5); } while (0)
#endif
Дата добавления: 2015-05-30; просмотров: 887;