Help - глюки с float в Keil?

Hi! Нужна бы срочная помощь - может кто сталкивался или подскажет что и где проверить:

Вообще-то, есть float деления и умножения как в ISR, так и в фоновых процедурах (AT89S53). Глюки какие-то странные, даже не могу однозначно определить. Начинает лезть мусор на LCD, сбоят символы, программа ыообще куда-то улетает. И все сильно зависит от случая - то может работать долго и устойчиво, то совершенно безобидное редактирование текста вообще вводит программу в режим постоянно перезапуска. Похоже, что это связано с float - убираю расчеты (везде не могу) - становится лучше, но не совсем. Может, компилятор что-то c RAM не то делает? DATA у меня полная моими переменными, IDATA - также, но для стека место вроде есть.

Program Size: data=204.5 xdata=0 code=10120 TYPE BASE LENGTH RELOCATION SEGMENT NAME -----------------------------------------------------

  • * * * * * * D A T A M E M O R Y * * * * * * * REG 0000H 0008H ABSOLUTE "REG BANK 0" DATA 0008H 0011H UNIT _DATA_GROUP_ IDATA 0019H 0006H UNIT _IDATA_GROUP_ BL51 BANKED LINKER/LOCATER V5.01 001FH 0001H *** GAP *** DATA 0020H 0002H BIT_ADDR ?BA?HYGROMETER BIT 0022H.0 0000H.5 UNIT ?BI?HYGROMETER 0022H.5 0000H.3 *** GAP *** DATA 0023H 003FH UNIT ?DT?HYGROMETER IDATA 0062H 006BH UNIT ?ID?HYGROMETER IDATA 00CDH 0001H UNIT ?STACK

Стека вроде должно хватать (как точно узнать?), все умножения/деления reentrant. Но даже окружение фоновых расчетов запретами прерываний не помогает. И в LCD (24х2) уже все перерыл и скопом пересмотрел, непонято что глючит (работаю по анализу готовности) - то символы проглотит, то изменит, то такие коды получит, что совсем экран очистит навеки.

Куда копать и что проверить?

Reply to
Yuri Kopylov
Loading thread data ...

"Leonid Egorov" snipped-for-privacy@p12.f.n5030.z2.fidonet.org>

сообщил/сообщила в новостях

получения

Работаю по готовности, и паузы ставил. Но, похоже, дело не в LCD, а где-то в программе. Перенес часть DATA в IDATA (на 'C'), поредактировал текст, методом тыка добился "стабильной" работы (пока глюков не вижу). Но стабильность эта условная. Добавляю в текст одну команду установки бита, например, (даже не переменную в RAM!), и все перестает работать - микро все время перезапускается. Конкретно эту ситуацию в симуляторе не ловил, но, думаю, так ничего не найти - безуспешно пытался искать предыдущие аналогичные. Почти уверен, что просто перестановка местами определений переменных DATA приведет к такой же катастрофе. Но как это ловить? Как для KEIL можно получить (и где смотреть) детальную карту RAM overlay и что-нибудь вида: такой-то адрес используется для переменный с такими-то именами, а также для такой-то библиотечной функции? Карта памяти (м51-файл) в этом смысле неудобна, но придется ее лопатить. Если нет другого более цивилизованного способа искать такие глюки. Компилятор-линкер не выдают ни одного warning.

Вот такие дела. Может кто знает, как сказать Keil-у, что я хочу, например, для данной переменной в RAM или массива применить NOOVERLAY ? Чтобы исключить подобные подозрения на линкер - я ведь все равно заранее знаю, что данный массив есть serial buffer, например, используется в прерываниях и никогда ни с кем делиться не должен. А что делает линкер - пока не знаю.

WBR Юрий Копылов snipped-for-privacy@mtu-net.ru

Reply to
Yuri Kopylov

Yuri Kopylov и Leonid Egorov в прошлый раз беседовали в воскресенье, 13-го июля, в 00:09

Как твои дела, Yuri ?

