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

Странное поведение Linker'a в Keil

Здравствуйте, столкнулся со следующей проблемой:

компиляция проекта проходит успешно, но про запуске на выполнение (отладка по С2) вместо того чтобы остановиться на main() и ждать дальнейших указаний программа прыгает неизвестно куда и зацикливается. Т.е. СРАЗУ после нажатия на кнопку Start debug session. При этом, если запустит симулятор, все работает как и должно. Т.е. после нажатия на кнопку Start debug session указатель выполняемой инструкции замирает на первой команде в main().

 

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

 

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

 

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

 

Спасибо.

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


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

В регистре сброса RSTSRC -- сброс по WDT. Он по умолчанию включен. Выключается в инициализации. Куда, в свою очередь, программа не попадает :) . Вообщем при помощи бубна и с Вашей помощью сделали следующее: влезли в STARTUP, там отключили цикл обнуления регистров памяти (не помогло) и убили последнюю команду "LJMP ?C_START". По идее, она как раз-то и должна вызывать main(). Вот только вызывает она хз что и зачем (программа падает в бесчисленные циклы и потом ресетится по WDT). Если у кого-то есть мысли по этому поводу, отпишитесь.

Спасибо.

Изменено пользователем DO_SL

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


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

. Если у кого-то есть мысли по этому поводу, отпишитесь.

Спасибо.

Какое количество глобальных переменных, структур, буферов, инициализированных констант и строк в Вашей программе? Учитывая то, что 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-а при разбиении проекта на несколько файлов, могут быть из-за неопределенности в отображении смешанного кода (листинг + ассемблер). В этом случае можно отслеживать ход выполнения команд по дизасемблеру. Хотя это не наглядно, а для большинства "программистО" незнакомых с ассемблером, просто катастрофа. Тогда можно, "наступив на горло правильной песне" :), свалить все в один сишный файл. Но я думаю, что лучше все же выучить ассемблер, чем потом поддерживать "километровый" код.

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


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

Сброс по WDT наступает уже после инициализации регистров. Такой вот вариант не заработал.

STARTUP1:

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

 

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

;LJMP    ?C_START

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

 

P.S. Чуть позже попробую Ваш вариант с отключением WDT сразу в STARTUP.a51. Спасибо за помощь.

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


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

Сброс по WDT наступает уже после инициализации регистров. Такой вот вариант не заработал.

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

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

 

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

;LJMP    ?C_START

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

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

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


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

Отключил WDT сразу в STARTUP. Все остальное вернул к оригинальному виду. Работает. Еще раз спасибо.

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


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

У меня модуль 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

Комментрование строчки с отключением ватчдога не помогает!

Как с этим бороться? Помогите разобраться плиззз!

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


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

У меня модуль RFM50 (от HopeRF), там чип Si4432...В файле startup.a51 добавил в метку STARTUP1 отключение ватчдога.
А, что? В Вашем МК управление WDT осуществляется так же, как и в C8051F361 ? Поскольку WDT отсутствовал в "классике", то его регистры и управление им в разных МК51 могут быть реализованы по-разному.

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


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

Да RFM50 и SI1000 - вроде одно и то же. Соответственно, с WDT аналогичная ситуация.

В даташите на SI1000 есть загадочная фраза насчёт того, что WDT, мол, если не отключить, сработает вскоре после старта программы, без уточнения, когда конкретно - он что, даже положенного цикла не отработает? В F990 честно срабатывал через 30 с чем-то мс после аппаратного сброса - не такое уж и маленькое время для стартапа.

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


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

Был в запаре. WDT отключил как писали выше.

Команду ;LJMP ?C_START комментировать не стал - в тело main() входит.

Изменено пользователем Halfback

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


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

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

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

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

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

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

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

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

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

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