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

 
 
 
Reply to this topicStart new topic
> Порт под MSP-GCC, TISRW_SS - что-то не так., Похоже я накосячил.
AHTOXA
сообщение Aug 10 2009, 05:12
Сообщение #1


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Обнаружил странное поведение. Если в прерывании от системного таймера использовать TISRW_SS (это так по умолчанию, scmRTOS_ISRW_TYPE = TISRW_SS), а в других прерываниях TISRW, то всё работает. Как только я пытаюсь использовать TISRW_SS в любом другом прерывании, то всё рушится.
Если совсем не использовать TISRW_SS, то всё работает как надо.
Вопрос такой - это так и должно быть, или этот косяк возник при портировании на msp-gcc?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
dxp
сообщение Aug 10 2009, 09:35
Сообщение #2


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(AHTOXA @ Aug 10 2009, 12:12) *
Обнаружил странное поведение. Если в прерывании от системного таймера использовать TISRW_SS (это так по умолчанию, scmRTOS_ISRW_TYPE = TISRW_SS), а в других прерываниях TISRW, то всё работает. Как только я пытаюсь использовать TISRW_SS в любом другом прерывании, то всё рушится.
Если совсем не использовать TISRW_SS, то всё работает как надо.
Вопрос такой - это так и должно быть, или этот косяк возник при портировании на msp-gcc?

Надо смотреть код конструктора/деструктора обертки TISRW_SS. Там должно при первом входе в прерывание происходить переключение указателя стека на отдельный стек прерываний. При вложенных прерываниях переключения стека уже производиться не должно. При выходе из первого по вложенности прерывания в основную программу указатель стека должен переключиться на стек прерванного процесса. Возможно, обертка TISRW_SS не анализирует вложенность прерываний и пытается каждый раз переключить укзатель стека. Надо посмотреть это место.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 10 2009, 10:30
Сообщение #3


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Да вроде анализируется...
Код
        INLINE inline void ISR_Enter()
        {
            if(Kernel.ISR_NestCount++ == 0)
            {
                Kernel.ProcessTable[Kernel.CurProcPriority]->StackPointer = GetStackPointer();
                SetISRStackPointer();
            }
        }
        //-----------------------------------------------------
        INLINE inline void ISR_Exit()
        {
            DisableInterrupts();
            if(--Kernel.ISR_NestCount) return;
            SetStackPointer(Kernel.ProcessTable[Kernel.CurProcPriority]->StackPointer);
            Kernel.SchedISR();
        }


Собственно код один в один с IAR. Разница начинается дальше, в GetStackPointer() / SetISRStackPointer() / SetStackPointer().
Но они, скорее всего, работают, иначе бы и при единственном обработчике с _SS всё падало.
Но на всякий случай:

Код
INLINE inline TStackItem* GetStackPointer()    { return reinterpret_cast<TStackItem*>(GetSP()); }
INLINE inline TStatusReg GetSP()
{
    uint16_t __x;
    __asm__ __volatile__(
        "mov    r1, %0"
        : "=r" (__x)
        :);
    return __x;
}

INLINE inline void SetISRStackPointer()
{
    WRITE_SP(GetInitialStack());
}
#define WRITE_SP(x) \
    __asm__ __volatile__("mov %0, r1" : : "r" ((uint16_t) x))

static INLINE inline word GetInitialStack()
{
    extern uint8_t __stack;
    return reinterpret_cast<word>(&__stack);
}


__stack определен в линкерном скрипте (для F149) как
Код
  PROVIDE (__stack = 0xa00);


Вроде правильно всё...

Полез в листинги... smile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Aug 11 2009, 11:21
Сообщение #4


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Уф, разобрался. Увидел в коде обработчика прерывания
Код
    139e:    0f 12           push    r15        
    13a0:    0e 12           push    r14        
    13a2:    0d 12           push    r13        
    13a4:    0c 12           push    r12        
    13a6:    31 80 06 00     sub    #6,    r1   ;#0x0006

резервирование пространства на стеке, вспомнил, что где-то уже читал про такое.

Поправил с запасом GetInitialStack() на
return reinterpret_cast<word>(&__stack) - 12;

и всё заработало.

Попытался решить проблему, отменив заинлайнивание обработчиков:
Код
OS_INTERRUPT interrupt(UART0RX_VECTOR) usart0_rx(void)
{
    OS::TISRW_SS ISR;
    Uart1.rx_interrupt_proc();
}

, но это не помогло. Всё равно до создания экземпляра TISRW_SS происходит резервирование одного байта на стеке. Нехорошо...

Откатился пока на TISRW...


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

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

 


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


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