[ skip ] YK> Работаю по готовности, и паузы ставил. Hо, похоже, дело не в LCD, YK> а где-то в программе. YK> Перенес часть DATA в IDATA (на 'C'), поредактировал текст, методом YK> тыка добился "стабильной" работы (пока глюков не вижу). Hо YK> стабильность эта условная. Добавляю в текст одну команду установки YK> бита, например, (даже не переменную в RAM!), и все перестает YK> работать - микро все время перезапускается. Это касается включенной оптимизации? Глюки повтоpяются даже с полностью выключенной оптимизацией? Пpобовали компилить с pазными веpсиями Keil? Hедавно, пpавда для С166, одна и та же пpогpамма в Keil 4.23 пеpиодически подвисала, в Keil 4.27 пpи той же оптимизации часами pаботало на уpа.

YK> Вот такие дела. YK> Может кто знает, как сказать Keil-у, что я хочу, например, для данной YK> переменной в RAM или массива применить NOOVERLAY ? volatile подойдет?

Hу бывай! Пиши, Yuri, незабывай!

Reply to
Leonid Egorov

"Ilja Vlaskin" snipped-for-privacy@f105.n.z2.fidonet.org>

сообщил/сообщила в новостях следующее:

reentant-stack

веpхнюю

Собственных процедур нет, только библиотечные float-операции (если им что-то нужно, например, reentrant-stack).

Спасибо за совет. Но если моя программа сильно глючит при некоторой компиляции, то на уровне ощущений она не успевает выполнить ничего и постоянно перезапускается. Хотя бывают линкования, когда все вроде работает. (Но надолго ли и до какого очередного внешнего события?) Попробую. И посмотрю memory map.

WBR Юрий snipped-for-privacy@mtu-net.ru

Reply to
Yuri Kopylov

Greetings, Yuri!

Посмотрел я мессагу, посланную Yuri Kopylov к All, и решил ответить:

[skip]

YK> IDATA 00CDH 0001H UNIT ?STACK YK> Стека вроде должно хватать (как точно узнать?), все YK> умножения/деления reentrant.

А я не был бы в этом так увеpен. Ты забыл что у тебя есть еще и reentant-stack (ведь у тебя как я понял есть reentrant-пpоцедуpы?), а он занимает веpхнюю часть памяти и pастет вниз навстpечу аппаpатному стеку.

YK> Куда копать и что проверить?

Самый действенный способ пpовеpить, хватает ли стеку такой:

  1. Пеpед началом pаботы обнулить область памяти данных.
  2. Чеpез некотоpое вpемя по какой-либо команде или событию пpовеpить область данных где pасположен стек на наличие области, заполненной нулями. Эта область и будет являться pезеpвом стека. Можно делать такую пpовеpку пеpиодически по какому-либо пpеpыванию и pезультат выдавать напpимеp чеpез UART.

C наилучшими пожеланиями Ilja aka ИЛ-2 (ilja_vlaskin$mail.ru)

... В Греческом зале, в Греческом зале...

Reply to
Ilja Vlaskin

Sun Jul 13 2003 10:25, Yuri Kopylov wrote to Ilja Vlaskin:

YK> Спасибо за совет. Hо если моя программа сильно глючит при некоторой YK> компиляции, то на уровне ощущений она не успевает выполнить ничего и YK> постоянно перезапускается. Хотя бывают линкования, когда все вроде YK> работает. (Hо надолго ли и до какого очередного внешнего события?) YK> Попробую. И посмотрю memory map.

YK> WBR Юрий snipped-for-privacy@mtu-net.ru

А может все таки глючит напр. питание, или помехи лезут ? Много с кейлом работал, ничего подобного не встречал.

Tadas

Reply to
Tadas

"Tadas" snipped-for-privacy@takas.lt сообщил/сообщила в новостях следующее:

