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

 
 
 
Reply to this topicStart new topic
> Страшные глюки с Philips 80C32, уже не знаю что деклать
Shedon
сообщение Feb 8 2005, 12:54
Сообщение #1


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

Группа: Свой
Сообщений: 110
Регистрация: 30-11-04
Из: Nizhny Novgorod
Пользователь №: 1 262



Есть сабжевый контроллер, есть прога на си, код хранится во внешней флэш, на 64кб, есть графический дисплей с контроллером SED1335, стал замечать следующею зависимость: чем больше программа по объёму тем больше становится глюков, сейчас прога весит без оптимизации 56889bytes of code. глюки заключаются в следующем перестаёт выводить графику на экран()рисует какие-то линии от болды), и зависает на этом, причём скол-во глюков зависит неким образом от оптимизации. Больше всех глючат функции обращения к контроллеру дисплея, обработка прерывания от таймера и функции си типа sprintf, vsprintf
. Вот ниже привожу пример как у меня построена работа с дисплеем, эта функция рисует точку в один пихел.

Код
#define BASE_ADDR          0x5000
#define DISP_W_D ((char volatile*) 0x018000)
#define DISP_W_C ((char volatile*) 0x018001)
#define DISP_R_D ((char volatile*) 0x018001)
#define DISP_R_C ((char volatile*) 0x018000)

__data unsigned char n_bit,n_bat,d_byt;
__data unsigned int adress;

//...
//...

void put_pixel(int tx, int ty)
{
   n_bat = tx/8;
   n_bit = tx-n_bat*8;
   adress = BASE_ADDR+(ty*40+n_bat);

   *DISP_W_C=0x46;
   *DISP_W_D=adress;
   *DISP_W_D=adress>>8;
   *DISP_W_C=0x43;
   d_byt=*DISP_R_D;

   d_byt |= (0x80>>n_bit);

   *DISP_W_C=0x46;
   *DISP_W_D=adress;
   *DISP_W_D=adress>>8;
   *DISP_W_C=0x42;
   *DISP_W_D=d_byt;
}


Контроллер дисплея подключён как внешняя память, т.е. здаётся мне глюки происходят при обращение к внешней памяти. Как мне кажется я где-то ошибаюсь с настройками компилятора, да забыл написать, компилятор IAR8051 v6.11, эмулятор PICE51, ниже привожу коммандные файлы с настройками проекта может кто что подскажет, заранее спасибо.

Все файлы проекта компилируются со след. параметрами:
Код
--no_wrap_diagnostics --only_stdout
--core=pl
--code_model=n
--data_model=l
--nr_virtual_regs=8
--calling_convention=pr
--place_constants=data
--require_prototypes
--migration_preprocessor_extensions
-e
--enable_multibytes
-r
-lCN indic
--no_cse
--no_inline
--no_code_motion
--no_unroll
-IC:\PROGRA~1\IARSYS~1\EMBEDD~1.2EV\8051\inc\FileName.c


Илинкуются след. образом:
Код
-IC:\PROGRA~1\IARSYS~1\EMBEDD~1.2EV\8051\config
-D_EXTENDED_STACK_START=2000
-D_EXTENDED_STACK_END=23FF
-D_EXTENDED_STACK_SIZE=3FF
-D?DPS=86
-D_NR_OF_VIRTUAL_REGISTERS=8
-D?DPMASK=1
-D?CBANK=90
-D_CODEBANK_START=8000
-D_CODEBANK_END=10000
-D_IDATA_STACK_SIZE=0x90
-D_PDATA_STACK_SIZE=0x90
-D_XDATA_STACK_SIZE=0xFFF
-e_medium_read=_formatted_read
-l "KALIBR.MAP"
-xsm
-p80
-IC:\PROGRA~1\IARSYS~1\EMBEDD~1.2EV\8051\lib\clib\
-f "lnk51ew.xcl"
-FINTEL-EXTENDED
graf_r.R51
indic.R51
obr_klav.R51
pribor.R51
proverka.R51
sint_nch.R51
svitok.R51
upr_pkan.R51
ZNGENM10.R51
gui.R51
AT24C32.R51
ExchangePC.R51
C:\PROGRA~1\IARSYS~1\EMBEDD~1.2EV\8051\lib\clib\cl-pli-nlpd-1e.r51
-o KALIBR.hex


