Доброго времени суток.
Создаю в eclipse проект на основе примера hello usoc. В нем есть две задачи, которые попеременно выводят в консоль сообщения, все вроде бы просто и понятно. В моей процессорной системе (Nios) есть порт (input) PIO. Он настроен на генерацию прерываний по нажатию на кнопку на моем борде. Если говорить о "чистом " C коде, то как зарегистрировать прерывания и описать их обработчик мне известно (через ф-ию alt_irq_register() и т.д.). В примере hello usoc я так и сделал, вот пример кода:
#include <stdio.h>
#include "includes.h"
#include "system.h"
#include "altera_avalon_pio_regs.h"
//#include "altera_avalon_pio_regs.h"
/* Definition of Task Stacks */
#define TASK_STACKSIZE 2048
OS_STK task1_stk[TASK_STACKSIZE];
OS_STK task2_stk[TASK_STACKSIZE];
/* Definition of Task Priorities */
#define TASK1_PRIORITY 1
#define TASK2_PRIORITY 8
volatile int buttons=0;
int led=0;
static void button_isr( void * base, alt_u32 id )
{
buttons = IORD_ALTERA_AVALON_PIO_EDGE_CAP(base);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(base,0x3);
}
void task1(void* pdata)
{
while (1)
{
if (buttons != 0)
{
switch (buttons) {
case 1:
alt_printf("Нажата кнопка pb_left\n ");
if (led == 0x80||led==0x00 )
led = 0x01;
else
led = led << 1;
buttons = 0;
break;
case 2:
alt_printf("Нажата кнопка pb_right\n ");
if (led == 0x01 ||led==0x00 )
led = 0x80;
else
led = led >> 1;
buttons = 0;
break;
default:
buttons = 0;
break;
}
IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE,led);
}
printf("Hello from task1\n");
//OSTimeDlyHMSM(0, 0, 1, 0);
}
}
void task2(void* pdata)
{
while (1)
{
alt_irq_register(BUTTONS_IRQ, (void*)BUTTONS_BASE, button_isr);
printf("Hello from task2\n");
//OSTimeDlyHMSM(0, 0, 1, 0);
}
}
/* The main function creates two task and starts multi-tasking */
int main(void)
{
IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE,0x00);
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(BUTTONS_BASE, 0x3);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(BUTTONS_BASE, 0x3);
alt_irq_register(BUTTONS_IRQ, (void*)BUTTONS_BASE, button_isr);
OSTaskCreateExt(task1,
NULL,
(void *)&task1_stk[TASK_STACKSIZE-1],
TASK1_PRIORITY,
TASK1_PRIORITY,
task1_stk,
TASK_STACKSIZE,
NULL,
0);
OSTaskCreateExt(task2,
NULL,
(void *)&task2_stk[TASK_STACKSIZE-1],
TASK2_PRIORITY,
TASK2_PRIORITY,
task2_stk,
TASK_STACKSIZE,
NULL,
0);
OSStart();
return 0;
}
Но я чувствую, что в ucos такая работа с прерываниями некорректна.
Подскажите пожалуйста, какова идеология работы с прерываниями под ucos, и как должен выглядеть обработчик прерываний в моем случае, то есть описанный штатными средствами операционной системы?
Если есть возможность поделитесь простым примером, от которого можно оттолкнутся.
Обработчик как обработчик. Можете поллингом сделать:
while(1)
{
if(BUTTON_PRESSED()) ...
}
Будет и просто, и без volatile, и антидребезг заодно.
Правильно ли я Вас понял, Вы предлагаете не использовать обработчик прерываний, а просто считывать состояние порта PIO?
Да.
Тогда я Вас понял, такой вариант тоже возможен, но только меня интересует именно синтаксис описания прерывания штатными средствами OC, может кто-нибудь поделится опытом?
Штатные средства ОС такие, что обработчик прерывания вызывается через враппер, который делает всю работу по входу/выходу из прерывания. Если у вас вектор прерываний настроен на работу через этот враппер, то свой обработчик записываете в таблицу обработчиков ОС и он выполнится без дополнительных телодвижений.
Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)