Начиная с некоторой версии моего проекта появилась странная вещь:
Прога не функционирует как надо- переполняется RSTACK, причем факт переполнения не зависит от размера стека( 128 уровней ставил ).
Аппаратно, проект- это две АТмеги128 (мастер и слейв) на плате, общающиеся по SPI, в обеих ось
(v.3.00) Проблема с мастером. Отладчик- JTAG ICE
Мастер получает байты от слейва с некоторым периодом, ну и обрабатывает их в процессах.
Обнаружил, что переполнение возникает в обработчике прерывания именно в момент записи:
msg_SpStart=s;
Код
/SPI interrupt service routine
#pragma vector = SPI_STC_vect
OS_INTERRUPT void ISR_SPI(void)
{
OS::scmRTOS_ISRW_TYPE ISR;
//Считываю принятый байт
byte s=SPDR;//получение команды
msg_SpStart=s;
msg_SpStart.sendISR();
}
Правда, SP указывает на начало стека- если точки останова ставить в обработчике прерывания, если убрать, и
стопорить прогу вручную, SP убегает до 0x05C4, при установленном диапазоне 0х140-0х160.
Настройки оси:
Код
#define scmRTOS_ISRW_TYPE TISRW_SS
#define scmRTOS_SYSTEM_TICKS_ENABLE 1
#define scmRTOS_SYSTIMER_HOOK_ENABLE 1
#define scmRTOS_IDLE_HOOK_ENABLE 1
#define scmRTOS_IDLE_PROCESS_DATA_STACK_SIZE 70
#define scmRTOS_IDLE_PROCESS_RETURN_STACK_SIZE 10
#define scmRTOS_CONTEXT_SWITCH_SCHEME 1
Откатился назад, до безглючной версии, и упростил ее до предельного вида- пустые процессы и один
обработчик SPI.
CODE
// Process types
//
typedef OS::process<OS::pr0, 300, 200> TPInSpi;
typedef OS::process<OS::pr1, 300, 200> TPOutSpi;
typedef OS::process<OS::pr2, 300, 200> TPPack;
typedef OS::process<OS::pr4, 300, 200> TPTestIn;
typedef OS::process<OS::pr3, 300, 200> TPRele;
//------------------------------------------
int main()
{
InitHard();
CONFIG_CSW();
START_SYSTEM_TIMER();//6ms
OS::Run();
}
//---------------------------------------------------------------------------
OS_PROCESS void TPInSpi::Exec()
{
for(;;)
{
msg_SpStart.wait();//
byte spcmd=msg_SpStart;
msg_SpStart.reset();
}//end_of_for(;;)
}
//---------------------------------------------------------------------------
OS_PROCESS void TPOutSpi::Exec()
{
for(;;)
{
}//end_of_for(;;)
}
//---------------------------------------------------------------------------
OS_PROCESS void TPPack::Exec()
{
for(;;)
{
}//end_of_for(;;)
}
//---------------------------------------------------------------------------
OS_PROCESS void TPTestIn::Exec()
{
//byte n_rele=1;
for(;;)
{
Sleep ();
}//end_of_for(;;)
}
//---------------------------------------------------------------------------
OS_PROCESS void TPRele::Exec()
{
Sleep();
}//end_of_for(;;)
}
//---------------------------------------------------------------------------
inline void InitHard(void)
{
...........
...........
...........
//-----------------
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: Off
// USART Mode: Asynchronous
UCSR0A=0x00;
UCSR0B=0x90;//разрешение приема и прерывания по-приему
//--Дальнейшие настройки--
UCSR0C=0x86;
UBRR0H=0x00;
UBRR0L=0x11;//12мгц- 38400
//----SPI----
SPCR|= (1 << MSTR);//мастер
SPCR|= (1 << SPIE);//разрешение прерываний
SPCR|= (1 << SPE);//включение модуля
}
//-----------------------------------------------------------
//SPI interrupt service routine
#pragma vector = SPI_STC_vect
OS_INTERRUPT void ISR_SPI(void)
{
OS::scmRTOS_ISRW_TYPE ISR;
//Считываю принятый байт
byte s=SPDR;//получение команды
msg_SpStart=s;
msg_SpStart.sendISR();
}
Переполнение стека появилось!!! И именно в тот же момент.
Если установить
#define scmRTOS_ISRW_TYPE TISRW
эффект не проявляется, но чем
#define scmRTOS_ISRW_TYPE TISRW_SS
хуже?!
Да и как вообще все это можно объяснить?
Причина редактирования: Использование [codebox]