В итоге программа получается след. размеров:
55 565 bytes of CODE memory
70 bytes of DATA memory( + 11 absolute )
10 262 bytes of XDATA
149 bytes of IDATA
8 bits of BIT memory
Go to the top of the page
 
+Quote Post
bialix
сообщение Feb 8 2005, 13:52
Сообщение #2


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

Группа: Свой
Сообщений: 174
Регистрация: 4-11-04
Из: zp.ua
Пользователь №: 1 046



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

объем программы растет потому что добавляются функции? если да - то проверяйте стек


--------------------
Имей мужество пользоваться своим собственным разумом! (с) И.Кант
Go to the top of the page
 
+Quote Post
Shedon
сообщение Feb 8 2005, 13:57
Сообщение #3


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

Группа: Свой
Сообщений: 110
Регистрация: 30-11-04
Из: Nizhny Novgorod
Пользователь №: 1 262



Цитата(bialix @ Feb 8 2005, 17:52)
я бы сказал, что у вас глючит или компилятор или переполняется стек

объем программы растет потому что добавляются функции? если да - то проверяйте стек
*

Да программа растёт из-за функций
Go to the top of the page
 
+Quote Post
bialix
сообщение Feb 8 2005, 14:05
Сообщение #4


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

Группа: Свой
Сообщений: 174
Регистрация: 4-11-04
Из: zp.ua
Пользователь №: 1 046



Вы писали:
Больше всех глючат функции обращения к контроллеру дисплея, обработка прерывания от таймера и функции си типа sprintf, vsprintf

Тогда это ОЧЕНЬ похоже на переполнение стека
тем более что функции sprintf, vsprintf очень прожорливы по отношению к стеку.

Начинайте анализировать дерево вызовов функций по листингу линкера, профилировать потребление стека своим отладчиком. Начинайте отключать какие-то функции. Затем вы дойдете до переписывания sprintf, vsprintf своими реализациями.


--------------------
Имей мужество пользоваться своим собственным разумом! (с) И.Кант
Go to the top of the page
 
+Quote Post
bialix
сообщение Feb 8 2005, 14:07
Сообщение #5


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

Группа: Свой
Сообщений: 174
Регистрация: 4-11-04
Из: zp.ua
Пользователь №: 1 046



и просто мои 5 копеек: для 51х лучше юзать кейла. Мое сугубое личное мнение.


--------------------
Имей мужество пользоваться своим собственным разумом! (с) И.Кант
Go to the top of the page
 
+Quote Post
Shedon
сообщение Feb 9 2005, 05:23
Сообщение #6


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

Группа: Свой
Сообщений: 110
Регистрация: 30-11-04
Из: Nizhny Novgorod
Пользователь №: 1 262



Может просто размер стека увеличить ???

-------------------------------------------
PS
Открыл окно "Распределение памяти"", во вкладке CODE есть две странные строчки:
Код
Адрес                Размер              Имя                                           Значение
------------------------------------------------------------                  ---------------
//...
//...
C:FFFF                [1]                   _XDATA_END                                      [typless]
C:10000             [16711679]       _FAR__DATA_START, _CODE_BANK     *Address out of range*
C:FFFFFF            [4278255617]    _FAR_DATA_END, _CODE_END, _FAR_CODE_END                                                                                *Address out of range*
C:FFFF                                        ***End of adress space ***


Что такое находится по адресам C:10000 и C:FFFFFF
Go to the top of the page
 
+Quote Post
bialix
сообщение Feb 9 2005, 08:40
Сообщение #7


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

Группа: Свой
Сообщений: 174
Регистрация: 4-11-04
Из: zp.ua
Пользователь №: 1 046



не знаю, я с яром для 51х не работал


--------------------
Имей мужество пользоваться своим собственным разумом! (с) И.Кант
Go to the top of the page
 
