реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Настройка BL51 Linker.
DO_SL
сообщение Feb 7 2013, 07:49
Сообщение #1





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



Здравствуйте.

Контроллер С8051F022, внешная RAM (xdata), по UART подключен термопринтер (по сути обычный терминал, только вывод на бумагу). Среда разработки KEIL 4.02, BL51.exe v6.22.

В проекте после инициализации и перед основным функционалом вызывается функция теста внешней RAM памяти. Сама функция работает, на выходе получаем номер закороченного или не присоединенного вывода. Теперь надо его вывести на термопринтер. Используется для этого printf(). Дальше, уж извините за большое количество букв, опишу все по порядку.

1) В проекте только тест железа, переменные по умолчанию в data (Small memory model в настройках проекта). Все работает. Используется ТОЛЬКО внешняя xdata, встроенная в МК не задействована.

2) Проект растет, small memory model уже мало, ставлю large(variables in xdata). До этого критичные для работы переменные в функции теста внешней RAM принудительно располагаются в data. На выходе функции теста внешней RAM получаю верный ответ, а вот принтер печатает кракозябры. Предполагаемая причина -- внутренние переменные printf() располагаются в битой памяти (внешняя микросхема RAM (xdata)). Переключил режим на совместное использование встроенной в МК xdata (адреса с 0х0000 до 0х0FFF) и внешней микросхемы RAM xdata (адреса с 0х1000 и выше). После этого все заработало.

3) Проект растет не по дням а по часам, внешняя RAM поставлена не для солидности. Объявляется большой массив в xdata. Печать опять кракозябрами.

file.m51

TYPE BASE LENGTH RELOCATION SEGMENT NAME
--------------------------------------------------------------------
XDATA 8053H 0030H UNIT ?XD?PRINTF?PRINTF
XDATA 81FFH 0001H UNIT ?XD?_PUTCHAR?PUTCHAR

А теперь собственно вопрос: как указать линкеру область памяти, в которой он может размещать переменные указанных выше функций? Нашел в хелпе следующее:

BL51 Putchar.obj & RAMSIZE(128) & CODE(0x0000-0xFFFF) & XDATA(0x0000-0x0FFF) пример

Ввел эту строку в linker_control_file.lin, ругается на ошибку. Убрал BL51 -- не помогло.

Вообщем вот. Надеюсь на вашу помощь.
Go to the top of the page
 
+Quote Post
DO_SL
сообщение Feb 8 2013, 09:09
Сообщение #2





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



Сделал сам. Может кому пригодиться ответ.

Как задать область памяти для целого модуля, я не нашел. Зато смог задать размещение переменных конкретной функции.
Для моего случая в файл настроек линковщика filename.lin добавил следующую строку:

XDATA(?XD?PRINTF?PRINTF(0h), ?XD?_PUTCHAR?PUTCHAR(30h),?XD?_CALCBADRAMPIN?TEST_DIAGNOSTICS(31h),
?XD?_STRCAT?STRCAT(68h))

Можно сделать это же в настройках проекта, вкладка BL51 Locate. В строку XDATA нужно ввести названия сегментов (берутся из filename.m51).

Т.е. для моего случая строка будет выглядеть так:
?XD?PRINTF?PRINTF(0h), ?XD?_PUTCHAR?PUTCHAR(30h),?XD?_CALCBADRAMPIN?TEST_DIAGNOSTICS(31h),
?XD?_STRCAT?STRCAT(68h).

Соответственно, по аналогии можно задавать адреса и других сегментов.

Недостатком такого решения является невозможность (т.е. у меня не получилось) задания допустимого диапазона памяти. Из-за этого приходиться жестко задавать адреса. В случае увеличения объема переменных (актуально для самописных функций) появятся предупреждения о перекрытии адресного пространства.

P.S. Заработало!!! disco.gif
Go to the top of the page
 
+Quote Post
редактор
сообщение Feb 8 2013, 10:34
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



С внешней памятью из под Keil не работал, хватало встроенной.
Но в глаза бросается на вкладке Target 3 поля для ввода адреса Off Chip Xdata Memory (Keil 4.23) с указанием размера каждого сегмента.
А описанный вами вариант пользую только для размещения сегментов (в основном кода) по фиксированным адресам.
Еще наверное "вкладка BL51 Locate" снять галку использования по умолчанию и добавить в XDATA Range еще кусок используемого пространства (через запятую).


--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
DO_SL
сообщение Feb 8 2013, 13:21
Сообщение #4





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



Не силен в теории компиляторов-линковщиков, так что все нижесказанное сугобо ИМХО, если не прав, поправьте пожалуйста.
Цитата
Но в глаза бросается на вкладке Target 3 поля для ввода адреса Off Chip Xdata Memory (Keil 4.23) с указанием размера каждого сегмента.

