Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Начало работы with scmRTOS
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
Страницы: 1, 2, 3, 4, 5, 6
Alex_rav(зеленинький я есть)
Доброго времени суток.
Давно используем ScmRTOS в своих проектах. До этого работали на LPC2148/2368/2387. В новом проекте используем LPC4330, да к тому же переходим на новую среду разработки (был IAR, а стал Eclipse+CodeSourcery). В данный момент перенес порт для Cortex-M4 в готовый, работающий проект для LPC4330. Прерывания от системного таймера и PendSV приходят, но ось раз за разом падает в HardFault. Причем падает после отработки по разу всех процессов, т.е. когда все процессы перешли в sleep. падает на строках

CODE
void TKernel::sched()
{
uint_fast8_t NextPrty = highest_priority(ReadyProcessMap);
if(NextPrty != CurProcPriority)
{
SchedProcPriority = NextPrty;

raise_context_switch();
do // <--------------------------- вот здесь
{
enable_context_switch();
DUMMY_INSTR();
disable_context_switch();
}
while(CurProcPriority != SchedProcPriority); // until context switch done
}
}


Я использую стартап и ld-скрипт от библиотеки CMSIS. С стартапом понятно, там переделал названия прерываний и все, а подскажите пожалуйста с ld-скриптом. Сейчас он выглядит вот так:

CODE

OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
ENTRY(_start)
SEARCH_DIR(.)
GROUP(-lgcc -lc -lcs3 -lcs3unhosted -lcs3micro)

MEMORY
{
rom (rx) : ORIGIN = 0x10000000, LENGTH = 128K
ram (rwx) : ORIGIN = 0x10008000, LENGTH = 32K
}

/* These force the linker to search for particular symbols from
* the start of the link process and thus ensure the user's
* overrides are picked up
*/
EXTERN(__cs3_reset_cortex_m)
EXTERN(__cs3_interrupt_vector_cortex_m)
EXTERN(__cs3_start_c main __cs3_stack __cs3_stack_size __cs3_heap_end)

PROVIDE(__cs3_stack = __cs3_region_start_ram + __cs3_region_size_ram);
PROVIDE(__cs3_stack_size = __cs3_region_start_ram + __cs3_region_size_ram - _end);
PROVIDE(__cs3_heap_start = _end);
PROVIDE(__cs3_heap_end = __cs3_region_start_ram + __cs3_region_size_ram);

SECTIONS
{
.text :
{
CREATE_OBJECT_SYMBOLS
__cs3_region_start_rom = .;
*(.cs3.region-head.rom)
__cs3_interrupt_vector = __cs3_interrupt_vector_cortex_m;
*(.cs3.interrupt_vector)
/* Make sure we pulled in an interrupt vector. */
ASSERT (. != __cs3_interrupt_vector_cortex_m, "No interrupt vector");
*(.rom)
*(.rom.cool.gif

__cs3_reset = __cs3_reset_cortex_m;
*(.cs3.reset)
/* Make sure we pulled in some reset code. */
ASSERT (. != __cs3_reset, "No reset code");

*(.text .text.* .gnu.linkonce.t.*)
*(.plt)
*(.gnu.warning)
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)

*(.rodata .rodata.* .gnu.linkonce.r.*)

*(.ARM.extab* .gnu.linkonce.armextab.*)
*(.gcc_except_table)
*(.eh_frame_hdr)
*(.eh_frame)

. = ALIGN(4);
KEEP(*(.init))

. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;

. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;

. = ALIGN(0x4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))

. = ALIGN(4);
KEEP(*(.fini))

. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;

KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))

. = ALIGN(4);
__cs3_regions = .;
LONG (0)
LONG (__cs3_region_init_ram)
LONG (__cs3_region_start_ram)
LONG (__cs3_region_init_size_ram)
LONG (__cs3_region_zero_size_ram)
}

/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} >rom
__exidx_end = .;
.text.align :
{
. = ALIGN(8);
_etext = .;
} >rom
__cs3_region_size_rom = LENGTH(rom);
__cs3_region_num = 1;

.data :
{
__cs3_region_start_ram = .;
*(.cs3.region-head.ram)
KEEP(*(.jcr))
*(.got.plt) *(.got)
*(.shdata)
*(.data .data.* .gnu.linkonce.d.*)
*(.ram)
. = ALIGN (8);
_edata = .;
} >ram AT>rom
.bss :
{
__bss_start__ = .;
*(.shbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
*(.ram.cool.gif
. = ALIGN (8);
_end = .;
__end = .;
__bss_end__ = .;
} >ram AT>rom
.heap :
{
*(.heap)
} >ram
.stack (__cs3_stack - __cs3_stack_size) :
{
*(.stack)
} >ram
__cs3_region_init_ram = LOADADDR (.data);
__cs3_region_init_size_ram = _edata - __cs3_region_start_ram;
__cs3_region_zero_size_ram = _end - _edata;
__cs3_region_size_ram = LENGTH(ram);
__cs3_region_num = 1;

.stab 0 (NOLOAD) : { *(.stab) }
.stabstr 0 (NOLOAD) : { *(.stabstr) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }

.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) }
}


