реклама на сайте
подробности

 
 
> ucos+nios+isr, Работа с прерываниями в UCOS
Slaven
сообщение Sep 15 2014, 19:15
Сообщение #1





Группа: Участник
Сообщений: 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, и как должен выглядеть обработчик прерываний в моем случае, то есть описанный штатными средствами операционной системы?
Если есть возможность поделитесь простым примером, от которого можно оттолкнутся.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
billidean
сообщение Oct 11 2014, 14:08
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 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. в таске, в начале тела ждем семафора, после чего делаем то, что надо, сбрасываем семафор
ну, это примерная модель, а уже для каждого конкретного случая может немного изменяться.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th April 2024 - 00:36
Рейтинг@Mail.ru


Страница сгенерированна за 0.01353 секунд с 7
ELECTRONIX ©2004-2016