|
|
|
ucos+nios+isr, Работа с прерываниями в UCOS |
|
|
|
Sep 15 2014, 19:15
|
Группа: Участник
Сообщений: 10
Регистрация: 16-08-13
Пользователь №: 77 949
|
Доброго времени суток. Создаю в 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, и как должен выглядеть обработчик прерываний в моем случае, то есть описанный штатными средствами операционной системы? Если есть возможность поделитесь простым примером, от которого можно оттолкнутся.
|
|
|
|
|
Sep 16 2014, 17:10
|
Группа: Участник
Сообщений: 10
Регистрация: 16-08-13
Пользователь №: 77 949
|
Правильно ли я Вас понял, Вы предлагаете не использовать обработчик прерываний, а просто считывать состояние порта PIO?
|
|
|
|
|
Sep 17 2014, 19:51
|
Группа: Участник
Сообщений: 10
Регистрация: 16-08-13
Пользователь №: 77 949
|
Тогда я Вас понял, такой вариант тоже возможен, но только меня интересует именно синтаксис описания прерывания штатными средствами OC, может кто-нибудь поделится опытом?
|
|
|
|
|
Sep 18 2014, 11:41
|
Знающий
Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245
|
Цитата(Slaven @ Sep 17 2014, 23:51) Тогда я Вас понял, такой вариант тоже возможен, но только меня интересует именно синтаксис описания прерывания штатными средствами OC, может кто-нибудь поделится опытом? Использовал на другом процессоре. Нет там никаких штатных средств описания прерывания, есть только общие слова (ucos-ii) Цитата YourISR: Save all CPU registers; Call OSIntEnter() or, increment OSIntNesting directly; Execute user code to service ISR; Call OSIntExit(); Restore all CPU registers; Execute a return from interrupt instruction; Остальное происходит как описано в даташите на процессор, единственное нельзя ожидать событий от RTOS в прерываниях.
|
|
|
|
|
Oct 11 2014, 14:08
|
Местный
Группа: Свой
Сообщений: 247
Регистрация: 4-10-10
Из: г. Екатеринбург
Пользователь №: 59 925
|
Код 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); } } Это вообще ... какая-то, в бесконечном цикле регить обработчик.... А вообще, более правильный механизм выглядит так: 1. регим обработчик прерывания 2. заводим семафор 3. заводим таск, которому нужно это прерывание 4. в обработчике прерывания взводим семафор 5. в таске, в начале тела ждем семафора, после чего делаем то, что надо, сбрасываем семафор ну, это примерная модель, а уже для каждого конкретного случая может немного изменяться.
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|