+Quote Post
Shedon
сообщение Feb 9 2005, 08:50
Сообщение #8


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

Группа: Свой
Сообщений: 110
Регистрация: 30-11-04
Из: Nizhny Novgorod
Пользователь №: 1 262



Цитата(bialix @ Feb 9 2005, 12:40)
не знаю, я с яром для 51х не работал
*

Да, похоже точно переполнение стека, сейчас просто перезапускается в опаределённый момент, первый раз с этим столкнулся, пока не вижу другого способа кромек как увеличить размер стека...
Go to the top of the page
 
+Quote Post
-Tумблер-
сообщение Feb 9 2005, 11:58
Сообщение #9


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

Группа: Свой
Сообщений: 146
Регистрация: 4-11-04
Из: Московская область
Пользователь №: 1 040



Цитата(Shedon @ Feb 8 2005, 15:54)
Есть сабжевый контроллер, есть прога на си, код хранится во внешней флэш, на 64кб, ....
.....
глюки
.....


Заочно трудно сказать - что там может быть. Возможно существует
и не одна причина. Можно посоветовать типа - "а что бы я сделал".

У 51-х есть известная проблема - "проблема ALE".
Решается вставкой резистора 430-560 ом в разрыв цепи ALE
процессор-регистр. Это я сделал бы автоматически, на уровне
инстинкта. Вне зависимости , улучшит это ситуацию или нет.

Далее, хочестя понять:
1. какова глубина вложения в стек - и хватит ли его.
Например, при старте программы прописать весь стек 0xFF.
А после некоторой работы вывести дамп стека на дисплей.
Сразу станет понятно, сколько заняли.

2. правильно ли читаются коды команд из внешней флэш -
нужно вставить проверку CRC16 вообще и пустить этот тест
циклически в частности. Для выяснения проблем этого эпизода. smile.gif

3. Тщательнее изучить диаграммы вывода на дисплей.
Может что-то "на грани". Заменить дисплей - может не повезло
с конкретным экземпляром.
Еще я бы нагрузил шину данных вывода (P0 если я не ошибаюсь)
резисторами 4K7 на питание. excl.gif

4. Временный откат назад - к простой и маленькой программе
которая работает исправно. Постепенное наращивание кода
до тех пор, пока не станет "плохо".
Или ловить "плохо" как льва в Африке. smile.gif


--------------------

- ЗАМЕНЯТЬ ДЕТАЛИ НА ХОДУ ВОСПРЕЩАЕТСЯ !!! -
Go to the top of the page
 
+Quote Post
Miron
сообщение Feb 11 2005, 11:24
Сообщение #10


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

Группа: Validating
Сообщений: 149
Регистрация: 11-02-05
Из: Рязань
Пользователь №: 2 574



Согласен с высказываниями насчет стека.
Советую еще обратить внимание на построение прерываний
Если прерывания выполняются в разных банках и в них вызываются
функции скомпилированные под другой регистровый банк а СИ как
правило компилит все под 0 банк то возникают ошибки похожие на то,
что вы описываете.
Отловить такое лучше всего просматривая трассировку программы после
точки останова на ошибке.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Feb 12 2005, 12:49
Сообщение #11


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Позволю и себе высказаться.
Что касается стека, то поведение МК в этом случае очень симптоматично и причина, скорее всего, кроется именно в этом. Особенно когда я увидел ссылки в сообщениях на функции sprintf.
Но. Контроль стека предварительным заполнением его какой нибудь детерминированной величиной не на все 100% может дать нужный результат. Дело в том, что когда компилятор выделяет некое пространство в стеке под временные переменные, он просто меняет значение указателя стека (которое может указывать за пределы сегмента стека), но не обязательно что-то пишет в выделенное пространство. Поэтому в работе может сложиться впечатление, что стека ещё достаточно, но программа, тем не менее, падает, т. к. локальные переменные могут быть уже вне сегмента стека и затирают какие-нибудь глобальные переменные или случается прерывание, которое изменяя глобальные переменные на самом деле изменяет свой адрес возврата.
Поэтому, как ещё одна мера предосторожности, нужно расположить под стеком наименее ответственный сегмент данных, например сегмент со стрингами. Глюки в этом случае будет легче выявить и они не будут приводить к падению программы.
Go to the top of the page
 
