Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Keil c51 и sprintf
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > MCS51
crabs
Добрый день. Столкнулся со следующей проблемой. Есть приложение, написанное для камня Si1000 в Keil. Всё отлажено и работает без нареканий. Помимо самого приложения мне понадобился бутлодер. Был написан бутлодер, приложение было сдвинуто в памяти на 2800H байт, вместе с векторами прерываний, и тд. В бутлодере, что находится в памяти начиная с нулевого адреса стоят LJMP'ы на все прерывания, которые размещены в основной программе.
После всех манипуляций программа стала зацикливаться. Как выснилось, программу вешает вызов функции sprintf() из стандартной библиотеки. Далее, по map- файлу я узнал, что зацикливается функция putchar, и в отладчике нашел место где всё останавливается. Выглядит это так:
CODE
C:0x9629 3099FD JNB TI0(0x98.1),C:9629
C:0x962C C299 CLR TI0(0x98.1)
C:0x962E F599 MOV SBUF0(0x99),A


Висяк в первой строке. То есть sprintf пытается отправить данные через последовательный порт. В программе функции вида *printf, где вызывается putchar не используются.

Менял виды оптимизации - безрезультатно. Если приложение размещается по нулевому адресу - всё ок. Как такое может быть? cranky.gif

редактор
Если виснет именно в этой строчке - значит не может дождаться сигнала от uart о завершении передачи.
Иногда необходимо принудительно записать байт в уарт, чтоб вызвать установку флага о завершении передачи.
Как вариант, при переносе кода что-то соптимизировали, или в бутлоадере есть обработчик событий от уарт, который работает по прерыванию, и соответственно обрабатывает (сбрасывает) этот флаг.
crabs
Цитата(редактор @ Mar 20 2012, 18:42) *
Если виснет именно в этой строчке - значит не может дождаться сигнала от uart о завершении передачи.

Это то понятно, что не сбрасывается или не устанавливается бит TI0. Но я же вызываю sprintf, а не printf. Мне нужно вывести в буфер, а не в порт
crabs
Сделал как указано здес http://www.keil.com/support/docs/2669.htm. Оставил вместо putchar пустые заглушки, которые никуда ничего не выводят. sprintf не зацикливается но и не работает, что логично. Я в замешательстве wacko.gif
barabek
Цитата(crabs @ Mar 21 2012, 17:47) *
Сделал как указано здес http://www.keil.com/support/docs/2669.htm. Оставил вместо putchar пустые заглушки, которые никуда ничего не выводят. sprintf не зацикливается но и не работает, что логично. Я в замешательстве wacko.gif

Извините, что немного не в тему. А зачем Вы сдвигали основную прогу в вверх, а бутлоадер оставили внизу? При этом, как я понял, в бутлоадере Вы не используете прерывания. Смысл в этом, если при изменении проги адреса обработчиков прерываний будут плыть? Проще в начале делать ljmp на бутлоадер, а затем из него на начало основной проги.

Кстати, может в этом и проблема, что Вы каким -то образом поставили не те адреса в вектора и прогу кидает туда, куда попадать она не должна? Это я так, пальцем в небо sm.gif
редактор
Цитата
Это я так, пальцем в небо

Кстати о птичках, при переносе проекта в верхнюю область, в настройках базу для векторов прерывания сместили???.
BootLoader точно не через UART0 работает и без прерываниям??
BootLoader собран как отдельный проект или как часть существующего???
Возможно возникает косяк с переходами. Так как длинна команд у проца разная, то при сбоях (неверном адресе перехода) весь правильный код может исполняться совсем по другому.


crabs
Цитата(редактор @ Mar 21 2012, 17:44) *
Кстати о птичках, при переносе проекта в верхнюю область, в настройках базу для векторов прерывания сместили???.
BootLoader точно не через UART0 работает и без прерываниям??
BootLoader собран как отдельный проект или как часть существующего???
Возможно возникает косяк с переходами. Так как длинна команд у проца разная, то при сбоях (неверном адресе перехода) весь правильный код может исполняться совсем по другому.

Базу сместил, бутлодер как отдельный проект. Я выкидывал бутлодер и просто по нулевому адресу ставил переход на начало проги(на прерывания ставил ljmp, как и в бутлодере) - поведение такое же. Бутлодер работает без прерываний

2 barabek: При изменеии проги обработчики останутся на месте, поскольку по их адресам находятся лишь переходы на подпрограммы обработки прерываний. То есть мы сместили таблицу векторов на определенное количество байт и всегда можем по смещению добраться до интерсующего прерывания

В общем попробую бутлодер сунуть в конец адресного пространства
редактор
Еще вариант. В проекте, работающем с 0-го адреса, в дизассемблере посмотреть какие команды сидят по данному смещению.
C:(0x9629 - 0x2800). Точка глюка минус смещение проекта.
Более вероятным выглядит вариант с неправильным переходом.


Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.