|
|
  |
Странное поведение Linker'a в Keil |
|
|
|
Mar 18 2011, 14:33
|
Группа: Участник
Сообщений: 14
Регистрация: 1-11-10
Из: Беларусь, Минск
Пользователь №: 60 563

|
Здравствуйте, столкнулся со следующей проблемой: компиляция проекта проходит успешно, но про запуске на выполнение (отладка по С2) вместо того чтобы остановиться на main() и ждать дальнейших указаний программа прыгает неизвестно куда и зацикливается. Т.е. СРАЗУ после нажатия на кнопку Start debug session. При этом, если запустит симулятор, все работает как и должно. Т.е. после нажатия на кнопку Start debug session указатель выполняемой инструкции замирает на первой команде в main().
Плата на C8051F361, не сигналовская макетка. Плата проверена, т.к. программа, которая только инициализирует LCD (зажигает подстветку, выводит стартовое меню и т.д.) работала без проблем. Только при добавлении последующих функций возникают проблемы.
Есть подозрение, что проблема в файле STARTUP, который добавляет сам Keil. С ним не сталкивался, есть ли смысл лезть туда, если да то как? Суда по дизассемблеру, зацикливание происходит именно там.
Еще один вариан -- неверное распределение памяти. В настройках проекта выбран тип Memory model: Large, Code ROM size: LARGE,64KB code.
Спасибо.
|
|
|
|
|
Mar 21 2011, 07:50
|
Группа: Участник
Сообщений: 14
Регистрация: 1-11-10
Из: Беларусь, Минск
Пользователь №: 60 563

|
В регистре сброса RSTSRC -- сброс по WDT. Он по умолчанию включен. Выключается в инициализации. Куда, в свою очередь, программа не попадает  . Вообщем при помощи бубна и с Вашей помощью сделали следующее: влезли в STARTUP, там отключили цикл обнуления регистров памяти (не помогло) и убили последнюю команду "LJMP ?C_START". По идее, она как раз-то и должна вызывать main(). Вот только вызывает она хз что и зачем (программа падает в бесчисленные циклы и потом ресетится по WDT). Если у кого-то есть мысли по этому поводу, отпишитесь. Спасибо.
Сообщение отредактировал DO_SL - Mar 21 2011, 07:51
|
|
|
|
|
Mar 21 2011, 08:49
|
Частый гость
 
Группа: Свой
Сообщений: 96
Регистрация: 10-06-05
Из: Новосибирск
Пользователь №: 5 890

|
Цитата(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-а при разбиении проекта на несколько файлов, могут быть из-за неопределенности в отображении смешанного кода (листинг + ассемблер). В этом случае можно отслеживать ход выполнения команд по дизасемблеру. Хотя это не наглядно, а для большинства "программистО" незнакомых с ассемблером, просто катастрофа. Тогда можно, "наступив на горло правильной песне"  , свалить все в один сишный файл. Но я думаю, что лучше все же выучить ассемблер, чем потом поддерживать "километровый" код.
|
|
|
|
|
Mar 21 2011, 09:28
|
Группа: Участник
Сообщений: 14
Регистрация: 1-11-10
Из: Беларусь, Минск
Пользователь №: 60 563

|
Сброс по 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. Спасибо за помощь.
|
|
|
|
|
Mar 21 2011, 09:56
|
Частый гость
 
Группа: Свой
Сообщений: 96
Регистрация: 10-06-05
Из: Новосибирск
Пользователь №: 5 890

|
Цитата(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() начинает выполняться. Если Вас в программе нет ни одного обработчика прерываний, то так и должно быть.
|
|
|
|
|
Mar 21 2011, 10:00
|
Группа: Участник
Сообщений: 14
Регистрация: 1-11-10
Из: Беларусь, Минск
Пользователь №: 60 563

|
Отключил WDT сразу в STARTUP. Все остальное вернул к оригинальному виду. Работает. Еще раз спасибо.
|
|
|
|
|
Jun 30 2011, 05:09
|
Местный
  
Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512

|
У меня модуль 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 Комментрование строчки с отключением ватчдога не помогает! Как с этим бороться? Помогите разобраться плиззз!
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|