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

 
 
> Прерывания и CAN
Troll
сообщение Nov 26 2008, 04:21
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 104
Регистрация: 30-06-05
Из: С-Петербург
Пользователь №: 6 406



Добрый день (утро, вечер, ночь).

Использую проц AT91SAM7A3, компилятор gcc

Возникла следующая проблема:
есть функции для работы с CAN. Одна функция обслуживает прерывания по приему пакетов (только прием), копирует принятые пакеты в буфер приема для последующей обработки. Другая функция занимается формированием и отправкой пакетов по CAN.

Функция прерывания:
Код
void can0_handler (void)
{
//    printd("*");
//    AT91C_BASE_CAN0->CAN_TCR = 0xFFFF;
//    AT91C_BASE_AIC->AIC_EOICR = 1;
//    return;

    int status;

    int i;
    int adr;
    AT91PS_CAN_MB mb;

    status = can0.pcan->CAN_SR;
    mb = &can0.pcan->CAN_MB0;

    for (i = 0; i<8; i++) {
        if (status & (1 << i)) {//Принят пакет
            adr = (mb->CAN_MB_MID >> 15) & 0xFF;
            if ((1<<adr) & can0.device_id) {//Устройство зарегистрированно для обслуживания
                can_packet_to_buf (can0.inbuf, can0.inbuf_size, mb->CAN_MB_MID, mb->CAN_MB_MDH, mb->CAN_MB_MDL, (mb->CAN_MB_MSR >> 16)&0xF);
                can0.inbuf_update = 1;
            }
            if ((1<<adr) & can0.device_id_echo) {//Устройство зарегистрированно для ретрансляции
                can_packet_to_buf (can1.outbuf, can1.outbuf_size, mb->CAN_MB_MID, mb->CAN_MB_MDH, mb->CAN_MB_MDL, (mb->CAN_MB_MSR >> 16)&0xF);
            }
            can0.pcan->CAN_TCR = (1 << i); //Освободить центр
        }
        mb++;
    }
    AT91C_BASE_AIC->AIC_EOICR = 1;
}

Функция для отправки сообщений (приведена не полностью):
Код
int can_work (pCAN c)
{
    CAN_PACKET packet;
    int val;
    int mask = canGetMailBoxIntMask(c);

    if (c->fmake != NULL) {
        if (delta_time(c->tfastreq) > c->rperiod_fast) {
            printd("fmake\r\n");
            c->tfastreq = jiffies;
        }
    }

    if (c->make != NULL) {
        if (delta_time(c->treq) > c->rperiod) {
            printd("make\r\n");
            c->treq = jiffies;
        }
    }

    c->pcan->CAN_IDR = 0xFF; // - 1 -
    can_sendmes (c);
    c->pcan->CAN_IER = (mask & 0xFFFF);

    return 1;
}


Функция can_work вызывается в основном цикле и с заданной периодичностью формирует и отправляет пакеты с данными.

Собственно проблема: если в коде can_work убрать строку (1), то все замечательно. В противном случае возникает "Spurious Interrupt".
Если прерываний от CAN не возникает (изначально не включать прерывания или отключить шину), то тоже все работает (строка (1) не убирается).

Пробовал отключать прерывания в SysAIC, тоже самое.
Если в функции прерывания оставить только верхнии закоментированные строки, то все равно не работает.
Вызов функции can_sendmes можно и закоментировать, ошибка все равно появится.

Дополнительно: передающее устройство присылает несколько десятков пакетов с периодичностью раз в секунду (хотя это влияет только на периодичность появления Spurious Interrupt).

Spurious Interrupt вываливается с периодичностью от 1 до нескольких десятков секунд.

Подскажите в чем может быть проблема? и как ее можно решить?

С уважением.

Сообщение отредактировал Troll - Nov 26 2008, 04:38


--------------------
Hemos Pasado
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 18th June 2025 - 05:00
Рейтинг@Mail.ru


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