Сергей Борщ
Цитата(Alex_rav(зеленинький я есть) @ Feb 25 2014, 13:30) *
Причем падает после отработки по разу всех процессов, т.е. когда все процессы перешли в sleep.
У меня такое поведение наблюдается когда обработчик прерывания системного таймера не попадает в таблицу векторов и вместо него попадает либо 0 либо default_handler.
Alex_rav(зеленинький я есть)
Странно, но в Hardfault падает после перехода в процесс TIdleProc.

CODE

template<> void TIdleProc::exec()
{
for(;;)
{
#if scmRTOS_IDLE_HOOK_ENABLE == 1
idle_process_user_hook(); \\ <------------------заходит сюда и потом падает в HardFault
#endif

#if scmRTOS_TARGET_IDLE_HOOK_ENABLE == 1
idle_process_target_hook();
#endif
}
}


Прерывания системного таймера происходят, вижу это в отладчике. Чувствую что где-то что-то просто пропустил при переносе, но не пойму пока что.
Сергей Борщ
idle_process_user_hook() - ваша функция. Может стека для TIdleProc мало выделили и она складывая в стек содержимое LR что-то портит?
Alex_rav(зеленинький я есть)
Цитата(Сергей Борщ @ Feb 25 2014, 17:05) *
idle_process_user_hook() - ваша функция. Может стека для TIdleProc мало выделили и она складывая в стек содержимое LR что-то портит?


Размер для стека :

CODE
#define scmRTOS_IDLE_PROCESS_STACK_SIZE (100 * sizeof(stack_item_t))


Мне тоже кажется что что-то не ладно со стеком. Буду разбираться с скриптами и памятью.
amusin
Пробую запустить проект-пример 1-EventFlag на STM32VL-Discovery в средах Eclipse и Atollic.
Проект собрал вне среды запуском утилиты make, натравив на компилятор - gnuarm/4_6_2012q2. Все под Win7x64.
В районе перехода на os_start() ядро уходит в Hard Fault.
Atollic выдает чуть больше инфы: говорит о попытке обращения по адресу 0x20002004 (ОЗУ до 0x20001FFF).
В чем может быть дело?

Начал осваивать Eclipse и еще не разобрался, как сделать отображение листинга ассемблера (не компилятора) в окне Disassembly.
Потому пока точно не знаю, на какой строке вылетает.

PS. В makefile помимо пути до компилятора поправил CHIP = STM32F10X_MD_VL (на дискавери value-line).
Сергей Борщ
Цитата(amusin @ Feb 28 2014, 12:36) *
PS. В makefile помимо пути до компилятора поправил CHIP = STM32F10X_MD_VL (на дискавери value-line).
Надо также поправить размеры памяти в скрипте линкера (*.ld)
amusin
Цитата(Сергей Борщ @ Feb 28 2014, 17:27) *
Надо также поправить размеры памяти в скрипте линкера (*.ld)

