Перейти к содержанию
    

Вопос по scmRTOS

Сейсас разбираюсь с scmRTOS, загрузил примерчик, все заработало. Но при изменении оптимизации, ставлю Low, то компилятор выдает много Warning и проект не работает в отладчике

 

Warning[Go006]: Too low level of optimization to inline function "OS::RaiseContextSwitch"

Warning[Go006]: Too low level of optimization to inline function "OS::GetHighPriority"

Warning[Go006]: Too low level of optimization to inline function "OS::TKernel::SchedISR"

Warning[Go006]: Too low level of optimization to inline function "SetDataSP"

Warning[Go006]: Too low level of optimization to inline function "SetReturnSP"

Warning[Go006]: Too low level of optimization to inline function "DisableInterrupts"

Warning[Go006]: Too low level of optimization to inline function "OS::TISRW_SS::ISR_Exit"

...

и так далее, количесво 59 шт.

 

Вопрос - можно ли как то настроить ОС или компилятор, чтобы проект заработал? Поскольку при максимальном уровне оптимизации не выполняются куски программы, такое чувство, что компилятор их просто выбрасывает!

 

Версия компилятора IAR 4.30.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос - можно ли как то настроить ОС или компилятор, чтобы проект заработал?
С оптимизацией Low - не получится. Компилятор не позволяет в режимах ниже High включать встраивание функций. Или придется существенно перерабатывать исходники ОС.
Поскольку при максимальном уровне оптимизации не выполняются куски программы, такое чувство, что компилятор их просто выбрасывает!
Чувства - это неправильно. Всегда можно посмотреть листинг и понять - есть в нем код или нет. А выбрасывать код компилятор имеет право - если результат каких-либо действий не используется или если компилятор заранее знает, что какое-либо условие всегда будет истинно или ложно. Обычно такое происходит, если какие-либо переменные, используемые в прерывании или (в случае ОС) в нескольких процессах объявлены без квалификатора volatile.

 

P.S. это не раздвоение личности :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С оптимизацией Low - не получится. Компилятор не позволяет в режимах ниже High включать встраивание функций. Или придется существенно перерабатывать исходники ОС.Чувства - это неправильно. Всегда можно посмотреть листинг и понять - есть в нем код или нет. А выбрасывать код компилятор имеет право - если результат каких-либо действий не используется или если компилятор заранее знает, что какое-либо условие всегда будет истинно или ложно. Обычно такое происходит, если какие-либо переменные, используемые в прерывании или (в случае ОС) в нескольких процессах объявлены без квалификатора volatile.

 

P.S. это не раздвоение личности :)

 

А если переменные объявлены все как extern, то может компилятор так делать?

 

Перед переменными поставил квалификатор volatile, теперь возникает новое предупреждение:

 

Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement

 

И результат то же, не работает программа, т.е. не выполняет куски программы.

 

Пробывал поставить оптимизацию Medium - в этот раз выдает ошибку:

 

Error[e18]: Range error,

PC offset out of range. Valid range is -4096 (-0x1000) to 4094 (0x0FFE).

File: F:\RegMik\Programms\IAR_AVR_scmRTOS\scmRTOS\AVR\OS_Target_asm.s90, Line: 234

Source: xjmp ContextSwitcher_ISR

 

Where $ = #no label found# + 0x2C [0x2C]

in module "scmRTOS_Asm" (F:\RegMik\Programms\IAR_AVR_scmRTOS\УЗ2(RS485)\Debug\Obj\OS_Target_asm.r90),

offset 0x2C in segment part 1, segment INTVEC

What: L_RestoreContext - ($ + 2) [0x103C]

Allowed range: 0xFFFFF000 - 0xFFF

Operand: L_RestoreContext [0x106a]

in module scmRTOS_Asm (F:\RegMik\Programms\IAR_AVR_scmRTOS\УЗ2(RS485)\Debug\Obj\OS_Target_asm.r90),

Offset 0x0 in segment part 2, segment CO

 

Что можете сказать по этому поводу?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если переменные объявлены все как extern, то может компилятор так делать?
extern или нет - не важно. Вот, смотрите простой пример:
extern bool flag;
void Test()
{
      flag = false;
      for(;;)
         if(flag == true)
         { 
             __no_operation();
             flag = false();
         }
}

Здесь компилятор имеет полное право выкинуть проверку условия и все, что внутри условного оператора - ведь он видит, что переменной было присвоено false и нигде не было присвоено true. Зачем же делать бессмысленную работу? Если он будет о каждой переменной строить предположения, никакой оптимизации не получится. Компилятор может поступить и иначе - считать flag в регистр перед циклом и на каждом проходе цикла проверять содержимое регистра. Результат будет таким же плачевным - реальное изменение flag на регистре никак не отразится. А если бы он так не поступал, вы бы в другом месте сразу закричали "зачем он снова считывает переменную в регистры, он же ее вот буквально пару команд назад считывал уже". На этом и основана оптимизация - компилятор выкидывает все лишнее и только вы можете знать, в каких именно случаях оно совсем не лишнее. И вы имеете все инструменты, чтобы объяснить это компилятору. Вот если бы flag был объявлен как extern bool volatile flag; то компилятор был бы обязан при каждом обращении к flag считывать ее значение и уже не мог бы предполагать, что она останется неизменной.

Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
Снова все правильно. У вас в одном выражении в качестве аргумента более одного раза встречается переменная с квалификатором volatile. А порядок вычисления подвыражений стандартом не определен - это решает оптимизатор, как ему покажется лучше. И он вас честно предупреждает, что сегодня он скомпилил доступ к volatile-переменным в одном порядке, а завтра может скомпилить в другом порядке. Вот пример, почему это может быть опасно:
 uint16_t word = ADCL | (ADCH << 8);

Каждое чтение ADCH обновляет содержимое пары ADCH:ADCL следующим результатом АЦП. И сегодня вы подав на вход половину опоры получите word = 0x0200, а после перекомпиляции вполне можете получить 0x0002, причем эти 0x00 и 0x02 будут от разных измерений. Чтобы явно указать компилятору порядок чтения volatile-переменных, надо завести временную переменную:

uint16_t word;
{
    uint8_t Tmp = ADCL;
    word = Tmp | (ADCH << 8);
}

Посмотрите еще вот эту ветку. Там обсасывался подобный случай.

И результат то же, не работает программа, т.е. не выполняет куски программы.
Очень трудно найти ошибку телепатически, не видя ни исходника ни листинга.
Пробывал поставить оптимизацию Medium - в этот раз выдает ошибку:
Это бага, но никак не связанная с вашими проблемами: допишите в начало scmRTOS_Target_asm.s90 перед строчкой #if (A90_PROC_OPTION == 0) || (A90_PROC_OPTION == 1) строчку
#define A90_PROC_OPTION     ((__TID__ >> 4) & 0x0F)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для начала можно просто имеющуюся демку скомпилировать и поиграться, а потом уже своё навешивать.

А про компилятор можно почитать IAR Compiler Reference Guide - я для себя там много интересного открыл.

В том числе, как надо писать и как не надо и что из этого может получиться

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вроде бы все заработало :08: , буду дальше отлаживать и проверять.

ОС scmRTOS заработало как и при оптимизации Medium, так и при оптимизации High, но только переменные передалал как volatile, как мне посоветовал мой тезка. Спасибо :beer:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...