Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не могу включить оптимизацию, иниализировать переменные
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
yuragv
Иар 2.10 для Hitachi H8S. проц 36049.

проект дорос до максимального размера флеш 92к.
при включении оптимазации по размеру Low - работает, а при медиум и high
размер получившегося кода становиться меньше 1кб. походже только стартап остаеться.
можно как-то побороться с этим?

модель памяти huge, если включить small, то код уменьшаеться до 80 кб,
но тогда не получаеться нормально работать с указателями на константы,
может быть в этом случае можно хитрость какую применить?
yuragv
IAR 2.10 проц Hitachi H8. модель памяти HUGE.
Потребовалось перенести код программы по адресу 0x6200,
с нуля лежит загрузчик.
Не происходит инициализация переменных.
прописал -P(CONST)DATA32_ID=6200-1FFFF


Подскажите плиз в чем может быть трабл.
yuragv
модератор собрал два мои сообщения в одну тему, но прошу заметить, что проекты разные и общее в двух вопросах только компилятор.
sergik_vrn
Цитата(yuragv @ Dec 20 2008, 01:01) *
Иар 2.10 для Hitachi H8S. проц 36049.

проект дорос до максимального размера флеш 92к.
при включении оптимазации по размеру Low - работает, а при медиум и high
размер получившегося кода становиться меньше 1кб. походже только стартап остаеться.
можно как-то побороться с этим?

надо бы для начала хотя бы листинг линкера увидеть

Цитата
модель памяти huge, если включить small, то код уменьшаеться до 80 кб,
но тогда не получаеться нормально работать с указателями на константы,
может быть в этом случае можно хитрость какую применить?

попробуйте описать указатель как __far
yuragv
ссылка на листинг
http://upload.com.ua/get/900612670/

__far в данном компиляторе отсутствует, есть __data32.
в принципе помогает, но не всегда.

смотрите что происходит.

есть константный массив шрифтов,
есть функция рисующая символ из этого массива PrintChar(char Sym)
и есть функция выводящая строку символов PrintStr(char* Str), с помощью пред. функции.

так вот. при выводе строки текста при помощи PrintStr из разных мест программы
в некотрых случаях строка текста отображаеться нормально, а некоторых ЧАСТЬ символов отображаеться мусором. то есть если б неправильно передавался указател на строку в ф-ции
PrintStr то неправильно б отображалась вся строка.
Сергей Борщ
Цитата(yuragv @ Dec 20 2008, 18:57) *
Не происходит инициализация переменных.
прописал -P(CONST)DATA32_ID=6200-1FFFF
Подскажите плиз в чем может быть трабл.
Чего-то не качается ваш map. С Н8 не работал, но в иаре для других платформ адреса инициализации указаны в сегменте INITTAB. В вашем скрипте линкера с телесистем этот сегмент не упомянут. На этом форуме вы скрипт вообще не показали. Если и там не полный скрипт - то не совсем понятно, на какую помощь вы рассчитываете. Телепатировать очень трудно, поэтому, если вам не сложно, выложите (можно тут же) минимальный проект, в котором эффект повторяется. Как я понимаю, это должно быть что-то вроде
Код
int a = 1, b = 2;
int main()
{
    b = a;
    return 0;
}


Цитата(yuragv @ Dec 22 2008, 22:44) *
то есть если б неправильно передавался указател на строку в ф-ции
PrintStr то неправильно б отображалась вся строка.
Больше похоже на порчу регистров или локальных переменных на стеке прерыванием. Ассемблерного обработчика прерывания в программе нет случайно?
yuragv
xcl-файл полностью

-ch8
-P(CONST)INTVEC=0-3FF
-P(CONST)FLIST=40-FF
-P(CODE)CODE24=6200-1FFFF
-P(CONST)DATA32_ID=6200-1FFFF
-Z(CONST)DIFUNCT=
-P(CONST)DATA32_C=
-Z(CONST)CHECKSUM=6200-1FFFF
-Z(DATA)DATA32_I,DATA32_Z,DATA32_N=FFF400-FFFBFF
-Z(DATA)DATA32_HEAP+_DATA32_HEAP_SIZE=
-Z(DATA)CSTACK+_CSTACK_SIZE#FFF400-FFFBFF

в описании к нему сказано:
/* DATA32_ID -- Initialization data for DATA32_I */
я добавил INITTAB
-P(CONST)INITTAB, DATA32_ID=6200-1FFFF
но это не помогло.

