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

 
 
> Резервирование RSTACK для AVRMega, Нестабильная работа
Aeore
сообщение May 30 2013, 19:53
Сообщение #1





Группа: Участник
Сообщений: 12
Регистрация: 10-08-07
Из: Odessa
Пользователь №: 29 704



Здравствуйте.

Компилятор: IAR AVR
Контроллер: AVR ATMega128 + 64КБ внешней памяти
Менеджер памяти: heap_3.c

Описание проблемы:
Прошивка представляет собой связку из нескольких слоев: ОС + Самописный фреймворк + Пользовательская программа. Специфика фреймворка и программы такова, что глубина вызовов может быть достаточно большой - приблизительно 20-30 вызовов в глубину. Вся эта связка в режиме симуляции под win32 работает нормально, но при прошивке контроллера начинаются проблемы - происходит циклическая перезагрузка, при том не всегда с самого начала. После очередного запуска программа может запуститься откуда-то с середины. Это все я контроллирую по трейсам в терминале.
Вобщем искал я искал и нашел такую проблему: в конфигурационном файле FreeRTOSConfig.h есть макроопределение configCALL_STACK_SIZE, которое по умолчанию установлено в 20. Исследование исходников показало, что это 20 байт, которые ОС резервирует в стеке задачи под адреса возврата из функций. Так как у меня мега, то получается максимальная глубина всего 10 вызовов, а дальше RSTACK начинает перетирать уже сохраненные регистры и все прочее, от чего начинаются проблемы. Ну хорошо, увеличим размер этой области до, скажем, 128 байт (глубина до 64 вызовов), при этом всем общего размера стека хватает - я его устанавливаю с запасом, скажем 8 КБ. Результат: программа не работает. Глючит уже по другому, но с тем же результатом. Вобщем экспериментальным образом я нашел, что при размере 45 текущая программа работает стабильно, но всеравно при дальнейшем усложнении кода начинаются похожие проблемы.

Вопрос: Как установить большой размер для стека возвратов?

Очень надеюсь на вашу помощь.

PS: Да, еще была проблема - вместе с этим постоянно срабатывал каллбэк vApplicationStackOverflowHook(), пока я не увеличил стандартные значения макросов configTIMER_QUEUE_LENGTH и configTIMER_TASK_STACK_DEPTH. После этого каллбэк срабатывал только после большого количества этих перезагрузок при глючащей системе. Теперь же, после небольшого допиливания программы (дописал несколько пустых классов-тасок и запустил их), опять начал срабатывать, но уже без таких феерических циклов перезагрузок как раньше (всего лишь одна):

