kolibrios/programs/develop/oberon07/doc/STM32.txt
maxcodehack 2f54c7de00 Update oberon07 from akron1's github
git-svn-id: svn://kolibrios.org@8097 a494cfbc-eb01-0410-851d-a64ba20cac60
2020-10-13 07:58:51 +00:00

404 lines
21 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Компилятор языка программирования Oberon-07/16 для
микроконтроллеров STM32 Cortex-M3.
------------------------------------------------------------------------------
Параметры командной строки
Вход - текстовые файлы модулей с расширением ".ob07", кодировка ANSI или
UTF-8 с BOM-сигнатурой.
Выход - hex-файл прошивки.
Параметры:
1) имя главного модуля
2) "stm32cm3"
3) необязательные параметры-ключи
-out <file_name> имя результирующего файла; по умолчанию,
совпадает с именем главного модуля, но с расширением ".hex"
-ram <size> размер ОЗУ в килобайтах (4 - 65536) по умолчанию 4
-rom <size> размер ПЗУ в килобайтах (16 - 65536) по умолчанию 16
-nochk <"ptibcwra"> отключить проверки при выполнении
-lower разрешить ключевые слова и встроенные идентификаторы в
нижнем регистре
-def <имя> задать символ условной компиляции
параметр -nochk задается в виде строки из символов:
"p" - указатели
"t" - типы
"i" - индексы
"b" - неявное приведение INTEGER к BYTE
"c" - диапазон аргумента функции CHR
"w" - диапазон аргумента функции WCHR
"r" - эквивалентно "bcw"
"a" - все проверки
Порядок символов может быть любым. Наличие в строке того или иного
символа отключает соответствующую проверку.
Например: -nochk it - отключить проверку индексов и охрану типа.
-nochk a - отключить все отключаемые проверки.
Например:
Compiler.exe "C:\example.ob07" stm32cm3 -ram 32 -rom 256 -nochk pti
Compiler.exe "C:\example.ob07" stm32cm3 -out "C:\Ex1.hex" -ram 8 -rom 32
В случае успешной компиляции, компилятор передает код завершения 0, иначе 1.
При работе компилятора в KolibriOS, код завершения не передается.
------------------------------------------------------------------------------
Отличия от оригинала
1. Расширен псевдомодуль SYSTEM
2. В идентификаторах допускается символ "_"
3. Усовершенствован оператор CASE (добавлены константные выражения в
метках вариантов и необязательная ветка ELSE)
4. Расширен набор стандартных процедур
5. Семантика охраны/проверки типа уточнена для нулевого указателя
6. Добавлены однострочные комментарии (начинаются с пары символов "//")
7. Разрешено наследование от типа-указателя
8. "Строки" можно заключать также в одиночные кавычки: 'строка'
9. Добавлен тип WCHAR
10. Добавлена операция конкатенации строковых и символьных констант
11. Добавлены кодовые процедуры
------------------------------------------------------------------------------
Особенности реализации
1. Основные типы
Тип Диапазон значений Размер, байт
INTEGER -2147483648 .. 2147483647 4
REAL 1.17E-38 .. 3.40E+38 4
CHAR символ ASCII (0X .. 0FFX) 1
BOOLEAN FALSE, TRUE 1
SET множество из целых чисел {0 .. 31} 4
BYTE 0 .. 255 1
WCHAR символ юникода (0X .. 0FFFFX) 2
2. Максимальная длина идентификаторов - 1024 символов
3. Максимальная длина строковых констант - 1024 символов (UTF-8)
4. Максимальная размерность открытых массивов - 5
5. Процедура NEW заполняет нулями выделенный блок памяти
6. Локальные переменные инициализируются нулями
7. В отличие от многих Oberon-реализаций, сборщик мусора и динамическая
модульность отсутствуют
8. Тип BYTE в выражениях всегда приводится к INTEGER
9. Контроль переполнения значений выражений не производится
------------------------------------------------------------------------------
Псевдомодуль SYSTEM
Псевдомодуль SYSTEM содержит низкоуровневые и небезопасные процедуры,
ошибки при использовании процедур псевдомодуля SYSTEM могут привести к
повреждению данных времени выполнения и аварийному завершению программы.
PROCEDURE ADR(v: любой тип): INTEGER
v - переменная или процедура;
возвращает адрес v
PROCEDURE SADR(x: строковая константа (CHAR UTF-8)): INTEGER
возвращает адрес x
PROCEDURE WSADR(x: строковая константа (WCHAR)): INTEGER
возвращает адрес x
PROCEDURE SIZE(T): INTEGER
возвращает размер типа T
PROCEDURE TYPEID(T): INTEGER
T - тип-запись или тип-указатель,
возвращает номер типа в таблице типов-записей
PROCEDURE INF(): REAL
возвращает специальное вещественное значение "бесконечность"
PROCEDURE MOVE(Source, Dest, n: INTEGER)
Копирует n байт памяти из Source в Dest,
области Source и Dest не могут перекрываться
PROCEDURE GET(a: INTEGER;
VAR v: любой основной тип, PROCEDURE, POINTER)
v := Память[a]
PROCEDURE GET8(a: INTEGER;
VAR x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
Эквивалентно
SYSTEM.MOVE(a, SYSTEM.ADR(x), 1)
PROCEDURE GET16(a: INTEGER;
VAR x: INTEGER, SET, WCHAR, SYSTEM.CARD32)
Эквивалентно
SYSTEM.MOVE(a, SYSTEM.ADR(x), 2)
PROCEDURE GET32(a: INTEGER; VAR x: INTEGER, SET, SYSTEM.CARD32)
Эквивалентно
SYSTEM.MOVE(a, SYSTEM.ADR(x), 4)
PROCEDURE PUT(a: INTEGER; x: любой основной тип, PROCEDURE, POINTER)
Память[a] := x;
Если x: BYTE или x: WCHAR, то значение x будет расширено
до 32 бит, для записи байтов использовать SYSTEM.PUT8,
для WCHAR -- SYSTEM.PUT16
PROCEDURE PUT8(a: INTEGER;
x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
Память[a] := младшие 8 бит (x)
PROCEDURE PUT16(a: INTEGER;
x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
Память[a] := младшие 16 бит (x)
PROCEDURE PUT32(a: INTEGER;
x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
Память[a] := младшие 32 бит (x)
PROCEDURE CODE(hword1, hword2,... : INTEGER)
Вставка машинного кода,
hword1, hword2 ... - константы в диапазоне 0..65535,
например:
SYSTEM.CODE(0BF30H) (* wfi *)
Также, в модуле SYSTEM определен тип CARD32 (4 байта). Для типа CARD32 не
допускаются никакие явные операции, за исключением присваивания.
Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях.
------------------------------------------------------------------------------
Оператор CASE
Синтаксис оператора CASE:
CaseStatement =
CASE Expression OF Сase {"|" Сase}
[ELSE StatementSequence] END.
Case = [CaseLabelList ":" StatementSequence].
CaseLabelList = CaseLabels {"," CaseLabels}.
CaseLabels = ConstExpression [".." ConstExpression].
Например:
CASE x OF
|-1: DoSomething1
| 1: DoSomething2
| 0: DoSomething3
ELSE
DoSomething4
END
В метках вариантов можно использовать константные выражения, ветка ELSE
необязательна. Если значение x не соответствует ни одному варианту и ELSE
отсутствует, то программа прерывается с ошибкой времени выполнения.
------------------------------------------------------------------------------
Тип WCHAR
Тип WCHAR добавлен в язык для удобной поддежки юникода. Для типов WCHAR и
ARRAY OF WCHAR допускаются все те же операции, как для типов CHAR и
ARRAY OF CHAR, за исключением встроенной процедуры CHR, которая возвращает
только тип CHAR. Для получения значения типа WCHAR, следует использовать
процедуру WCHR вместо CHR. Для правильной работы с типом, необходимо сохранять
исходный код в кодировке UTF-8 c BOM.
------------------------------------------------------------------------------
Конкатенация строковых и символьных констант
Допускается конкатенация ("+") константных строк и символов типа CHAR:
str = CHR(39) + "string" + CHR(39); (* str = "'string'" *)
newline = 0DX + 0AX;
------------------------------------------------------------------------------
Проверка и охрана типа нулевого указателя
Оригинальное сообщение о языке не определяет поведение программы при
выполнении охраны p(T) и проверки типа p IS T при p = NIL. Во многих
Oberon-реализациях выполнение такой операции приводит к ошибке времени
выполнения. В данной реализации охрана типа нулевого указателя не приводит к
ошибке, а проверка типа дает результат FALSE. В ряде случаев это позволяет
значительно сократить частоту применения охраны типа.
------------------------------------------------------------------------------
Дополнительные стандартные процедуры
COPY (x: ARRAY OF CHAR/WCHAR; VAR v: ARRAY OF CHAR/WCHAR);
v := x;
Если LEN(v) < LEN(x), то строка x будет скопирована
не полностью
LSR (x, n: INTEGER): INTEGER
Логический сдвиг x на n бит вправо.
MIN (a, b: INTEGER): INTEGER
Минимум из двух значений.
MAX (a, b: INTEGER): INTEGER
Максимум из двух значений.
BITS (x: INTEGER): SET
Интерпретирует x как значение типа SET.
Выполняется на этапе компиляции.
LENGTH (s: ARRAY OF CHAR/WCHAR): INTEGER
Длина 0X-завершенной строки s, без учета символа 0X.
Если символ 0X отсутствует, функция возвращает длину
массива s. s не может быть константой.
WCHR (n: INTEGER): WCHAR
Преобразование типа, аналогично CHR(n: INTEGER): CHAR
------------------------------------------------------------------------------
Использование регистров общего назначения R0 - R12
R0 - R3: регистровый стэк (промежуточные значения выражений)
R4 - R12: не используются
------------------------------------------------------------------------------
Вызов процедур и кадр стэка
Правила вызова похожи на соглашение cdecl (x86):
- параметры передаются через стэк справа налево
- результат, если есть, передается через регистр R0
- вызывающая процедура очищает стэк
Состояние стэка при выполнении процедуры:
меньшие адреса <- |var3|var2|var1|LR|arg1|arg2|arg3| -> бОльшие адреса
LR - сохраненный регистр LR (адрес возврата)
argX - параметры в порядке объявления (слева направо)
varX - локальные переменные в порядке использования в процедуре
Размер каждого элемента в стэке (кроме локальных переменных структурных
типов) - 1 машинное слово (4 байта). Структурные переменные (массивы и
записи) занимают место в стэке в соответствии с их размером (с учетом
выравнивания).
Размещение локальных переменных зависит от их размеров и порядка
использования, и в общем случае неопределенно. Если переменная не
используется явно, то компилятор не выделяет для нее место в стэке.
------------------------------------------------------------------------------
Скрытые параметры процедур
Некоторые процедуры могут иметь скрытые параметры, они отсутствуют в списке
формальных параметров, но учитываются компилятором при трансляции вызовов.
Это возможно в следующих случаях:
1. Процедура имеет формальный параметр открытый массив:
PROCEDURE Proc (x: ARRAY OF ARRAY OF REAL);
Вызов транслируется так:
Proc(LEN(x), LEN(x[0]), SYSTEM.ADR(x))
2. Процедура имеет формальный параметр-переменную типа RECORD:
PROCEDURE Proc (VAR x: Rec);
Вызов транслируется так:
Proc(SYSTEM.TYPEID(Rec), SYSTEM.ADR(x))
------------------------------------------------------------------------------
Кодовые процедуры
Компилятор поддерживает процедуры, написаные в машинных кодах.
Синтаксис:
PROCEDURE "[code]" имя [ (параметры): ТипРезультата ]
МашКом, МашКом,... МашКом;
";" после заголовка и END "имя" в конце процедуры не ставятся.
МашКом - целочисленная константа [0..65535] (в том числе и константное
выражение).
Например:
PROCEDURE [code] WFI
0BF30H; (* wfi *)
Компилятор автоматически добавляет к такой процедуре команду возврата
(bx LR). Способ передачи параметров и результата не изменяется. Регистр LR,
при входе в процедуру не сохраняется.
Чтобы использовать кодовые процедуры, необходимо импортировать псевдомодуль
SYSTEM.
------------------------------------------------------------------------------
Обработка прерываний
При возникновении прерывания, будет вызван обработчик (если он объявлен).
Объявление обработчика:
PROCEDURE handler_name [iv]; (* процедура без параметров *)
iv - целочисленная константа (константное выражение), номер вектора прерывания
в таблице векторов, iv >= 2:
0 начальное значение SP
1 сброс
...
15 SysTick
...
59 TIM6
60 TIM7
...
например:
(* обработчик прерываний от TIM6 *)
PROCEDURE tim6 [59];
BEGIN
(* код обработки *)
END tim6;
Также, можно объявить общий обработчик (iv = 0), который будет вызван, если
не назначен индивидуальный. Общий обработчик получает параметр - номер вектора
прерывания. По значению этого параметра, обработчик должен определить источник
прерывания и выполнить соответствующие действия:
PROCEDURE handler (iv: INTEGER) [0];
BEGIN
IF iv = 59 THEN
(* TIM6 *)
ELSIF iv = 60 THEN
(* TIM7 *)
ELSIF ....
....
END
END handler;
В конец программы компилятор добавляет команду ожидания прерывания.
------------------------------------------------------------------------------
Обработка ошибок
В случае возникновения ошибки при выполнении программы, будет вызван
пользовательский обработчик (если он объявлен).
Объявление обработчика ошибок:
PROCEDURE trap (modNum, modName, err, line: INTEGER) [1];
BEGIN
END trap;
где,
modNum - номер модуля (в отчете о компиляции:
compiling (modNum) "modName" )
modName - адрес имени модуля
err - код ошибки
line - номер строки
Коды ошибок:
1 ASSERT(x), при x = FALSE
2 разыменование нулевого указателя
3 целочисленное деление на неположительное число
4 вызов процедуры через процедурную переменную с нулевым значением
5 ошибка охраны типа
6 нарушение границ массива
7 непредусмотренное значение выражения в операторе CASE
8 ошибка копирования массивов v := x, если LEN(v) < LEN(x)
9 CHR(x), если (x < 0) OR (x > 255)
10 WCHR(x), если (x < 0) OR (x > 65535)
11 неявное приведение x:INTEGER к v:BYTE, если (x < 0) OR (x > 255)
После возврата из обработчика программа будет перезапущена.
------------------------------------------------------------------------------