отладчика нет у меня, поэтому мин. проект будет все равно великовал. отладочную инфу я через уарт выводил.


что каксаеться втрого проекта. прерываний в асме нет. функции дисплея некоторые в асме. попробую убрать их пока.
yuragv
вопрос с оптимизацией решен.

осталось только разобраться с инициализацией переменных
Сергей Борщ
Цитата(yuragv @ Dec 23 2008, 11:15) *
отладчика нет у меня, поэтому мин. проект будет все равно великовал. отладочную инфу я через уарт выводил.
Проект с одним-единственным исходным файлом с текстом из сообщения №6 занимает много места? Для его проверки отладчик не нужен - достаточно встроенного в IAR симулятора.
Цитата(yuragv @ Dec 23 2008, 11:15) *
функции дисплея некоторые в асме. попробую убрать их пока.
Вы соблюдаете правила совместного использования С и асм? Возможно вы иногда портите какой-либо из регистров, который должны были бы сохранить при входе в функцию и восстановить при выходе.
Цитата(yuragv @ Dec 25 2008, 14:32) *
вопрос с оптимизацией решен.
Обычно принято сообщать, в чем была ошибка, чтобы наступившие на эти же грабли нашли здесь не только уверенность, что они не одиноки, но и решение.
Цитата(yuragv @ Dec 25 2008, 14:32) *
осталось только разобраться с инициализацией переменных
Родилось предположение - а вы случайно не используете самописный стартап? В таком случае вы должны из него вызывать библиотечные функции инициализации данных или писать свои аналоги.
yuragv
Спасибо большое за ответы.
Я прошу прощения за сумбурность и невнятность.

С оптимизацией не удалось разобраться, просто я перевел память данных в модель small и программа уменьшилась процентов на 10%.
А память портилась из-за неправильной очистки ее же, которая осталась от проекта в старом железе и не была вовремя замечена. К оптимизации еще придеться вернуться.

По поводу инициализация, я кажеться понял в чем дело. Поскольку в устройстве имеется сторониий загрузчик, необходимое условие - программа должна располагаться с адреса 0x6000. Таблица векторов в загрузчике перенаправляет прерывание на адрес 0x6000+addr_vector. я соответственно прописал свои переходы на функции прерываний. по адресу 0x6000 я поставил jmp main. то есть в стартап у меня не попадает программа при старте. как сделать чтобы программа стартовала в стартап?


нашел. стартую в __program_start. все инициализируется.
Сергей Борщ
Цитата(yuragv @ Dec 28 2008, 17:50) *
я соответственно прописал свои переходы на функции прерываний.
Каким образом? Возможно именно здесь и кроется ошибка, из-за которой оптимизатор все выкидывает.
yuragv
org 6000H
jmp @__program_start
; прерывание TPU0 - системный таймер
org 6080H
jmp @InterruptSysTimer
; прерывание TPU3 - uart2
org 60C0H
jmp @IntUart2Function


зря модератор свел две темы в одну.

про оптимизацию это один проект,
а про инициализацию - другой(там где программу перенести потребовалось по адресу 0x6000)

кстати все равно локальные переменные внутри ф-ции не инициализируються
Сергей Борщ
Цитата(yuragv @ Dec 28 2008, 21:24) *
org 6000H
jmp @__program_start
А перед этим стоит ASEG:ROOT?
P.S. И используйте кнопку '#' на форме ввода для оформления исходников.
Цитата(yuragv @ Dec 28 2008, 21:24) *
кстати все равно локальные переменные внутри ф-ции не инициализируються
Приводите пример кода. Инициализация локальных переменных никак не связана со стартапом. Или вы имеете ввиду, что не обнуляются неинициализированные локальные переменные? Так они и не должны, их надо инициализировать явно.
yuragv
может подскажите еще такую вещь:

процессор 16-ти битный.


пример:

byte TmpBuf[1000];
byte Board;

*((dword *)(TmpBuf+10))=0x06000100;

в данном случае дает правильный результат.

если поменять местами byte TmpBuf[1000] и byte Board;

то в итоге TmpBuf будет заполнен так 00,01,00,00
то есть 0x06 выйдет за границу массива.

как сделать так чтобы TmpBuf всегда лежал по четному адресу?
HARMHARM
Цитата(yuragv @ Dec 28 2008, 22:01) *
как сделать так чтобы TmpBuf всегда лежал по четному адресу?