+Quote Post
-Tумблер-
сообщение Feb 14 2005, 12:27
Сообщение #12


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

Группа: Свой
Сообщений: 146
Регистрация: 4-11-04
Из: Московская область
Пользователь №: 1 040



Цитата(IgorKossak @ Feb 12 2005, 15:49)
но не обязательно что-то пишет в выделенное пространство. Поэтому в работе может сложиться впечатление, что стека ещё достаточно, но программа, тем не менее, падает, т. к. локальные переменные могут быть уже вне сегмента стека

*



excl.gif Сушествует, конечно и второй метод (но я его считаю первым!!).
Это - определение экстремального значения указателя стека.
Очевидно, для x51 это тривиальный поиск максимума. (щас найдем):

#define SP_RESEARCH

#ifdef SP_RESEARCH
idata byte sp_pointer;
#endif

void main (void)
{
#ifdef SP_RESEARCH
/* search from this value */
sp_pointer = SP;
#endif

.
.
.

}

В какой-нибудь самой "глубокой" процедуре прерывания
(в таймерной например):
interrupt void T0_int (void)
{
TH0=wdTh;
TL0+=wdTl;
...
#ifdef SP_RESEARCH
/* max search !*/
if (sp_pointer < SP) sp_pointer=SP;
#endif
...
}

Далее по какому - нибудь событию (нажатие кнопки, таймер, "всегда")
выведем sp_pointer в COM-порт. Довольно быстро обнаружим
максимум. конечно, можно предложить вариант, когда это
не сработает - договоримся не делать таких проектов "И ФСЕ".

Замечу, что поскольку речь шла об IAR, это надо
сделать для ОБОИХ стеков. excl.gif
IAR любит использовать 2 стека. И оба желательно контролировать. excl.gif

Сочетание обоих методов позволяет решить проблему. blush.gif

Очевидно, это уже из серии дискуссии "кто и как тестирует.."
Совершенно очевидно, если бы автор программы контролировал
этот важнейший параметр по мере изготовления продукции,
те действовал "по шагам" ничего подобного бы не случилось.
А теперь нет гарантий, что этот проект вообще можно довести
до качественного результата.
smile.gif


--------------------

- ЗАМЕНЯТЬ ДЕТАЛИ НА ХОДУ ВОСПРЕЩАЕТСЯ !!! -
Go to the top of the page
 
+Quote Post
-Tумблер-
сообщение Feb 14 2005, 16:51
Сообщение #13


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

Группа: Свой
Сообщений: 146
Регистрация: 4-11-04
Из: Московская область
Пользователь №: 1 040



Цитата(IgorKossak @ Feb 12 2005, 15:49)
..не на все 100% может дать нужный результат. ..
*


Хорошенько подумав, пришел к выводу, что все-таки
"так не может быть". Действительно, в случае создания
автоматических переменных в стеке сначала произойдет коррекция
SP. Если в этот момент произойдет прерывание, у стека
будет занято еще некоторое пространство. Которое, очевидно,
будет использовано раньше (чем пространство локальных переменных).
И что же ? После окончания прерывания, локальные переменные
будут использованы, и память в стеке также будет изменена.
Никаких "проплешин" использования стека не будет.
В этом случае поменяется лишь порядок искажения стекового
пространства. Однако, если после вывода дампа стека в ком-порт
мы обнаружим не искаженную область стекового "ковра памяти",
это одназначно будет указывать на отсутствие переполнения.
А вот если не искаженной области не будет совсем,
однозначного вывода сделать нельзя.
Но даже если и в "этом разе" переполнения нет, работать
так не рекомендуется.. любая последующая коррекция проекта может привести к самым разным результатам..
smile.gif


--------------------

- ЗАМЕНЯТЬ ДЕТАЛИ НА ХОДУ ВОСПРЕЩАЕТСЯ !!! -
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 05:47
Рейтинг@Mail.ru


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