Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Странное поведение Linker'a в Keil
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > MCS51
DO_SL
Здравствуйте, столкнулся со следующей проблемой:
компиляция проекта проходит успешно, но про запуске на выполнение (отладка по С2) вместо того чтобы остановиться на main() и ждать дальнейших указаний программа прыгает неизвестно куда и зацикливается. Т.е. СРАЗУ после нажатия на кнопку Start debug session. При этом, если запустит симулятор, все работает как и должно. Т.е. после нажатия на кнопку Start debug session указатель выполняемой инструкции замирает на первой команде в main().

Плата на C8051F361, не сигналовская макетка. Плата проверена, т.к. программа, которая только инициализирует LCD (зажигает подстветку, выводит стартовое меню и т.д.) работала без проблем. Только при добавлении последующих функций возникают проблемы.

Есть подозрение, что проблема в файле STARTUP, который добавляет сам Keil. С ним не сталкивался, есть ли смысл лезть туда, если да то как? Суда по дизассемблеру, зацикливание происходит именно там.

Еще один вариан -- неверное распределение памяти. В настройках проекта выбран тип Memory model: Large, Code ROM size: LARGE,64KB code.

Спасибо.
barabek
А что в регистре сброса RSTSRC в это время?
DO_SL
В регистре сброса RSTSRC -- сброс по WDT. Он по умолчанию включен. Выключается в инициализации. Куда, в свою очередь, программа не попадает sm.gif . Вообщем при помощи бубна и с Вашей помощью сделали следующее: влезли в STARTUP, там отключили цикл обнуления регистров памяти (не помогло) и убили последнюю команду "LJMP ?C_START". По идее, она как раз-то и должна вызывать main(). Вот только вызывает она хз что и зачем (программа падает в бесчисленные циклы и потом ресетится по WDT). Если у кого-то есть мысли по этому поводу, отпишитесь.
Спасибо.
O.L.
Цитата(DO_SL @ Mar 21 2011, 13:50) *
. Если у кого-то есть мысли по этому поводу, отпишитесь.
Спасибо.

Какое количество глобальных переменных, структур, буферов, инициализированных констант и строк в Вашей программе? Учитывая то, что RAM памяти у контроллера f36x много, были случаи, когда при выполнении инициализации всего этого "добра", до выполнения команд секции main успевал срабатывать WDT.
В этом случае, самое безопасное найти в коде файла STARTUP.A51 (лучше если он скопирован в директорию проекта) метку STARTUP1 и после нее вставить вот такую строчку.
Код
STARTUP1:
    IF IDATALEN <> 0
   ; Stop WDT
   ANL     0xD9,#0xBF        ; WDTE = 0 (clear watchdog timer // enable)

Если WDT нужен в основной программе, то в секции main перед началом инициализации периферии его включаем.

Прыжки "не ведомо куда" в отладчике Keil-а при разбиении проекта на несколько файлов, могут быть из-за неопределенности в отображении смешанного кода (листинг + ассемблер). В этом случае можно отслеживать ход выполнения команд по дизасемблеру. Хотя это не наглядно, а для большинства "программистО" незнакомых с ассемблером, просто катастрофа. Тогда можно, "наступив на горло правильной песне" sm.gif, свалить все в один сишный файл. Но я думаю, что лучше все же выучить ассемблер, чем потом поддерживать "километровый" код.
DO_SL
Сброс по WDT наступает уже после инициализации регистров. Такой вот вариант не заработал.
CODE
STARTUP1:

;IF IDATALEN <> 0
; MOV R0,#IDATALEN - 1
; CLR A
;IDATALOOP: MOV @R0,A
; DJNZ R0,IDATALOOP
;ENDIF


А работать начало после удаления последней строки в STARTUP.A51
CODE
;LJMP ?C_START

Вот это-то меня и удивило. При этом main() начинает выполняться.

P.S. Чуть позже попробую Ваш вариант с отключением WDT сразу в STARTUP.a51. Спасибо за помощь.
O.L.
Цитата(DO_SL @ Mar 21 2011, 15:28) *
Сброс по WDT наступает уже после инициализации регистров. Такой вот вариант не заработал.
Код
STARTUP1:
;IF IDATALEN <> 0
;                MOV     R0,#IDATALEN - 1
;                CLR     A
;IDATALOOP:      MOV     @R0,A
;                DJNZ    R0,IDATALOOP
;ENDIF

Без исходного кода трудно определить причину, но скорее всего из-за не инициализированных переменных подпрограммы выполняют что то не то.

Цитата(DO_SL @ Mar 21 2011, 15:28) *
А работать начало после удаления последней строки в STARTUP.A51
Код
;LJMP    ?C_START

Вот это-то меня и удивило. При этом main() начинает выполняться.

Если Вас в программе нет ни одного обработчика прерываний, то так и должно быть.
DO_SL
Отключил WDT сразу в STARTUP. Все остальное вернул к оригинальному виду. Работает. Еще раз спасибо.
Halfback
У меня модуль RFM50 (от HopeRF), там чип Si4432
У тоже походу проблемы с запуском.
В файле startup.a51 добавил в метку STARTUP1 отключение ватчдога. Но всё равно не помогает.
Код
STARTUP1:

IF IDATALEN <> 0

           ANL     0xD9,#0xBF       ; WDTE = 0 (clear watchdog timer // enable)
                MOV     R0,#IDATALEN - 1
                CLR     A


В трассировшике смотрел, зацикливается на метке IDATALOOP
Код
IDATALOOP:      MOV     @R0,A
                DJNZ    R0,IDATALOOP

Комментрование строчки с отключением ватчдога не помогает!
Как с этим бороться? Помогите разобраться плиззз!
Палыч
Цитата(Halfback @ Jun 30 2011, 09:09) *
У меня модуль RFM50 (от HopeRF), там чип Si4432...В файле startup.a51 добавил в метку STARTUP1 отключение ватчдога.
А, что? В Вашем МК управление WDT осуществляется так же, как и в C8051F361 ? Поскольку WDT отсутствовал в "классике", то его регистры и управление им в разных МК51 могут быть реализованы по-разному.
Harbinger
Да RFM50 и SI1000 - вроде одно и то же. Соответственно, с WDT аналогичная ситуация.
В даташите на SI1000 есть загадочная фраза насчёт того, что WDT, мол, если не отключить, сработает вскоре после старта программы, без уточнения, когда конкретно - он что, даже положенного цикла не отработает? В F990 честно срабатывал через 30 с чем-то мс после аппаратного сброса - не такое уж и маленькое время для стартапа.
Halfback
Был в запаре. WDT отключил как писали выше.
Команду ;LJMP ?C_START комментировать не стал - в тело main() входит.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.