Оберон-клуб «ВЄДАsoft»

Твердыня модульных языков
Текущее время: 14 ноя 2019, 21:38

Часовой пояс: UTC + 2 часа




Начать новую тему Ответить на тему  [ Сообщений: 57 ]  На страницу Пред.  1, 2, 3, 4, 5, 6
Автор Сообщение
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 26 июл 2019, 17:54 
Не в сети

Сообщения: 32
Comdiv писал(а):
Есть простейшая реализация кучи как стека - лучше, чем ничего. Но если на всех целевых микроконтроллерах памяти всегда мало, то без освобождения только лучше.

Так и сделано

Comdiv писал(а):
Цитата:
- Системные флаги (пока не нужно)
Что это?

[ccall], [noalign], ... -- такое же расширение, как и DISPOSE, WCHAR.

Comdiv писал(а):
Необходимость использовать SYSTEM без возможности задействовать более удобные способы лезть в систему способствует выработке предметного слоя абстракции при наличии минимального понимания у разработчика.


По поводу SYSTEM.
Нижние 512 байт адресного пространства (0H-01FFH) занимают регистры специальных функций и регистры 8- и 16-битной периферии.
Сейчас, обращение к ним осуществляется через SYSTEM.GET/SYSTEM.PUT. Это просто, универсально, но выглядит некрасиво.
Возможные решения:

- использовать переменную-указатель
Код: "OBERON"
  1.  
  2. CONST
  3. REDLED = 1;
  4. GREENLED = 40H;
  5.  
  6. WDT = (120H - 100H) DIV 2;
  7. P1DIR = 22H - 10H;
  8.  
  9. VAR
  10. p8: POINTER TO RECORD r: ARRAY 240 OF BYTE END;
  11. p16: POINTER TO RECORD r: ARRAY 128 OF INTEGER END;
  12.  
  13. BEGIN
  14. SYSTEM.PUT16(SYSTEM.ADR(p8), 10H); (* 8-битные устройства находятся в адресах 10H .. 0FFH *)
  15. SYSTEM.PUT16(SYSTEM.ADR(p16), 100H); (* 16-битные устройства находятся в адресах 100H .. 1FFH *)
  16.  
  17. p16.r[WDT] := 5A80H; (* отключить сторожевой таймер *)
  18. p8.r[P1DIR] := REDLED + GREENLED;

недостатки: длинная запись, т. к. нет указателей на массивы; обращение к устройствам по индексу в массиве, а не по адресу; кроме того, компилятор будет вставлять ненужную проверку на NIL (но это можно отключить).

- сделать возможным указать адрес переменной при объявлении
Код: "OBERON"
  1. CONST
  2. REDLED = 1;
  3. GREENLED = 40H;
  4.  
  5. aWDT = 120H;
  6. aP1DIR = 22H;
  7.  
  8. VAR
  9. WDT [aWDT]: INTEGER;
  10. P1DIR [aP1DIR]: BYTE;
  11.  
  12. BEGIN
  13. WDT := 5A80H; (* отключить сторожевой таймер *)
  14. P1DIR := REDLED + GREENLED;
  15.  


Второй вариант выглядит лучше и должен быть эффективнее и компактнее.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 26 июл 2019, 23:09 
Не в сети

Сообщения: 144
Тут, на мой взгляд, можно совершить ту же ошибку, что широко распространена во многих платформах-языках.
Есть абстракция языка программирования - переменные. Есть память как аппаратное устройство - часть компьютера. Переменные языка, в основном, отображаются на это устройство, поэтому когда возникает необходимость работы с памятью именно как с устройством, возникает соблазн работать с ним через всю ту же языковую абстркацию, расширив её дополнительными понятиями, наподобие volatile, absolute address, и других. Но ошибка заключается в ошибочном выборе представления, из-за чего вид кода не соответствует тому, что он делает. Если с памятью нужно работать как с устройством, то и использовать лучше абстракцию языка, больше соответствующее устройству - процедуры. Например
Код: "OBERON"
выглядит лучше в виде чего-то такого
Код: "OBERON"
  1. Device.Watchdog(FALSE);