Да не похоже - уж висел scope на reset, ничего не ловит. И вся ситуация одинакова - все, скажем, работает. Много минут. Изменяю код, прошиваю - тут же начинаются постоянные перезапуски, программа даже не успевает проинициализировать LCD и что-либо выдать. Меняю на старый HEX - все опять работает.

Сейчас лопачу memory-map и перевожу в табличку Excel чтобы понять, что происходит. Дополнительный признак того, что что-то с памятью (и никакая диагностика не ловит) - когда-то (когда программа была меньше или было не так жарко), микро отвечал нормальное эхо в WinTerminal при записи в него системной информации. Теперь все может проходить также нормально, но последние <CR><LF> эха иногда пропадают. И строки ответа лезут друг на друга. Подозреваю, что кто-то лезет в мой буфер вывода (стек?).

Найду ошибку - скажу, что бывает.

WBR Юрий snipped-for-privacy@mtu-net.ru

Reply to
Yuri Kopylov

"Leonid Egorov" snipped-for-privacy@p12.f.n5030.z2.fidonet.org>

сообщил/сообщила в новостях следующее:

установки

полностью

Keil?

пеpиодически

уpа.

Keil C51 - 7.01, BL51 - 5.01. В предыдущих версиях не пробовал. Оптимизацию понижал до уровня2, кажется (где еще остается DATA overlay - иначе ничего в память не влезет и не скомпилируется). Положительного эффекта не дает. По поводу перезапусков микро еть кое-какое обсуждение в конференции на сайте Keil. Но не мой случай, к сожалению. Копаю memory map. Это работа не для слабонервных и на день как минимум при программе в 12К.

WBR Юрий

Reply to
Yuri Kopylov

YK> Может кто знает, как сказать Keil-у, что я хочу, например, для данной YK> переменной в RAM или массива применить NOOVERLAY ?

LE> volatile подойдет?

volatile это совсем другое. Я бы объявил ее просто как static, это бы автоматически ислючило ее перекрытие.

Reply to
Andy Mozzhevilov

Greetings, Yuri!

Посмотрел я мессагу, посланную Yuri Kopylov к Ilja Vlaskin, и решил ответить:

Так у тебя в конце концов ЕСТЬ или HЕТ reentrant-пpоцедуpы???

[skip]

YK> Hо, судя по начальному выполняемому коду startup, никакой YK> инициализации reentrant-стека не происходит:

Пpавильно, потому что в startup.a51 имеется такой кусок:

=== Пилить Windows Clipboard отсель === IF IBPSTACK <> 0 EXTRN DATA (?C_IBP)

MOV ?C_IBP,#LOW IBPSTACKTOP ENDIF === Пилить Windows Clipboard досель ===

Кейловские библиотеки скомпилиpованы по умолчанию с IPBSTACK = 0 Поэтому, чтобы инициализиpовать reentrant-stack из стаpтапа надо подключить имеющийся startup.a51 к пpоекту (он заменит пpи этом библиотечный модуль) и подпpавить в нем значение IPBSTACK. Так что если у тебя все-таки есть reentrant-пpоцедуpы, то глюки запpосто могут быть из-за того что у тебя не инициализиpован reentrant-stack.

YK> - после JMP с 0-адреса идет только цикл обнуления RAM YK> [0x00....0x7F] YK> - устанавливается hrdw-stack 0x81 YK> - уход на main.

Hу, не на main, а на пpоцедуpу начальной инициализации статических пеpеменных, а уж оттуда - на main.

C наилучшими пожеланиями Ilja aka ИЛ-2 (ilja_vlaskin$mail.ru)

... В Греческом зале, в Греческом зале...

Reply to
Ilja Vlaskin

"Andy Mozzhevilov" snipped-for-privacy@svrw.ru сообщил/сообщила в новостях следующее:

Закончил частичный анализ memory map. Некоторые замечания, которые могут быть полезными:

- причины глюков не вижу пока

- линкер не перекрывает переменные, если они global. Т.е. для каждой global есть своя область памяти (в моем случае, по-крайней мере), и этого, видимо, достаточно, чтобы Global-var была NOOVERLAY.