Для IAR:
Код
#pragma data_alignment = 2
yuragv
Код
void FuncTest(void)
{
   byte buf[]="test";
  
   if(buf[0]=='t') {  
       // эта часть кода не выполняеться
   }
}
Сергей Борщ
А что показывает листинг?
sergeeff
Сегмент данных лежит там, где ожидается?
yuragv
нашел я где собачка порылась.


при инициализации локальных переменных (а именно массивов) компилятор использует функцию memcpy32, при этом вызов memcpy32 делает через таблицу векторов.


Решение проблемы :
Поставил в опциях Library Calls -> Direct



P.S. однако рано радовался.
функция atoi не хочет отказываться от вызовов
через таблицу векторов.
как быть?
Сергей Борщ
Цитата(yuragv @ Jan 4 2009, 15:50) *
функция atoi не хочет отказываться от вызовов
через таблицу векторов.
как быть?
Функция уже скомпилирована в библиотеку, значит надо подключить другой вариант библиотеки (если таковой имеется) или обеспечить работоспособность вызовов через векторы. Не знаком с архитектурой H8S, не могли бы вы кратенько изложить ее особенности, как физически реализуются вызовы через таблицу векторов и для чего используется именно такой механизм? По аналогии с AVR и MSP430 могу предположить, что вам надо было таблицу векторов расположить в файле линкера с адреса 0x6200, а в загрузчике сделать перенаправление свободных векторов из таблицы загрузчика на таблицу приложения. Таким образом приложение будет менее всего завязано на загрузчик и переход с варианта "с загрузчиком" на вариант "без загрузчика" сведется к замене _..X_ROM_START_ с 0x6200 на 0x0000:
Код
-D_..X_ROM_START_=0x6200
/*
* The '_..X_' prefix is used by C-SPY as an indication that the label should
* not be displayed in the dissassembly window.
*/
-P(CONST)INTVEC=_..X_ROM_START_-(_..X_ROM_START_+3FF)
-P(CONST)FLIST=(_..X_ROM_START_+40)-(_..X_ROM_START_+FF)
-P(CODE)CODE24=_..X_ROM_START_-1FFFF
-P(CONST)DATA32_ID,DATA32_C=_..X_ROM_START_-1FFFF
-Z(CONST)DIFUNCT,CHECKSUM=_..X_ROM_START_-1FFFF
yuragv
в загрузчике все вектора перенаправлены на адрес 0x6000+addr_vector.
изначально я свои прерывания в программе так и прописал

Код
org 6000H
jmp @__start_program

org 6080H
jmp @int_sys_timer

и т.д.


но какие функции используються в библиотеках я не знаю. а перенести таблицу FLIST на адрес 0x6000 компилятор не дает. пишет Range Error. Да и не поможет это. Дело в том что в таблице векторов прописаны адреса. а нужна команда jmp @addr.
Поэтому пока пришлось сделать некрасиво. В готовом бинарнике внешней программой переношу таблицу векторов на адрес 0x6000, преобразовывая адрес в команду jmp @addr.


p.s. через таблицу векторов как я понимаю - более быстрый вызов фунцкии. процессор работает в расширенно режиме с 24-битной адресацией. а так короткий восьмибитный адрес получаеться.сильно честно говоря не вникал.
Сергей Борщ
Цитата(yuragv @ Jan 5 2009, 12:23) *
Дело в том что в таблице векторов прописаны адреса. а нужна команда jmp @addr.
Мдас... попадалово. Судя по системе команд для вызова функций по таблице используется команда jsr @@addr:8, которая требует наличия таблицы в первых 256 (512?) байтах. Поэтому не проходит перенос. Команды jmp @@addr:24 для перенаправления таблицы в системе команд нет. Остается только смотреть, есть ли в комплекте компилятора специальная версия библиотеки без использования таблицы, и если такой версии нет - пересобирать библиотеку. Ну или оставлять таблицу в нулевых адресах, не использовать ее в загрузчике и давать возможность загрузчику переписывать ее при обновлении. sad.gif Или писать в загрузчике на каждый вектор подпрограмму с использованием временного регистра и переходом по команде jsr @ERn (тогда range error при перемещении таблицы обходится опцией -Q линкера - кладем ее на 0x6200 а линкуем в 0)
yuragv
спасибо. пока оставлю так как есть. тем более что устройство поставляеться с загрузчиком и менять его никто не будет.
буду думать в процессе. проект долгоиграющий.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.