а этот код
Код: "OBERON"
  1. P1DIR := REDLED + GREENLED
так
Код: "OBERON"
  1. Device.TurnLed({REDLED, GREENLED})


Если нужен обобщённый механизм, то всё равно лучше использовать процедуры
Код: "OBERON"
  1. Device.PutInt(WDT, 5A80H);
  2. Device.PutByte(P1DIR, REDLED + GREENLED);
И пусть всё будет эффективно за счёт псевдомодульности или иных, менее хардкодных способов оптимизации


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 27 июл 2019, 06:52 
Не в сети

Сообщения: 32
Понятное дело, чем меньше ресурсы системы, тем ближе средства разработки к железу.
Тут уж не до абстракций -- такты и байты сэкономить бы.
Но вообще, это надо как следует продумать, а пока обкатать то, что есть.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 27 июл 2019, 12:33 
Не в сети

Сообщения: 144
akron1 писал(а):
Тут уж не до абстракций -- такты и байты сэкономить бы.
Абстракции же не обязаны отнимать дополнительные ресурсы во время исполнения программы.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 12 авг 2019, 16:43 
Не в сети

Сообщения: 32
Я переписал RTL (MSP430) в машинных кодах и встроил его в компилятор, так, чтобы в прошивку добавлялись только те процедуры RTL, которые используются. Это позволило снизить минимально допустимый размер ПЗУ до 2048 байт, а также значительно увеличило производительность для некоторых операций. В процессе переписывания, выяснилось, что рукописный машинный код получается в 2-3 раза меньше и в 2-4 раза быстрее. Впрочем, я ожидал получить результат еще хуже. Компилятор всё же написан не для хорошей кодогенерации, а для быстрого добавления бэк-эндов. Кое-что в кодогенерации еще можно улучшить, ну а пока, если я ничего не забыл, для простых экспериментов уже подходит.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 12 авг 2019, 20:01 
Не в сети

Сообщения: 62
Откуда: Equestria
Почему бы не маркировать используемые процедуры? Все равно используется IL, а не прямая генерация, можно без проблем дропать неиспользуемое.

_________________
Извините, хоть и пони, но не толерантный и не терпеливый. Ну щито поделать.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Oberon-07/16
СообщениеДобавлено: 12 авг 2019, 21:33 
Не в сети

Сообщения: 32
SovietPony писал(а):
Почему бы не маркировать используемые процедуры? Все равно используется IL, а не прямая генерация, можно без проблем дропать неиспользуемое.

Для пользовательских процедур так и сделано. Фронт-энд, перед передачей промежуточного кода в бэк-энд, удаляет неиспользуемые процедуры. Но для RTL все намного сложнее. Фронт-энд знает только имена процедур, но не знает об их назначении. Например, если фронт-энд встречает операцию целочисленного умножения, то он генерирует команду MUL промежуточного кода. Бэк-энд, встречая команду MUL, если это x86, транслирует ее в машинную команду imul, а если это MSP430 - в вызов процедуры RTL._mul. Таким образом, фронт-энд не знает, какая операция потребует вызов RTL-процедуры (и не должен знать). Бэк-энд получает линейный список команд промежуточного кода и не имеет информации об использовании процедур (RTL-процедура может вызвать другую RTL-процедуру или вспомогательную). Поэтому модуль RTL всегда добавляется в результирующий файл полностью. Фронт-энд считает, что все процедуры RTL._* используются. Для больших машин, удалять неиспользуемые части RTL не нужно: размер RTL для x86(64) < 10 кб. А для контроллеров лучше встроить RTL в бэк-энд и, тем самым, сэкономить байты и такты без усложнения компилятора. Сложно, разве что, программировать в маш. кодах, но для MSP430 это оказалось сравнительно просто.


Вернуться к началу
 Профиль  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 57 ]  На страницу Пред.  1, 2, 3, 4, 5, 6

Часовой пояс: UTC + 2 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group
Тех.поддержка phpBB