- для простых float-операций (*/+-) не используется reentrant-stack

- несмотря на то, что hrdw-stack размещается в IRAM, совсем не очевидно, что максимальное перемещение переменных в DRAM и максимальное (казалось бы) неиспользование напрямую IRAM обеспечивает максимальную длину стека. Все зависит от конкретной ситуации, и для обеспечения максимального размера стека нужен кропотливый анализ memory map и много итераций - проб размещения переменных.

- что бы я пока не делал (в разумных пределах, созраняя видимую работоспособность программы), линкер оставляет дырку в RAM [0x16...0x1F]. Пока не пойму зачем.

WBR Юрий snipped-for-privacy@mtu-net.ru

Reply to
Yuri Kopylov

"Ilja Vlaskin" snipped-for-privacy@f105.n.z2.fidonet.org>

сообщил/сообщила в новостях следующее:

  1. Моих собственных теперь (давно уже) нет.
  2. Явно определенных как reentrant моих никогда не было.
  3. Раньше (были Keil warning) были процедуры, вызываемые как из main, так и из ISR. Я игнорировал warnings, будучи 100% уверенным, что эти процедуры никогда не могут быть вызваны из разных мест или прерваны и даже в main окружал их EA=0/1 на всякий случай. Были похожие глюки, связанные с непонятным поведением программы, но бывало, что все и работало (программа тогда была меньше).
  4. Теперь (говорим об этом) есть float-умножения/деления/сложения/вычитания как в main, так и в ISR. Не знаю, называется ли это наличием 'reentrant'-процедур или нет. С другой стороны, док на Keil называет _nop() как reentrant тоже, но очевидно, что для NOP никакого доп стека не нужно.

подключить

модуль) и

запpосто могут

Я что, для float-операций должен вручную подключать доп стек и это не делается автоматически?

пеpеменных,

У меня нет инициализации. Кстати, считаю это вредным. Иначе что делать при WDT-перезапуске? Вообще-то, хотелось бы просто восстановить последовательность выполнения команд, а не чистить память и инициализировать ее поновой. Это для меня будет (но будет! - в HT-PIC я с этим боролся и даже мы обсуждали в конфе давно, но так решения и не было) один из последних вопросов, когда проект закончится и нужно будет включить WDT - как убрать вышеуказанную очистку RAM [0x00-0x7F] (кроме как вручную в HEX-файле).

С уважением, Юрий Копылов. snipped-for-privacy@mtu-net.ru

Reply to
Yuri Kopylov

Tue Jul 15 2003 21:07, Yuri Kopylov wrote to Ilja Vlaskin:

YK> ......... один из YK> последних вопросов, когда проект закончится и нужно будет включить YK> WDT - как убрать вышеуказанную очистку RAM [0x00-0x7F] (кроме как YK> вручную в HEX-файле).

YK> С уважением, Юрий Копылов. snipped-for-privacy@mtu-net.ru

Из стартапа убрать, в чем же сложность ?

Tadas

Reply to
Tadas

YK> - линкер не перекрывает переменные, если они global. Т.е. для каждой YK> global есть своя область памяти

Это очевидно, по другому и быть не может.

YK> - для простых float-операций (*/+-) не используется reentrant-stack YK> - несмотря на то, что hrdw-stack размещается в IRAM, совсем не YK> очевидно, что максимальное перемещение переменных в DRAM и YK> максимальное (казалось бы) неиспользование напрямую IRAM обеспечивает YK> максимальную длину стека.

Как то ты путанно сказал. idata - она ведь 256 байт, в том числе первая часть перекрывает 128 байт data, а вторые 128 байт могут адресоваться только как idata. Стек обычно кладется наверх. Так что перетаскивание в data ничего не даст. А если у тебя модель small, то в data и так по умолчанию все переменные попадают.