Вроде все необходимое сделал автор примеров. Линкеру подсовывается $(CHIP).ld
Было:
Код
MEMORY
{
    RAM (xrw)    : ORIGIN = 0x20000000, LENGTH =  20K
...

Стало:
Код
MEMORY
{
    RAM (xrw)    : ORIGIN = 0x20000000, LENGTH =  8K
...
AHTOXA
Хм. По идее всё должно работать после правки параметра CHIP в makefile.
Попробуйте пример 4-Debug, он изначально рассчитан на discovery.
Если не заработает, попробуйте другой компилятор. На нём всё проверялось.
amusin
Цитата(AHTOXA @ Mar 2 2014, 00:05) *
Хм. По идее всё должно работать после правки параметра CHIP в makefile.
Попробуйте пример 4-Debug, он изначально рассчитан на discovery.
Если не заработает, попробуйте другой компилятор. На нём всё проверялось.

Попробовал пример 4-Debug - не заработал. Попробовал рекомендованный компилятор - работают оба проекта! Спасибо за подсказку!
Глянул в листинг. В компиляторе 4.6... переход на os_start выглядит так
Код
80002c0:    f7ff ffa6     bl    8000210 <os_start>
80002c4:    200003c4     .word    0x200003c4

В рекомендованном 4.8... -
Код
80002c6:    f7ff ffa3     bl    8000210 <os_start>
80002ca:    bf00          nop

AHTOXA
Не вижу ничего криминального в этом фрагменте листинга. Скорее всего косяк где-то дальше.
Но раз проблема решена, то и фиг с нимsm.gif
Argon-11
Не знаю, по адресу обращаюсь или нет...
Не удается скомпилировать 1-EventFlag с помощью GCC 4.8.

выдает вот это:

z:\GCC_ARM\1-EventFlag>make
--- building 1-EventFlag
Ошибка в синтаксисе команды.
Ошибка в синтаксисе команды.
Ошибка в синтаксисе команды.
Ошибка в синтаксисе команды.
--- compiling ./src/main.cpp...
./src/main.cpp:128:1: fatal error: opening dependency file obj/main.d: No such f
ile or directory
compilation terminated.
make: *** [obj/main.o] Ошибка 1

В чем м.б. дело?

До этого ставил Sourcery G++ Lite 2010.09-51 - то же самое.

на форуме вычитал, что "может отсутствовать sh.exe"
что это такое и где взять? почему этого нет в комплекте с make или того же G++ Lite?

установил CoreUtils, ошибка пропала.
но возникла другая проблема:

z:\GCC_ARM\1-EventFlag>make
--- building 1-EventFlag
--- compiling ./src/main.cpp...
make: Interrupt/Exception caught (code = 0xc00000fd, addr = 0x4217b3)


вроде тоже пропала проблема: перенес все, что касается GNU (GCC, CoreUtils) в папку без скобок в названии (было в Program Files (x86))
теперь пытаюсь прикрутить к eclipse...
mdmitry
Для начинающих может быть полезно:
scmrtos-installation-on-arduino
sevstels
Хочу поинтересоваться таким нюансом.
Приходится поддерживать много разных проектов под AVR для разных потребителей и высылать им обновления, чтоб они могли собирать свои проекты самостоятельно. Собрал подпрограммы в IAR библиотеку, чтоб было легче сопровождать. Но тут столкнулся с трудностью: не получается вкомпилировать объекты scmRTOS в библиотеку. Например мютексы. RTOS "не собирается" без настроек под конкретный проект. Может кто сталкивался, подскажите решение.
k155la3
Цитата(sevstels @ Sep 16 2015, 14:48) *
Хочу поинтересоваться таким нюансом.
Приходится поддерживать много разных проектов под AVR для разных потребителей и высылать им обновления, чтоб они могли собирать свои проекты самостоятельно. Собрал подпрограммы в IAR библиотеку, чтоб было легче сопровождать. Но тут столкнулся с трудностью: не получается вкомпилировать объекты scmRTOS в библиотеку. Например мютексы. RTOS "не собирается" без настроек под конкретный проект. Может кто сталкивался, подскажите решение.


Там, насколько помню, используются шаблоны.
Это может ограничить возможность сборки универсальной библиотеки.
Или вообще такую возможность.

Код
namespace OS
{
    template<> void TIdleProc::exec()
    {
        for(;;)
        {
        #if scmRTOS_IDLE_HOOK_ENABLE == 1
            idle_process_user_hook();
        #endif

        #if scmRTOS_TARGET_IDLE_HOOK_ENABLE == 1
            idle_process_target_hook();
        #endif
        }
    }
}



AlexG
Использовал ли кто-нибудь scmRTOS с IAR EWARM со включенной опцией "Enable thread support in library"?
Возникли проблемы с динамическим выделением памяти в нескольких процессах одновременно - malloc по умолчанию не реентерабельный и программа падает очень быстро. Вариантов решения два:
  1. Подменить malloc и free на свои через --redirect malloc и --redirect free
  2. Использовать штатные IARовские библиотечные функции в многопоточном варианте, для этого надо реализовать System locks interface, а конкретно функции
    void __iar_system_Mtxinit(__iar_Rmtx *); /* Initialize a system lock */
    void __iar_system_Mtxdst(__iar_Rmtx *);/*Destroy a system lock */
    void __iar_system_Mtxlock(__iar_Rmtx *); /* Lock a system lock */
    void __iar_system_Mtxunlock(__iar_Rmtx *); /* Unlock a system lock */
    и еще четыре аналогичных __iar_file_*


Второй вариант выглядит предпочтительным, т.к. если ограничиться заменой malloc конфликт может вылезти в какой-нибудь другой не реентерабельной функции системной библиотеки. Но есть сомнения в возможности увязать System locks interface с ОС на C++:
допустим, выполняется оператор new, он вызывает malloc, тот вызывает __iar_system_Mtxlock, тот должен использовать Tmutex, но чтобы существовал объект класса Tmutex, нужно чтобы он был создан с помощью new (явно или не явно). Проблема курицы и яйца какая-то.
AHTOXA
Цитата(AlexG @ May 26 2018, 15:19) *
должен использовать Tmutex, но чтобы существовал объект класса Tmutex, нужно чтобы он был создан с помощью new (явно или не явно). Проблема курицы и яйца какая-то.

Можно создать объект класса TMutex статически.
AlexG
По варианту 1 все получилось. Одного статически созданного мьютекса хватило, чтобы потоки не дрались за подмененный malloc. Других конфликтов из-за многопоточности внутри стандартной библиотеки пока не обнаружилось.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.