Автор |
Сообщение |
|
|
Заголовок сообщения: |
Re: Как разработать кросс-компилятор Форта для микроконтролл |
|
|
Спасибо за ответы, буду рыть дальше
Спасибо за ответы, буду рыть дальше :)
|
|
|
|
Добавлено: Пт дек 02, 2011 02:04 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как разработать кросс-компилятор Форта для микроконтролл |
|
|
oco писал(а): Ага, понятно! Но есть замечание, например в микроконтроллерах AVR два адресных пространства ПЗУ и ОЗУ с одинаковыми адресами, и чтение реализуется разными командами. Поэтому для нужны два слова "@" для чтения ОЗУ и "RO@" для чтения ПЗУ. Да, все так. oco писал(а): Еще вопрос: а если я не хочу словарные статьи вообще в ПЗУ создавать? Тогда как? (то есть заголовки, я хотел сказать) Можно имена и адреса держать в памяти хост-машины, а в ПЗУ писать только код. Это часто делается при кросс-компиляции. Если от целевого МК не требуется в процессе работы самостоятельно интерпретировать передаваемые строки на Форте (для чего он должен иметь возможность найти в своей памяти, какому имени что соответствует), то имена в МК класть вобщем-то и не надо.
[quote="oco"]Ага, понятно! Но есть замечание, например в микроконтроллерах AVR два адресных пространства ПЗУ и ОЗУ с одинаковыми адресами, и чтение реализуется разными командами. Поэтому для нужны два слова "@" для чтения ОЗУ и "RO@" для чтения ПЗУ.[/quote] Да, все так. [quote="oco"]Еще вопрос: а если я не хочу словарные статьи вообще в ПЗУ создавать? Тогда как? (то есть заголовки, я хотел сказать)[/quote] Можно имена и адреса держать в памяти хост-машины, а в ПЗУ писать только код. Это часто делается при кросс-компиляции. Если от целевого МК не требуется в процессе работы самостоятельно интерпретировать передаваемые строки на Форте (для чего он должен иметь возможность найти в своей памяти, какому имени что соответствует), то имена в МК класть вобщем-то и не надо.
|
|
|
|
Добавлено: Пт дек 02, 2011 01:52 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как разработать кросс-компилятор Форта для микроконтролл |
|
|
Ага, понятно! Но есть замечание, например в микроконтроллерах AVR два адресных пространства ПЗУ и ОЗУ с одинаковыми адресами, и чтение реализуется разными командами. Поэтому для нужны два слова "@" для чтения ОЗУ и "RO@" для чтения ПЗУ.
Еще вопрос: а если я не хочу словарные статьи вообще в ПЗУ создавать? Тогда как? (то есть заголовки, я хотел сказать)
Ага, понятно! Но есть замечание, например в микроконтроллерах AVR два адресных пространства ПЗУ и ОЗУ с одинаковыми адресами, и чтение реализуется разными командами. Поэтому для нужны два слова "@" для чтения ОЗУ и "RO@" для чтения ПЗУ.
Еще вопрос: а если я не хочу словарные статьи вообще в ПЗУ создавать? Тогда как? (то есть заголовки, я хотел сказать)
|
|
|
|
Добавлено: Пт дек 02, 2011 01:45 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как разработать кросс-компилятор Форта для микроконтролл |
|
|
Тогда получается, что надо для CREATE делать вариант RCREATE. При этом DOES> остается как есть, потому что оно на стек ничего не кладет, а просто дописывает в код переход на вот этот хвост, который после него. Вместо RO@ можно тоже @, если ПЗУ в общем адресном пространстве.
Предположим, что ПЗУ с данными находится в диапазоне 0x1000-0x1FFF, а ОЗУ - 0x7000-0x7FFF. Допустим также, что мы и туда, и туда чуть-чуть понаписали, и DP указывает на 0x7010, а RODP - на 0x1020. Тогда получается так:
: CONSTANT RCREATE RO, DOES> @ ; 5 CONSTANT FIVE
Слово CONSTANT создаст заголовок слова FIVE, и припишет ему код "push 0x1020". Далее RO, запишет 5 по адресу 0x1020 и передвинет указатель. Если мы теперь выполним FIVE, на стеке будет 0x1020. Вся работа по выбору между ПЗУ и ОЗУ уже сделана, можно пользоваться @.
Тогда получается, что надо для CREATE делать вариант RCREATE. При этом DOES> остается как есть, потому что оно на стек ничего не кладет, а просто дописывает в код переход на вот этот хвост, который после него. Вместо RO@ можно тоже @, если ПЗУ в общем адресном пространстве.
Предположим, что ПЗУ с данными находится в диапазоне 0x1000-0x1FFF, а ОЗУ - 0x7000-0x7FFF. Допустим также, что мы и туда, и туда чуть-чуть понаписали, и DP указывает на 0x7010, а RODP - на 0x1020. Тогда получается так:
: CONSTANT RCREATE RO, DOES> @ ; 5 CONSTANT FIVE
Слово CONSTANT создаст заголовок слова FIVE, и припишет ему код "push 0x1020". Далее RO, запишет 5 по адресу 0x1020 и передвинет указатель. Если мы теперь выполним FIVE, на стеке будет 0x1020. Вся работа по выбору между ПЗУ и ОЗУ уже сделана, можно пользоваться @.
|
|
|
|
Добавлено: Пт дек 02, 2011 01:36 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как разработать кросс-компилятор Форта для микроконтролл |
|
|
Хищник писал(а): Если я правильно понимаю, в данном случае речь идет о системе с как минимум двумя областями памяти данных - в ПЗУ и ОЗУ Да, я это имел в виду Цитата: Что касается CREATE, оно всегда делает одно и то же - создает слово и добавляет ему код вида
push <here> ret
где <here> - первый свободный адрес на момент создания слова. Это означает, что такой адрес уже не изменится, поэтому само слово можно смело определять для ПЗУ. Вот дальше интереснее. Формально, даже gcc может перераспределять данные по разным областям. Для констант используется память read-only, что позволяет, в частности, использовать для их хранения ПЗУ, а компилятор будет следить, чтобы программист не пытался изменить значение константы далее по тексту программы. Можно поступить и так, завести для этого отдельный указатель. К примеру, если DP - переменная, хранящая указатель на свободное место в памяти данных (ОЗУ), то RODP - указатель на свободное место в Read-Only памяти. Соответственно, ROHERE положит этот адрес на стек, ROALLOT выделит память, а RO, скомпилирует число. Это подход в целом в стиле Форта.
Альтернатива - не трогать существующие механизмы работы памяти. Для этого мы создаем в ПЗУ образ будущей памяти данных, а при старте форт-системы в микроконтроллере первым делом переносим весь этот массив в ОЗУ. Я так понимаю, что должно быть примерно так: : CONSTANT CREATE RO, DOES> RO@ ; : VARIABLE CREATE 0 , DOES> ; RO@ выбирает значение из ПЗУ Обычная запятая будет ложить значение в область данных ПЗУ, которая при запуске будет копироваться в ОЗУ. Но DOES> должен давать в этих случаях разные адреса. В первом случае - в ПЗУ, второй в ОЗУ. Заводить разные DOES> ?
[quote="Хищник"]Если я правильно понимаю, в данном случае речь идет о системе с как минимум двумя областями памяти данных - в ПЗУ и ОЗУ[/quote] Да, я это имел в виду [quote]Что касается CREATE, оно всегда делает одно и то же - создает слово и добавляет ему код вида
push <here> ret
где <here> - первый свободный адрес [b]на момент создания слова[/b]. Это означает, что такой адрес уже не изменится, поэтому само слово можно смело определять для ПЗУ. Вот дальше интереснее. Формально, даже gcc может перераспределять данные по разным областям. Для констант используется память read-only, что позволяет, в частности, использовать для их хранения ПЗУ, а компилятор будет следить, чтобы программист не пытался изменить значение константы далее по тексту программы. Можно поступить и так, завести для этого отдельный указатель. К примеру, если DP - переменная, хранящая указатель на свободное место в памяти данных (ОЗУ), то RODP - указатель на свободное место в Read-Only памяти. Соответственно, ROHERE положит этот адрес на стек, ROALLOT выделит память, а RO, скомпилирует число. Это подход в целом в стиле Форта.
Альтернатива - не трогать существующие механизмы работы памяти. Для этого мы создаем в ПЗУ образ будущей памяти данных, а при старте форт-системы в микроконтроллере первым делом переносим весь этот массив в ОЗУ.[/quote] Я так понимаю, что должно быть примерно так: : CONSTANT CREATE RO, DOES> RO@ ; : VARIABLE CREATE 0 , DOES> ; RO@ выбирает значение из ПЗУ Обычная запятая будет ложить значение в область данных ПЗУ, которая при запуске будет копироваться в ОЗУ. Но DOES> должен давать в этих случаях разные адреса. В первом случае - в ПЗУ, второй в ОЗУ. Заводить разные DOES> ?
|
|
|
|
Добавлено: Пт дек 02, 2011 01:14 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как разработать кросс-компилятор Форта для микроконтролл |
|
|
Если я правильно понимаю, в данном случае речь идет о системе с как минимум двумя областями памяти данных - в ПЗУ и ОЗУ. Что касается CREATE, оно всегда делает одно и то же - создает слово и добавляет ему код вида
push <here> ret
где <here> - первый свободный адрес на момент создания слова. Это означает, что такой адрес уже не изменится, поэтому само слово можно смело определять для ПЗУ. Вот дальше интереснее. Формально, даже gcc может перераспределять данные по разным областям. Для констант используется память read-only, что позволяет, в частности, использовать для их хранения ПЗУ, а компилятор будет следить, чтобы программист не пытался изменить значение константы далее по тексту программы. Можно поступить и так, завести для этого отдельный указатель. К примеру, если DP - переменная, хранящая указатель на свободное место в памяти данных (ОЗУ), то RODP - указатель на свободное место в Read-Only памяти. Соответственно, ROHERE положит этот адрес на стек, ROALLOT выделит память, а RO, скомпилирует число. Это подход в целом в стиле Форта.
Альтернатива - не трогать существующие механизмы работы памяти. Для этого мы создаем в ПЗУ образ будущей памяти данных, а при старте форт-системы в микроконтроллере первым делом переносим весь этот массив в ОЗУ.
Если я правильно понимаю, в данном случае речь идет о системе с как минимум двумя областями памяти данных - в ПЗУ и ОЗУ. Что касается CREATE, оно всегда делает одно и то же - создает слово и добавляет ему код вида
push <here> ret
где <here> - первый свободный адрес [b]на момент создания слова[/b]. Это означает, что такой адрес уже не изменится, поэтому само слово можно смело определять для ПЗУ. Вот дальше интереснее. Формально, даже gcc может перераспределять данные по разным областям. Для констант используется память read-only, что позволяет, в частности, использовать для их хранения ПЗУ, а компилятор будет следить, чтобы программист не пытался изменить значение константы далее по тексту программы. Можно поступить и так, завести для этого отдельный указатель. К примеру, если DP - переменная, хранящая указатель на свободное место в памяти данных (ОЗУ), то RODP - указатель на свободное место в Read-Only памяти. Соответственно, ROHERE положит этот адрес на стек, ROALLOT выделит память, а RO, скомпилирует число. Это подход в целом в стиле Форта.
Альтернатива - не трогать существующие механизмы работы памяти. Для этого мы создаем в ПЗУ образ будущей памяти данных, а при старте форт-системы в микроконтроллере первым делом переносим весь этот массив в ОЗУ.
|
|
|
|
Добавлено: Чт дек 01, 2011 22:56 |
|
|
|
|
|
Заголовок сообщения: |
Re: Как разработать кросс-компилятор Форта для микроконтролл |
|
|
Уважаемый Хищник! Хотелось бы уяснить несколько вопросов, касающихся гарвардской архитектуры. Как реализовать определяющие слова, в частности CREATE и DOES> ? Возьмем например классические определения константы и переменной: Код: : CONSTANT CREATE , DOES> @ ; : VARIABLE CREATE 0 , DOES> ; Хочется, чтобы значение константы находилось в ПЗУ, а переменной в ОЗУ, соответственно слово "запятая" в каждом случае должно быть разным? И DOES> в константе ложит на стек адрес в ПЗУ, а в переменной - в ОЗУ, опять они должны быть разными? Потом, при прошивке ОЗУ ведь не прошивается, поэтому программа при старте должна данные для переменных из ПЗУ перекинуть в ОЗУ. То есть, начальные значения переменных таки сначала ложим в отдельную область ПЗУ, которую копируем в ОЗУ? Как это сделать, что-то я совсем запутался...
Уважаемый Хищник! Хотелось бы уяснить несколько вопросов, касающихся гарвардской архитектуры. Как реализовать определяющие слова, в частности CREATE и DOES> ? Возьмем например классические определения константы и переменной: [code]: CONSTANT CREATE , DOES> @ ; : VARIABLE CREATE 0 , DOES> ;[/code] Хочется, чтобы значение константы находилось в ПЗУ, а переменной в ОЗУ, соответственно слово "запятая" в каждом случае должно быть разным? И DOES> в константе ложит на стек адрес в ПЗУ, а в переменной - в ОЗУ, опять они должны быть разными? Потом, при прошивке ОЗУ ведь не прошивается, поэтому программа при старте должна данные для переменных из ПЗУ перекинуть в ОЗУ. То есть, начальные значения переменных таки сначала ложим в отдельную область ПЗУ, которую копируем в ОЗУ? Как это сделать, что-то я совсем запутался...
|
|
|
|
Добавлено: Чт дек 01, 2011 18:32 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
chess писал(а): Тут я не согласен, так как макросы для инструментальной системы могут быть макросами для целевой, а макросы для целевой системы могут и не быть макросами для инструментальной. В моем варианте макросы для целевой системы являются обычными словами инструментальной системы, определенными через двоеточие и никак не годятся на роль макросов для инструментальной системы. Я не про назначение макросов, а про механизм их создания - это обычные слова Форта. chess писал(а): Насчет DISPATCH-NUMBER - аналогичное переключение осуществляют сами слова целевой системы, только каждое слово локально - принципиальной разницы нет, есть только отсутствие глобальной переменной-вектора .
Принципиальная разница как раз есть. Слово целевой системы забирает весь стек, а это некорректно. Надо как-то регулировать. Можно, кстати, запоминать DEPTH на момент переключения к целевой компиляции, это уже будет гораздо лучше.
[quote="chess"]Тут я не согласен, так как макросы для инструментальной системы могут быть макросами для целевой, а макросы для целевой системы могут и не быть макросами для инструментальной. В моем варианте макросы для целевой системы являются обычными словами инструментальной системы, определенными через двоеточие и никак не годятся на роль макросов для инструментальной системы. [/quote] Я не про назначение макросов, а про механизм их создания - это обычные слова Форта. [quote="chess"]Насчет DISPATCH-NUMBER - аналогичное переключение осуществляют сами слова целевой системы, только каждое слово локально - принципиальной разницы нет, есть только отсутствие глобальной переменной-вектора .[/quote]
Принципиальная разница как раз есть. Слово целевой системы забирает весь стек, а это некорректно. Надо как-то регулировать. Можно, кстати, запоминать DEPTH на момент переключения к целевой компиляции, это уже будет гораздо лучше.
|
|
|
|
Добавлено: Пт сен 11, 2009 09:25 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Хищник писал(а): Макросы тут ни при чем, поскольку это обычные слова, которые можно использовать как для инструментальной, так и для целевой компиляции.
Тут я не согласен, так как макросы для инструментальной системы могут быть макросами для целевой, а макросы
для целевой системы могут и не быть макросами для инструментальной. В моем варианте макросы для целевой системы являются обычными словами инструментальной системы, определенными через двоеточие и никак не годятся на роль макросов для инструментальной системы. Насчет DISPATCH-NUMBER - аналогичное переключение
осуществляют сами слова целевой системы, только каждое слово локально - принципиальной разницы нет, есть только отсутствие глобальной переменной-вектора .
[quote="Хищник"]Макросы тут ни при чем, поскольку это обычные слова, которые можно использовать как для инструментальной, так и для целевой компиляции.[/quote]
Тут я не согласен, так как макросы для инструментальной системы могут быть макросами для целевой, а макросы
для целевой системы могут и не быть макросами для инструментальной. В моем варианте макросы для целевой системы являются обычными словами инструментальной системы, определенными через двоеточие и никак не годятся на роль макросов для инструментальной системы. Насчет DISPATCH-NUMBER - аналогичное переключение
осуществляют сами слова целевой системы, только каждое слово локально - принципиальной разницы нет, есть только отсутствие глобальной переменной-вектора .
|
|
|
|
Добавлено: Пт сен 11, 2009 07:36 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
chess писал(а): Понятно, что так формально более корректно. Но мой вариант не требует перегрузки вектора по концу определения. Этот момент я использовал для упрощения реализации макросов.
Вообще-то именно перегрузка вектора и является инструментом корректного распределения чисел между инструментальным и целевым стеками. Это никак не недостаток, а именно запланированный инструмент, о котором я и рассказал как о варианте. Макросы тут ни при чем, поскольку это обычные слова, которые можно использовать как для инструментальной, так и для целевой компиляции. Разумеется, можно несколько слов, занимающихся прямой подстановкой кодов команд, оформить в виде макроса, но числа, числа-то?! В том и смысл введенного в ядро DISPATCH-NUMBER, что оно позволяет совершенно управляемо распределять числа из входного потока между инструментальной и целевой системами.
[quote="chess"]Понятно, что так формально более корректно. Но мой вариант не требует перегрузки вектора по концу определения. Этот момент я использовал для упрощения реализации макросов. [/quote]
Вообще-то именно перегрузка вектора и является инструментом корректного распределения чисел между инструментальным и целевым стеками. Это никак не недостаток, а именно запланированный инструмент, о котором я и рассказал как о варианте. Макросы тут ни при чем, поскольку это обычные слова, которые можно использовать как для инструментальной, так и для целевой компиляции. Разумеется, можно несколько слов, занимающихся прямой подстановкой кодов команд, оформить в виде макроса, но числа, числа-то?! В том и смысл введенного в ядро DISPATCH-NUMBER, что оно позволяет совершенно управляемо распределять числа из входного потока между инструментальной и целевой системами.
|
|
|
|
Добавлено: Чт сен 10, 2009 18:00 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Хищник писал(а): Обращу внимание на вектор DISPATCH-NUMBER, которое именно обработкой чисел для кросс-системы и занимается.
Понятно, что так формально более корректно. Но мой вариант не требует перегрузки вектора по концу определения. Этот момент я использовал
для упрощения реализации макросов.
Макрос пишется просто, например:
Код: : name здесь числа и фортМК-слова ;
Как правило в теле макроса много ассемблерных команд(делается для ускорения исполнения кода).
Затем просто делать инлайн-вставки через подстановку имен
макросов.
[quote="Хищник"]Обращу внимание на вектор DISPATCH-NUMBER, которое именно обработкой чисел для кросс-системы и занимается. [/quote]
Понятно, что так формально более корректно. Но мой вариант не требует перегрузки вектора по концу определения. Этот момент я использовал
для упрощения реализации макросов.
Макрос пишется просто, например:
[code]: name здесь числа и фортМК-слова ;[/code]
Как правило в теле макроса много ассемблерных команд(делается для ускорения исполнения кода).
Затем просто делать инлайн-вставки через подстановку имен
макросов.
|
|
|
|
Добавлено: Чт сен 10, 2009 11:23 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Обращу внимание на вектор DISPATCH-NUMBER, которое именно обработкой чисел для кросс-системы и занимается. При начале определения слова для кросс-системы в DISPATCH-NUMBER записывается адрес слова TC-LIT, , а при завершении определения опять возвращается NOOP. При таком подходе переход между инструментальной и целевой компиляцией получается незаметным, и ни префиксов, ни искусственных приемов вроде "переносим все числа, как только увидим слово" не требуется.
Обращу внимание на вектор DISPATCH-NUMBER, которое именно обработкой чисел для кросс-системы и занимается. При начале определения слова для кросс-системы в DISPATCH-NUMBER записывается адрес слова TC-LIT, , а при завершении определения опять возвращается NOOP. При таком подходе переход между инструментальной и целевой компиляцией получается незаметным, и ни префиксов, ни искусственных приемов вроде "переносим все числа, как только увидим слово" не требуется.
|
|
|
|
Добавлено: Чт сен 10, 2009 10:37 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Хищник писал(а): На самом деле эти вопросы просто не нужно ставить, о чем я и написал выше с разъяснением, как для этого можно организовать кросс-транслятор.
Работа над компилятором - процесс эпизодический, а разработка ПО для аппаратуры процесс постоянный, поэтому из предметной области нужно по возможности исключать
лишние сущности вроде преффиксов и операций типа #. Ну и кто кроме пользователя инструмента и разработчика этого инструмента это лучше сделает.
[quote="Хищник"]На самом деле эти вопросы просто не нужно ставить, о чем я и написал выше с разъяснением, как для этого можно организовать кросс-транслятор.[/quote]
Работа над компилятором - процесс эпизодический, а разработка ПО для аппаратуры процесс постоянный, поэтому из предметной области нужно по возможности исключать
лишние сущности вроде преффиксов и операций типа #. Ну и кто кроме пользователя инструмента и разработчика этого инструмента это лучше сделает.
|
|
|
|
Добавлено: Чт сен 10, 2009 08:17 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
Хищник писал(а): как для этого можно организовать кросс-транслятор.
На форке это решается примерно так
Код: nums{ 1 2 3 ... тут все числа идут на стек контроллера ... }nums 5 6 ... тут как обычно на стек Код: nums{ - имя юнита который понимает числа Код: }nums - единственное слово в этом юните которое его и убирает из контекста
вобщем действительно проблем нет
[quote="Хищник"]как для этого можно организовать кросс-транслятор.[/quote]
На форке это решается примерно так
[code] nums{ 1 2 3 ... тут все числа идут на стек контроллера ... }nums 5 6 ... тут как обычно на стек [/code] [code]nums{[/code] - имя юнита который понимает числа [code]}nums [/code] - единственное слово в этом юните которое его и убирает из контекста
вобщем действительно проблем нет :roll:
|
|
|
|
Добавлено: Чт сен 10, 2009 01:05 |
|
|
|
|
|
Заголовок сообщения: |
|
|
|
chess писал(а): Решение этих вопросов на самом деле не представляет собой каких-либо принципиальных затруднений, что было сделано еще четыре года назад, когда я еще только начинал осваивать форт.
На самом деле эти вопросы просто не нужно ставить, о чем я и написал выше с разъяснением, как для этого можно организовать кросс-транслятор.
[quote="chess"]Решение этих вопросов на самом деле не представляет собой каких-либо принципиальных затруднений, что было сделано еще четыре года назад, когда я еще только начинал осваивать форт.[/quote]
На самом деле эти вопросы просто не нужно ставить, о чем я и написал выше с разъяснением, как для этого можно организовать кросс-транслятор.
|
|
|
|
Добавлено: Ср сен 09, 2009 23:28 |
|
|
|
|