Насколько я понимаю, это только указывает допустимый объем памяти для всего проекта. Работа с внешней xdata по коду на Си ничем не отличается от внутренней. Контроллеру во время инициализации нужно указать, с какой именно памятью работать: только внутренней, только внешней или внешняя+ внутренняя (это все про xdata разумеется). Линковщик про это не знает, он просто размещают переменные в допустимом диапазоне адресов. Мне же как раз и было нужно изменить допустимый диапазон адресов в xdata для конкретных функций, а не для всего проекта целиком. Где это сделать, я так и не нашел (задание именно диапазона, а не конкретного адреса).
Цитата
Еще наверное "вкладка BL51 Locate" снять галку использования по умолчанию и добавить в XDATA Range еще кусок используемого пространства (через запятую).

Пространство адресов xdata нужно было именно уменьшить, а не увеличить. Т.е. внутренняя xdata работает по адресам 0х0000 -- 0х0FFF, внешняя с 0x1000 до 0xFFFF. Тест внешней xdata представляет из себя запись значения по адресу в xdata, чтение значения по этому адресу и сравнение с исходным. Управление микросхемой RAM берет на себя железный модуль в МК.

Линковщик при сборке проекта размещал внутренние переменные printf() по адресам старше 0x1000, то есть во внешней микросхеме. Поэтому printf() отрабатывала не корректно (для теста я специально вешал КЗ на соседние выводы внешней микросхемы). Для правильной работы было необходимо, чтобы все переменные, используемые в ходе теста и вывода результатов, размещались в МК (то есть физически в самой микросхеме контроллера).

Эмммм. Может я Вас не так понял, если что, поправьте.
Go to the top of the page
 
+Quote Post
редактор
сообщение Feb 11 2013, 07:39
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 356
Регистрация: 9-06-07
Пользователь №: 28 315



Скорее всего не понял вопрос я. Думал надо просто добавить память в проект без привязки конкретных блоков к месту.

Привязать размещение к месту можно либо указав линкеру адрес (как вы уже сделали), либо непосредственно в си-файле директивой _at_
Но это пивязать конкретный блок(массив) к конкретному адресу.

PS:
В справке Keil для опций линкера "XDATA Linker Directive" по указано

Цитата
XDATA (<[>range<]> <[>segment <[>(address)<]> <[>, ...<]><]>)

Видно что диапазон задается первым параметром, но чем это поможет в данной ситуации не представляю.
И скорее всего это можно вписать в опции только при создании собственного файла с правилами линковки.
Да в примерах этой страницы справки везде стоит директива CODE() (Paste & Copy Methode наверное)
Удачи





--------------------
Хорошую систему делают из стандартных блоков нестандартно мыслящие инженеры.
Go to the top of the page
 
+Quote Post
AndreyS
сообщение Feb 11 2013, 13:43
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 235
Регистрация: 28-01-05
Из: Санкт-Петербург
Пользователь №: 2 276



Цитата(DO_SL @ Feb 8 2013, 17:21) *
вырезал


Добрый день.
BL51 не настраивал, он не позволяет работать с банками свободно.
Работаю с LX51
Вот настройки для мое проги под бутзагрузчик
идем в настройки проекта LX51 locate
Там есть поле USER segment в нем можно задать конструкции по размещению в фиксированной области памяти (или в диапазоне адресов) ваших сегментов.
Вот мой пример
?BANK?SELECT(C:0x7100),?BANK?SWITCH(C:0x7110),?CO?FORBOOTDATA (C:0x70F0)
Тут зафиксированы три процедуры.
?BANK?SELECT
?BANK?SWITCH
?CO?FORBOOTDATA
префиксы указывают на модуль (читайте описание на кейл ?CO? область кода). ?BANK? из асмового стартапа.
Для переменных тут будет муторно все прописывать
Можно просто переопределить классы в поле User class (для этого надо снять галочку Use Memory Layout from Target Dialog). Пропишите что у вас диапазон внешней памяти меньше чем может быть.
Я например прописал себе класс для данных модуля обработчиков прерывания CODE_INTR (C:0x7000-C:0x7FFF)
и вставил в модуль переопределение #pragma userclass (CODE = INTR)
таким образом у меня после линковки модуль обработчикв прерываний лег в коде по фиксированному диапазону кода.

С данными все тоже самое. Определите себе диапазон и пропишите его в линковщке. А все что работает с внешними ОЗУ данными положите в один модуль.
Вот примерно так
В модуле ставим #pragma userclass (xdata = MyClass)
В настройках линкера XDATA_MYCLASS (X:0x0000-C:0x0050)

PS
Пример вы нашли правильный.
Вы в настройках линкера уберите галочку использовать данные из диалога и в классе измените только строку XDATA(0x0000-0x0FFF)


--------------------
Удачи.
Go to the top of the page
 
+Quote Post
DO_SL
сообщение Feb 12 2013, 08:20
Сообщение #7





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



Спасибо за помощь. Проверю приведенные выше способы позже, сейчас со временем совсем жестко.
Еще раз спасибо всем.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 17:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.01398 секунд с 7
ELECTRONIX ©2004-2016