|
отладка scmrtos |
|
|
|
Aug 21 2013, 05:32
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Полагаю, проблема в оптимизации. Ось компилируется с достаточно высокой степенью оптимизации и связь между исходником и ассемблерным кодом становится далеко не однозначной. Сишный же код наверняка компилится вообще без оптимизации, поэтому никаких неоднозначностей не возникает. Остается выбрать: если мы хотим писать большие медленные программы, то надо отключить оптимизацию и при компиляции C++. Если же мы хотим писать маленькие быстрые программы, то надо открывать рядом окно дизассемблера и отлаживаться в нем. Вариант "отключать оптимизацию на время отладки" - это вообще не вариант, ибо а) будет отлаживаться фактически другая программа б) не факт что она вообще соберется (без оптимизациии отключается встраивание) в) после включения оптимизации в якобы отлаженной программе она может перестать работать и горе-программист окажется в той же ситуации, что и в начале - программа не работает, а отлаживать оптимизированный код он не умеет.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 22 2013, 06:34
|
Частый гость
 
Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463

|
добрый день, подскажите как правильно использовать init_stack_frame() и stack_slack(), если можно на примере, что то у меня не получается с этими функциями программу скомпилировать - ошибки такого плана CODE cannot call member function 'size_t OS::TBaseProcess::stack_slack() const' without object main.cpp no matching function for call to 'OS::process<(OS::TPriority)1u, 300u>::init_stack_frame()' main.cpp вот в таком вот коде CODE template <> OS_PROCESS void TProc4::exec() {init_stack_frame(); for(;;) {res_table.uregs[104]=stack_slack(); GreenLED::On(); sleep(50); GreenLED::Off(); sleep(950); } } что я не так делаю? кажется разобрался... init_stack_frame(); вызывается самой ос а stack_slack(); следует вызывать таким образом Proc4.stack_slack(); верно? то есть в итоге делать так CODE template <> OS_PROCESS void TProc4::exec() {//init_stack_frame(); for(;;) {res_table.uregs[104]=Proc4.stack_slack(); GreenLED::On(); sleep(50); GreenLED::Off(); sleep(950); } }
Сообщение отредактировал сарматъ - Sep 22 2013, 07:03
|
|
|
|
|
Oct 18 2013, 10:49
|
Частый гость
 
Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463

|
продолжаю тему начатую тутплатка работает под управлением ос, через несколько дней работы ос перестает переключать задачки, при этом сама ос продолжает работать в одной из задач есть мигание светодиодом, эта задачка никого не ждет никаких ресурсов, вот ее код Код template <> OS_PROCESS void TProc4::exec() {//init_stack_frame(); for(;;) {res_table.uregs[104]=stack_slack(); GreenLED::On(); sleep(50); GreenLED::Off(); sleep(950); } } но светодиодик моргать перестает подскажите какие места в ос посмотреть отладчиком какие переменные чтобы понять отчего перестали переключаться задачки?
Сообщение отредактировал сарматъ - Oct 18 2013, 10:50
|
|
|
|
|
Oct 18 2013, 13:33
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Здесь я вижу только три возможные проблемы: 1) Перестают генериться прерывания системного таймера. Это можно проверить, останавливая и запуская программу и смотря на переменную Kernel.SysTickCount. Если она меняется - значит прерывания генерятся и обработчик вызывается. 2) Из-за переполнения стека в переменную Timeout этого процесса заносится ноль и ожидание этого процесса становится бесконечным, либо заносится какое-то огромное число и вы просто не дожидаетесь окончания задержки sleep(). Опять же отлавливается отладчиком наблюдая за этой переменной - тикает ли и дотикивает ли до нуля. 3) Какой-то из более высокоприоритетных процессов крутится в цикле не отдавая управление (не впадая в ожидание в каком-либо из системных сервисов). Или же более высокоприоритетные процессы не успевают выполнить свою работу и до низкоприоритетных очередь просто не доходит. Это отлавливается наблюдая за тем, где крутится программа - если в IdleTask, то все нормально, если в каком-то из процессов - разбираться, почему он не отдает управление.
Есть еще одна возможная причина - 4) во время выполнения этой задачи происходит перепланировка, которая по какой-то неведомой причине удаляет эту задачу из карты активных задач. Это можно проверить, поставив точку останова в IdleTask и посмотрев на переменную Timeout этого процесса и на карту активных процессов Kernel.ReadyProcessMap. Либо ReadyProcessMap должен содержать единичку в бите этого процесса, либо Timeout должен быть ненулевым. Ни вторая, ни четвертая не объясняют, почему останавливаются и другие задачи тоже. Ну разве что кто-то обнуляет ReadyProcessMap, останавливая все процессы.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 18 2013, 15:50
|
Частый гость
 
Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463

|
да в этом месте Код void OS::TKernel::system_timer() { SYS_TIMER_CRIT_SECT(); #if scmRTOS_SYSTEM_TICKS_ENABLE == 1 SysTickCount++; #endif точки останова не срабатывают, Kernel.SysTickCount не увеличивается, но я не понимаю изза чего, подскажите куда копать дальше? в задачке есть прерывания - они работают, в том смысле что прерывания разрешены... в TIdleProc::exec() тоже ос попадает
Сообщение отредактировал сарматъ - Oct 18 2013, 16:06
|
|
|
|
|
Oct 19 2013, 08:23
|
Частый гость
 
Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463

|
наехал телнетом на опеносд посмотрел значения регистров связанных с таймером систик 0xE000E010 - 0х00010007 - прерывания разрешены (не понял пока назначение 16-го бита пробовал его сбрасывать с помощью mww команды, этот бит все равно устанавливается в единицу)0хЕ000Е014 - 0х0002903f - значение регистра перезагрузки 0хЕ000Е018 - все время разные значения - таймер тикает это прерывание не вызывается CODE extern "C" OS_INTERRUPT void Default_SystemTimer_ISR() { scmRTOS_ISRW_TYPE ISR;
#if scmRTOS_SYSTIMER_HOOK_ENABLE == 1 system_timer_user_hook(); #endif
Kernel.system_timer();
#if scmRTOS_SYSTIMER_NEST_INTS_ENABLE == 0 DISABLE_NESTED_INTERRUPTS(); #endif } нашел разницу между работающей и нерабочей системой в работающей системе регистр 0xe000ed04 равен 0 когда система залипла то значение 1400e84d выходит что pendsv, равно как и систик отложены поэтому прерывание систик больше не генерируется, так? и что с этим делать?
Сообщение отредактировал сарматъ - Oct 19 2013, 17:11
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|