YK> Все зависит от конкретной ситуации, и для YK> обеспечения максимального размера стека нужен кропотливый анализ YK> memory map и много итераций - проб размещения переменных. YK> - что бы я пока не делал (в разумных пределах, созраняя видимую YK> работоспособность программы), линкер оставляет дырку в RAM YK> [0x16...0x1F]. Пока не пойму зачем.

Он не может туда засунуть сегмент, потому что видимо все они больше по размеру, чем эта дырка. А сверху этой дырки торчит область битовых переменных. Можно использовать эту область двумя способами:

  1. Объявить в ней некоторые глобальные переменные явно, то есть указать адрес при помощи _at_ unsigned char data my_var _at_ 0x1F;

  1. Указать линкеру (формат опции навскидку не вспомню), что область битовых переменных размещается не по умолчанию, с адреса 0х20, а выше на столько, чтобы какой либо сегмент стал влазить в эту дырку.

И версия Keil какая?

Reply to
Andy Mozzhevilov

"Tadas" snipped-for-privacy@takas.lt сообщил/сообщила в новостях следующее:

Надеюсь, что не будет. Я просто имел ввиду опыт решения подобной задачи в HT-PIC (давно), когда имела место и проблема экономии ROM. Там обнуление уходило при выполнении, но линкер все равно вставлял НИКОГДА не используемый код процедуры обнуления (видимо, обсуждение осталось в архивах). Я тогда заменял startup своим явно написанным куском как часть C-программы.

С уважением, Юрий Копылов. snipped-for-privacy@mtu-net.ru

Reply to
Yuri Kopylov

"Sergey Davydov" snipped-for-privacy@f1210.n.z2.fidonet.org>

сообщил/сообщила в новостях

WDT-пеpезапуске?

поновой.

не должен

некоppектного

пpовеpил и

будет заново

ты его

Нет, вопрос чисто идеологический - я сам лучше знаю, какие переменные RAM могут врать, а какие нет. Исходя из алгоритма задачи. И я сам (своим кодом) хотел бы проверить валидность RAM. Например, не хотелось бы при WDT-RESET обнулять длинные цифровые фильтры и PID, чтобы они опять долго входили в режим и т.д. Я бы просто проверил критические переменные в RAM на свои лимиты, а не начинал с обнуленных величин. Разве не логично?

WBR Юрий Копылов snipped-for-privacy@mtu-net.ru

Reply to
Yuri Kopylov
15-Jul-03 17:07 Yuri Kopylov wrote to Andy Mozzhevilov:

YK> - что бы я пока не делал (в разумных пределах, созраняя видимую YK> работоспособность программы), линкер оставляет дырку в RAM YK> [0x16...0x1F]. Пока не пойму зачем. Не зачем, а почему. Видать все имеющиеся куски (единицы линковки), которые у него есть -- большепо размеру. Все переменные, объявленные в файле filename.c вне каких-либо функций (это могут быть как "глобальные", видимые из других файлов, так и статические переменные) ещё компилятором объединяются в сегмент с именем вида ?DT?filename для data и ?ID?filename для idata-переменных. Линкер эти куски может только двигать и менять местами между собой, но уже не рвёт. Все оверлейные переменные, всё дерево, укладываются соответственно в _DATA_GROUP_ и _IDATA_GROUP_.

KEIL C не имеет такой вещи, как #pragma psect data=имя если бы это было, то можно было бы сделать

// foo.c #pragma psect data=?DT?foo_part1 int foo1,foo2; #pragma psect data=?DT?foo_part2 int foo3,foo4;

При этом вместо секции ?DT?foo на 8 байт со всеми 4 переменными создалось бы две секции по 4 байта и линкер заполнил бы ими дырочки. Поскольку этого нет, то единственное, что можно предолжить -- это создать несколько файлов, в которых объявить по одной-две глобальных переменных, тогда будет несколько мелких секций, которые линкер начнёт тасовать и закроет дырочки.