Вот пример трейсов, тут работа начинается с "Svc: LBKLogic started". Видно, что програма стартует нормально, но потом начинаются уже какие=-то глюки, после чего контроллер перезагружается (следующий "Svc: LBKLogic started") и дальше пока что все идет хорошо! (это до поры до времени)
Код
Svc: LBKLogic started
<!> Fatal: FreeRTOS stack overflow (Task: "J¤JјJНJСJ$%ҐJ", Stack ptr: 4acd, Stack base: 4ad1)
<!> Fatal: FreeRTOS stack overflow (Task: "J¤JјJНJСJ$%ҐJ", Stack ptr: 4a99, Stack base: bcf7)
<!> Fatal: FreeRTOS stack overflow (Task: "J¤JјJНJСJ$%ҐJ", Stack ptr: 4a65, Stack base: bcf7)
<!> Fatal: FreeRTOS stack overflow (Task: "J¤JјJНJСJ$%ҐJ", Stack ptr: 4a31, Stack base: bcf7)
<!> Fatal: FreeRTOS stack overflow (Task: "J¤JјJНJСJ$%ҐJ", Stack ptr: 49fd, Stack base: bcf7)
<!> Fatal: FreeRTOS stack overflow (Task: "J¤JјJНJСJ$%ҐJ", Stack ptr: 49c9, Stack base: bcf7)
<!> Fatal: FreeRTOS stack overflow (Task: "J¤JјJНJСJ$%ҐJ", Stack ptr: 4995, Stack base: bcf7)
<!> Fatal: FreeRTOS stack overflow (Task: "J¤JјJНJСJ$%6—6±1b0Л-µЗб"9дCлб"9дCлб"9дCлб"9дCлб"9дCлб"9дCлб"9дCлб"9дC%А&%i3"^›", Stack ptr: 4961, Stack base: bcf7)
<!> Fatal: FreeRTOS stack overflow (Task: "J¤J6—6±1b0Л-µЗб"9дCлб"9дCлб"9дCлб"9дCлб"9дCлб"9дCлб"9дCлб"9дCлб"9дC%А&%i3"^›", Stack ptr: 492d, Stack base: bcf7)
Svc: LBKLogic started
Svc: Platform started
Svc: HMILogic started
Svc: BeepMaster started
Svc: Controller started
Nothing more to run


PPS: Фрагмент текущей конфигурации из FreeRTOSConfig.h:
Код
#ifndef WIN32
# include <iom128.h>
#endif

#define configCALL_STACK_SIZE        45 // 20 by default

#define configUSE_PREEMPTION                1
#define configUSE_IDLE_HOOK                0
#define configUSE_TICK_HOOK                0
#define configCPU_CLOCK_HZ                ( ( unsigned long ) 16000000 )
#define configTICK_RATE_HZ                ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES                ( ( unsigned portBASE_TYPE ) 9 )
#define configMINIMAL_STACK_SIZE            ( ( unsigned short ) 85 + configCALL_STACK_SIZE ) // 85 by default
#define configTOTAL_HEAP_SIZE                ( ( size_t ) ( 51200 ) )
#define configMAX_TASK_NAME_LEN                ( 16 )
#ifdef DEBUG // ygurin
#define configUSE_TRACE_FACILITY            1
#else
#define configUSE_TRACE_FACILITY            0
#endif
#define configUSE_16_BIT_TICKS                1
#define configIDLE_SHOULD_YIELD                1
#define configUSE_TIMERS                        1
#define configTIMER_TASK_PRIORITY               (configMAX_PRIORITIES - 1)
#define configTIMER_QUEUE_LENGTH                64 // 20 by default 64
#define configTIMER_TASK_STACK_DEPTH            92 // 64 by default 92

#define configUSE_CO_ROUTINES                 0
#define configMAX_CO_ROUTINE_PRIORITIES       ( 2 )

#define INCLUDE_vTaskPrioritySet        1
#define INCLUDE_uxTaskPriorityGet        1
#define INCLUDE_vTaskDelete            1
#define INCLUDE_vTaskCleanUpResources            0
#define INCLUDE_vTaskSuspend            1
#define INCLUDE_vTaskDelayUntil            1
#define INCLUDE_vTaskDelay            1



А это MAP файл с сегментами, который сгенерировал компилятор:

Имя Пространство Адрес Размер Тип Выравнивание
NEAR_I DATA 00001100 - 00001309 20A Relative 0
NEAR_Z DATA 0000130A - 00001390 87 Relative 0
RSTACK DATA 00001391 - 00001790 400 Predefined 0
CSTACK DATA 00001791 - 00001B90 400 Predefined 0
NEAR_HEAP DATA 00001B91 - 0000E68A CAFA Predefined 0
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
desh
сообщение May 31 2013, 19:13
Сообщение #2


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

Группа: Свой
Сообщений: 113
Регистрация: 25-10-07
Из: Краснодар
Пользователь №: 31 725



Возможно Ваша проблемма не в FreeRTOS, а в прикладной задаче. Переполнение буфера, ошибка в математике указателей, доступ к общей памяти из нескольких задач без блокировок и т.п.
Использую FreeRTOS c ATmega2561 как с внешней памятью так и без нее. За несколько лет работы в этой связке все проблемы возникали только из-за ошибок прикладного кода.
Сейчас стек вызовов 100 байт (глубина порядка 30). Для себя доработал ядро так, что кроме переполнения CStack я отслеживаю еще и переполнение RStack.

Протестируйте внешнюю память на предмет ошибок. Очень может быть у Вас проблемма с железом.
Я использую вот такой тест. Попробуйте доработать его под себя.

CODE

#include "types.h"
#include <stdio.h>
#include <stdlib.h>

#define MEMORY_START 0x1100
#define MEMORY_SIZE 32768

USHORT Errors;
ULONG Tests;
ULONG Total;

void Delay(USHORT Ms)
{
TCCR1B_WGM12 = 1; // СTС
OCR1A = (F_CPU / (2 * 8 * 1000)) - 1;
TCNT1 = 0;
TCCR1B_CS11 = 1; // Прескаллер 8
while (Ms--)
{
#ifdef NDEBUG
while (!TIFR_OCF1A); // Ждем флаг 1мс
TIFR_OCF1A = 1; // Сброс флага
#endif
}
TCCR1B_CS11 = 0; // Таймер отключен
}

void SetLedGreen(bool State)
{
DDRF_DDF2 = 1;
PORTF_PORTF2 = State ? 0 : 1;
}

void SetLedRed(bool State)
{
#if defined(_MA_301_)
DDRE_DDE7 = 1;
PORTE_PORTE7 = State ? 0 : 1;
#else
DDRB_DDB4 = 1;
PORTB_PORTB4 = State ? 0 : 1;
#endif
}

void UartInit(ULONG Baud)
{
USHORT Reg = (F_CPU / (Baud * 16)) - 1;

#if defined(_MA_301_)
UBRR1H = Reg >> 8;
UBRR1L = Reg;
UCSR1C = (1 << UCSZ11)|(1 << UCSZ10); // 8-N-1
UCSR1B = (1 << RXEN1)|(1 << TXEN1);
#elif defined(_M_320_)
UBRR1H = Reg >> 8;
UBRR1L = Reg;
UCSR1C = (1 << UCSZ11)|(1 << UCSZ10); // 8-N-1
UCSR1B = (1 << RXEN1)|(1 << TXEN1);
DDRD_DDD6 = 1;
PORTD_PORTD6 = 1;
#else
UBRR0H = Reg >> 8;
UBRR0L = Reg;
UCSR0C = (1 << UCSZ01)|(1 << UCSZ00); // 8-N-1
UCSR0B = (1 << RXEN0)|(1 << TXEN0);
DDRD_DDD7 = 1;
PORTD_PORTD7 = 0;
#endif
}

#ifdef NDEBUG
int putchar(int Char)
{
#if defined(_MA_301_)
while (!UCSR1A_UDRE1);
UDR1 = Char;
#elif defined(_M_320_)
while (!UCSR1A_UDRE1);
UDR1 = Char;
#else
while (!UCSR0A_UDRE0);
UDR0 = Char;
#endif
return Char;
}
#endif

void MemoryEnable()
{
DDRF_DDF3 = 1;
MCUCR_SRE = 1;
}

void MemoryInit(UCHAR InitVal)
{
UCHAR *ExtMem = (UCHAR*)MEMORY_START;

for (ULONG Index = 0; Index < MEMORY_SIZE; Index++)
{
ExtMem[Index] = InitVal ^ Index;
}
}

void MemoryTest(UCHAR InitVal)
{
UCHAR ReadVal;
UCHAR *ExtMem = (UCHAR*)MEMORY_START;

for (ULONG Index = 0; Index < MEMORY_SIZE; Index++)
{
ReadVal = ExtMem[Index] ^ Index;
if (ReadVal != InitVal) Errors++;
}
}

int main( void )
{
bool State = false;

UartInit(115200);
printf("Memory test\r\n");
MemoryEnable();
for (;;)
{
UCHAR InitVal = rand();

SetLedGreen(State ^= true);
MemoryInit(InitVal);
MemoryTest(InitVal);
Total += Errors;
SetLedRed(Total ? true : false);
printf("Test %lu, Init 0x%02X, Errors %hu, Total %lu\r\n", Tests, InitVal, Errors, Total);
Errors = 0;
Tests++;
}
}


Сообщение отредактировал desh - May 31 2013, 19:29
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Aeore   Резервирование RSTACK для AVRMega   May 30 2013, 19:53
- - Aeore   Переполнение буфера, очевидно, происходит, но по н...   Jun 1 2013, 21:25
- - desh   Да не спешите Вы. Там от 323 до 128 один регистр с...   Jun 1 2013, 21:50
- - framer   А может еще зависит от размера стека для конкретно...   Jun 2 2013, 06:17
- - Aeore   desh, RAMPZ у меня не сохранялся, спасибо. Я сейча...   Jun 2 2013, 08:31
|- - desh   Цитата(Aeore @ Jun 2 2013, 12:31) а так ж...   Jun 2 2013, 09:33
||- - Aeore   Цитата(desh @ Jun 2 2013, 12:33) Что меша...   Jun 3 2013, 18:15
||- - framer   Цитата(Aeore @ Jun 3 2013, 21:15) А тепер...   Jun 6 2013, 08:33
||- - Aeore   Цитата(framer @ Jun 6 2013, 11:33) А пров...   Jun 12 2013, 20:09
||- - framer   Цитата(Aeore @ Jun 13 2013, 00:09) CODE [...   Jun 14 2013, 12:06
||- - framer   Цитата(Aeore @ Jun 16 2013, 23:59) Как он...   Jun 17 2013, 06:11
|- - _Артём_   Цитата(Aeore @ Jun 2 2013, 11:31) Програм...   Jun 2 2013, 12:16
- - desh   Так. ЧуднО у вас все. ЦитатаЦикл есть. Перезагруж...   Jun 3 2013, 20:01
|- - Aeore   Цитата(desh @ Jun 3 2013, 23:01) Запретит...   Jun 5 2013, 18:54
- - desh   ЦитатаПробовал. Симулятор вел себя не вполне адекв...   Jun 7 2013, 13:42
- - desh   У вас как на АВР-е определен базовый тип portBASE_...   Jun 14 2013, 06:52
|- - Aeore   Цитата(desh @ Jun 14 2013, 09:52) У вас к...   Jun 16 2013, 20:59
- - Aeore   Да, это так. Я недавно перевел систему из преемпти...   Jun 25 2013, 08:11


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

 


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


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