У меня всегда есть ассемблерные куски (обработчики прерываний и очень близкие к железу вещи). я обычно там директивами ассемблера создаю несколько секций, что-то типа DT_ASMISR SEGMENT DATA ; split into regions for better fit DT_ASMISR_2 SEGMENT DATA DT_ASMISR_3 SEGMENT DATA

RSEG DT_ASMISR public tim40ms,tout40ms,tout_key,tout1S isrphase: ds 1 systick: ds 1 tim40ms: ds 1 ; 40ms increment tout40ms: ds 1 ; 40ms downcount tout1S: ds 1 ; 1S downcount

RSEG DT_ASMISR_2 public dispMask1,dispMask0 dispMask0: ds 1 ; DIG[7..0] blink mask dispMask1: ds 1 ; OUT[1..0],BEEP state; BARS,x,x,DIG[9..8] blink mask dispIndex: ds 1 ; current position, pointer inside dispSegBuf

и т.д.

wbr,

Reply to
Oleksandr Redchuk

Hi Sergey! You wrote to Yuri Kopylov on Thu, 17 Jul 2003 00:30:44 +0600:

[...]

SD> В общем-то точно я стандаpты Си не помню, но вpоде бы неинициализиpованные SD> пеpеменные обнуляться не должны.

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

Hеинициализированные автоматические (локальные) переменные не инициализируются компилятором (там будет лежать "мусор").

Bye.

### Девушка не воробей, залетит - мало не покажется!

Reply to
Harry Zhurov

Greetings, Yuri!

Посмотрел я мессагу, посланную Yuri Kopylov к Ilja Vlaskin, и решил ответить:

Если есть пpоцедуpы, вызываемые из ISR, и у этих пpоцедуp есть локальные пеpеменные, то насколько я помню пpи постpоении деpева пpоцедуp их влияние на дpугие пpоцедуpы не учитывается, поэтому ее локальные пеpеменные могут запpосто испоpтить локальные пеpеменные дpугих выполняющихся в данный момент пpоцедуp. (Так-ли это - можешь увидеть по деpеву пpоцедуp) Решение пpоблемы:

  1. Скоppектиpовать деpево подпpогpамм (см. соотв. диpективы линкеpа)
  2. Объявлять пеpеменные как static. Этот метод не годиться, если в пpоцедуpу пеpедаются какие-либо паpаметpы.

C наилучшими пожеланиями Ilja aka ИЛ-2 (ilja_vlaskin$mail.ru)

... В Греческом зале, в Греческом зале...

Reply to
Ilja Vlaskin

"Ilja Vlaskin" snipped-for-privacy@f105.n.z2.fidonet.org>

сообщил/сообщила в новостях следующее:

локальные

влияние на

могут запpосто

пpоцедуp.

Есть такая буква в слове. Линкер использовал для локальных переменных адреса [2...6] (Bank0 ???) как для локальных переменных процедур, вызываемых из ISR, так и из main. Поскольку портящиеся процедуры main были типа 'перевод float в строку, выдача char на LCD' и подобные, у меня возникало странное ощущение, что глюки связаны с float и c LCD. Хотя сначала я грешил на стек, думая что компилятор с линкером достаточно умны, чтобы не допускать OVERLAY используемых в ISR локальных переменных. Проверить в железе сейчас не могу - прибор пока временно у заказчика.

пpоцедуpу

Не очень понимаю, как можно скорректировать дерево процедур или как сказать линкеру, чтобы он делал overlay не с этими, а с другими переменными. Для меня очевиднее вынести локальные переменные процедур, вызываемых из ISR (и только оттуда!) в global-блок - в любом случае их никто и никогда кроме этих процедур использовать не должен. И передавать параметры также через global. Все остальное должно получиться автоматически (имеется ввиду overlay процедер из main с уже другими адресами). Есть еще, конечно, вариант - все эти overlay-процедуры выполнять при запрещенных прерываниях, но это криво. Хотя можно сэкономить RAM.

С уважением, Юрий Копылов snipped-for-privacy@mtu-net.ru

Reply to
Yuri Kopylov

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.