Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1.         Компилятор языка программирования Oberon-07/16 для
  2.             микроконтроллеров MSP430x{1,2}xx.
  3. ------------------------------------------------------------------------------
  4.  
  5.         Параметры командной строки
  6.  
  7.   Вход - текстовые файлы модулей с расширением ".ob07", кодировка ANSI или
  8. UTF-8 с BOM-сигнатурой.
  9.   Выход - hex-файл прошивки.
  10.   Параметры:
  11.   1) имя главного модуля
  12.   2) "msp430"
  13.   3) необязательные параметры-ключи
  14.       -out <file_name> имя результирующего файла; по умолчанию,
  15.       совпадает с именем главного модуля, но с расширением ".hex"
  16.       -ram <size> размер ОЗУ в байтах (128 - 2048) по умолчанию 128
  17.       -rom <size> размер ПЗУ в байтах (2048 - 24576) по умолчанию 2048
  18.       -nochk <"ptibcwra"> отключить проверки при выполнении
  19.       -lower разрешить ключевые слова и встроенные идентификаторы в
  20.       нижнем регистре
  21.       -def <имя> задать символ условной компиляции
  22.  
  23.       параметр -nochk задается в виде строки из символов:
  24.       "p" - указатели
  25.       "t" - типы
  26.       "i" - индексы
  27.       "b" - неявное приведение INTEGER к BYTE
  28.       "c" - диапазон аргумента функции CHR
  29.       "a" - все проверки
  30.  
  31.       Порядок символов может быть любым. Наличие в строке того или иного
  32.       символа отключает соответствующую проверку.
  33.  
  34.       Например: -nochk it - отключить проверку индексов и охрану типа.
  35.       -nochk a - отключить все отключаемые проверки.
  36.  
  37.   Например:
  38.  
  39.   Compiler.exe "C:\example.ob07" msp430 -ram 128 -rom 4096 -nochk pti
  40.   Compiler.exe "C:\example.ob07" msp430 -out "C:\Ex1.hex" -ram 512 -rom 16384
  41.  
  42.   В случае успешной компиляции, компилятор передает код завершения 0, иначе 1.
  43. При работе компилятора в KolibriOS, код завершения не передается.
  44.  
  45. ------------------------------------------------------------------------------
  46.         Отличия от оригинала
  47.  
  48.  1.     Расширен псевдомодуль SYSTEM
  49.  2.     В идентификаторах допускается символ "_"
  50.  3.     Усовершенствован оператор CASE (добавлены константные выражения в
  51.         метках вариантов и необязательная ветка ELSE)
  52.  4.     Расширен набор стандартных процедур
  53.  5.     Семантика охраны/проверки типа уточнена для нулевого указателя
  54.  6.     Добавлены однострочные комментарии (начинаются с пары символов "//")
  55.  7.     Разрешено наследование от типа-указателя
  56.  8.     "Строки" можно заключать также в одиночные кавычки: 'строка'
  57.  9.     Добавлена операция конкатенации строковых и символьных констант
  58. 10.     Добавлены кодовые процедуры
  59. 11.     Не реализована вещественная арифметика
  60.  
  61. ------------------------------------------------------------------------------
  62.         Особенности реализации
  63.  
  64. 1.      Основные типы
  65.  
  66.           Тип              Диапазон значений               Размер, байт
  67.  
  68.         INTEGER       -32768 .. 32767                           2
  69.         CHAR          символ ASCII (0X .. 0FFX)                 1
  70.         BOOLEAN       FALSE, TRUE                               1
  71.         SET           множество из целых чисел {0 .. 15}        2
  72.         BYTE          0 .. 255                                  1
  73.  
  74. 2.      Максимальная длина идентификаторов - 1024 символов
  75. 3.      Максимальная длина строковых констант - 1024 символов (UTF-8)
  76. 4.      Максимальная размерность открытых массивов - 5
  77. 5.      Процедура NEW заполняет нулями выделенный блок памяти
  78. 6.      Локальные переменные инициализируются нулями
  79. 7.      В отличие от многих Oberon-реализаций, сборщик мусора и динамическая
  80.         модульность отсутствуют
  81. 8.      Тип BYTE в выражениях всегда приводится к INTEGER
  82. 9.      Контроль переполнения значений выражений не производится
  83. 10.     Ошибки времени выполнения:
  84.  
  85. номер    ошибка
  86.  
  87.  1       ASSERT(x), при x = FALSE
  88.  2       разыменование нулевого указателя
  89.  3       целочисленное деление на неположительное число
  90.  4       вызов процедуры через процедурную переменную с нулевым значением
  91.  5       ошибка охраны типа
  92.  6       нарушение границ массива
  93.  7       непредусмотренное значение выражения в операторе CASE
  94.  8       ошибка копирования массивов v := x, если LEN(v) < LEN(x)
  95.  9       CHR(x), если (x < 0) OR (x > 255)
  96. 11       неявное приведение x:INTEGER к v:BYTE, если (x < 0) OR (x > 255)
  97.  
  98. ------------------------------------------------------------------------------
  99.         Псевдомодуль SYSTEM
  100.  
  101.   Псевдомодуль SYSTEM содержит низкоуровневые и небезопасные процедуры,
  102. ошибки при использовании процедур псевдомодуля SYSTEM могут привести к
  103. повреждению данных времени выполнения и аварийному завершению программы.
  104.  
  105.         PROCEDURE ADR(v: любой тип): INTEGER
  106.                 v - переменная или процедура;
  107.                 возвращает адрес v
  108.  
  109.         PROCEDURE SADR(x: строковая константа): INTEGER
  110.                 возвращает адрес x
  111.  
  112.         PROCEDURE SIZE(T): INTEGER
  113.                 возвращает размер типа T
  114.  
  115.         PROCEDURE TYPEID(T): INTEGER
  116.                 T - тип-запись или тип-указатель,
  117.                 возвращает номер типа в таблице типов-записей
  118.  
  119.         PROCEDURE MOVE(Source, Dest, n: INTEGER)
  120.                 Копирует n байт памяти из Source в Dest,
  121.                 области Source и Dest не могут перекрываться
  122.  
  123.         PROCEDURE GET(a: INTEGER;
  124.                 VAR v: любой основной тип, PROCEDURE, POINTER)
  125.                 v := Память[a]
  126.  
  127.         PROCEDURE GET8(a: INTEGER; VAR x: INTEGER, SET, BYTE, CHAR)
  128.                 Эквивалентно
  129.                 SYSTEM.MOVE(a, SYSTEM.ADR(x), 1)
  130.  
  131.         PROCEDURE PUT(a: INTEGER; x: любой основной тип, PROCEDURE, POINTER)
  132.                 Память[a] := x;
  133.                 Если x: BYTE, то значение x будет расширено до 16 бит,
  134.                 для записи байтов использовать SYSTEM.PUT8
  135.  
  136.         PROCEDURE PUT8(a: INTEGER; x: INTEGER, SET, BYTE, CHAR)
  137.                 Память[a] := младшие 8 бит (x)
  138.  
  139.         PROCEDURE CODE(word1, word2,... : INTEGER)
  140.                 Вставка машинного кода,
  141.                 word1, word2 ... - целочисленные константы (константные
  142.                 выражения) - машинные слова, например:
  143.                 SYSTEM.CODE(0D032H, 0010H) (* BIS #16, SR; CPUOFF *)
  144.  
  145.  
  146.   Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях.
  147.  
  148. ------------------------------------------------------------------------------
  149.         Оператор CASE
  150.  
  151.   Синтаксис оператора CASE:
  152.  
  153.         CaseStatement =
  154.                 CASE Expression OF Сase {"|" Сase}
  155.                         [ELSE StatementSequence] END.
  156.         Case = [CaseLabelList ":" StatementSequence].
  157.         CaseLabelList = CaseLabels {"," CaseLabels}.
  158.         CaseLabels = ConstExpression [".." ConstExpression].
  159.  
  160.   Например:
  161.  
  162.         CASE x OF
  163.         |-1:    DoSomething1
  164.         | 1:    DoSomething2
  165.         | 0:    DoSomething3
  166.         ELSE
  167.                 DoSomething4
  168.         END
  169.  
  170.   В метках вариантов можно использовать константные выражения, ветка ELSE
  171. необязательна. Если значение x не соответствует ни одному варианту и ELSE
  172. отсутствует, то программа прерывается с ошибкой времени выполнения.
  173.  
  174. ------------------------------------------------------------------------------
  175.         Конкатенация строковых и символьных констант
  176.  
  177.   Допускается конкатенация ("+") константных строк и символов типа CHAR:
  178.  
  179.   str = CHR(39) + "string" + CHR(39); (* str = "'string'" *)
  180.  
  181.   newline = 0DX + 0AX;
  182.  
  183. ------------------------------------------------------------------------------
  184.         Проверка и охрана типа нулевого указателя
  185.  
  186.   Оригинальное сообщение о языке не определяет поведение программы при
  187. выполнении охраны p(T) и проверки типа p IS T при p = NIL. Во многих
  188. Oberon-реализациях выполнение такой операции приводит к ошибке времени
  189. выполнения. В данной реализации охрана типа нулевого указателя не приводит к
  190. ошибке, а проверка типа дает результат FALSE. В ряде случаев это позволяет
  191. значительно сократить частоту применения охраны типа.
  192.  
  193. ------------------------------------------------------------------------------
  194.         Дополнительные стандартные процедуры
  195.  
  196.  
  197.         COPY (x: ARRAY OF CHAR; VAR v: ARRAY OF CHAR);
  198.                 v := x;
  199.                 Если LEN(v) < LEN(x), то строка x будет скопирована
  200.                 не полностью.
  201.  
  202.         LSR (x, n: INTEGER): INTEGER
  203.                 Логический сдвиг x на n бит вправо.
  204.  
  205.         MIN (a, b: INTEGER): INTEGER
  206.                 Минимум из двух значений.
  207.  
  208.         MAX (a, b: INTEGER): INTEGER
  209.                 Максимум из двух значений.
  210.  
  211.         BITS (x: INTEGER): SET
  212.                 Интерпретирует x как значение типа SET.
  213.                 Выполняется на этапе компиляции.
  214.  
  215.         LENGTH (s: ARRAY OF CHAR): INTEGER
  216.                 Длина 0X-завершенной строки s, без учета символа 0X.
  217.                 Если символ 0X отсутствует, функция возвращает длину
  218.                 массива s. s не может быть константой.
  219.  
  220. ------------------------------------------------------------------------------
  221.         Использование регистров общего назначения R4 - R15
  222.  
  223.         R4 - R7:  регистровый стэк (промежуточные значения выражений)
  224.         R8 - R13: не используются
  225.         R14:      указатель кучи
  226.         R15:      используется при обработке прерываний
  227.  
  228. ------------------------------------------------------------------------------
  229.         Вызов процедур и кадр стэка
  230.  
  231.   Правила вызова похожи на соглашение cdecl (x86):
  232.   - параметры передаются через стэк справа налево
  233.   - результат, если есть, передается через регистр R4
  234.   - вызывающая процедура очищает стэк
  235.  
  236.   Состояние стэка при выполнении процедуры:
  237.  
  238.   меньшие адреса <- |var3|var2|var1|PC|arg1|arg2|arg3| -> бОльшие адреса
  239.  
  240.   PC   - значение регистра PC перед вызовом (адрес возврата)
  241.   argX - параметры в порядке объявления (слева направо)
  242.   varX - локальные переменные в порядке использования в процедуре
  243.  
  244.   Размер каждого элемента в стэке (кроме локальных переменных структурных
  245.   типов) - 1 машинное слово (2 байта). Структурные переменные (массивы и
  246.   записи) занимают место в стэке в соответствии с их размером (с учетом
  247.   выравнивания).
  248.  
  249.   Размещение локальных переменных зависит от их размеров и порядка
  250.   использования, и в общем случае неопределенно. Если переменная не
  251.   используется явно, то компилятор не выделяет для нее место в стэке.
  252.  
  253. ------------------------------------------------------------------------------
  254.         Скрытые параметры процедур
  255.  
  256.   Некоторые процедуры могут иметь скрытые параметры, они отсутствуют в списке
  257. формальных параметров, но учитываются компилятором при трансляции вызовов.
  258. Это возможно в следующих случаях:
  259.  
  260. 1.      Процедура имеет формальный параметр открытый массив:
  261.                 PROCEDURE Proc (x: ARRAY OF ARRAY OF REAL);
  262.         Вызов транслируется так:
  263.                 Proc(LEN(x), LEN(x[0]), SYSTEM.ADR(x))
  264. 2.      Процедура имеет формальный параметр-переменную типа RECORD:
  265.                 PROCEDURE Proc (VAR x: Rec);
  266.         Вызов транслируется так:
  267.                 Proc(SYSTEM.TYPEID(Rec), SYSTEM.ADR(x))
  268.  
  269. ------------------------------------------------------------------------------
  270.         Кодовые процедуры
  271.  
  272.   Компилятор поддерживает процедуры, написаные в машинных кодах.
  273.   Синтаксис:
  274.  
  275.   PROCEDURE "[code]" имя [ (параметры): ТипРезультата ]
  276.       МашСлово, МашСлово,... МашСлово;
  277.  
  278.   ";" после заголовка и END "имя" в конце процедуры не ставятся.
  279.   МашСлово - целочисленная константа (в том числе и константное выражение).
  280.   Например:
  281.  
  282.   PROCEDURE [code] asr (n, x: INTEGER): INTEGER  (* ASR(x, n) -> R4 *)
  283.       4115H, 2,              (*  MOV  2(SP), R5; R5 <- n  *)
  284.       4114H, 4,              (*  MOV  4(SP), R4; R4 <- x  *)
  285.       0F035H, 15,            (*  AND  #15, R5             *)
  286.       2400H + 3,             (*  JZ   L1                  *)
  287.                              (*  L2:                      *)
  288.       1104H,                 (*  RRA  R4                  *)
  289.       8315H,                 (*  SUB  #1, R5              *)
  290.       2000H + 400H - 3;      (*  JNZ  L2                  *)
  291.                              (*  L1:                      *)
  292.  
  293.   Компилятор автоматически добавляет к такой процедуре команду RET.
  294.   Способ передачи параметров и результата не изменяется.
  295.  
  296.   Кодовые процедуры можно использовать также и для добавления в программу
  297. константных данных:
  298.  
  299.   PROCEDURE [code] sqr
  300.       0, 1, 4, 9, 16, 25, 36, 49, 64, 81;
  301.  
  302.   Получить адрес такой "процедуры": SYSTEM.ADR(sqr).
  303.   Получить адрес n-го машинного слова: SYSTEM.ADR(sqr) + n * 2.
  304.  
  305.   Чтобы использовать кодовые процедуры, необходимо импортировать псевдомодуль
  306. SYSTEM.
  307.  
  308. ------------------------------------------------------------------------------
  309.         Обработка прерываний
  310.  
  311.   При появлении запроса на прерывание, процессор:
  312.   - помещает в стэк значение регистра PC
  313.   - помещает в стэк значение регистра SR
  314.   - очищает регистр SR
  315.   - выполняет переход по адресу IV[priority], где
  316.     IV - таблица векторов прерываний,
  317.     priority - приоритет прерывания (номер элемента в таблице IV) (0..30)
  318.  
  319.   Компилятор генерирует код обработки прерываний:
  320.  
  321.                    ; IV[0] = адрес следующей команды
  322.   PUSH  #0         ; поместить в стэк приоритет прерывания
  323.   JMP   Label      ; перейти к обработчику
  324.  
  325.                    ; IV[1] = адрес следующей команды
  326.   PUSH  #1         ; поместить в стэк приоритет прерывания
  327.   JMP   Label      ; перейти к обработчику
  328.  
  329.   ...
  330.                    ; IV[priority] = адрес следующей команды
  331.   PUSH  #priority  ; поместить в стэк приоритет прерывания
  332.   JMP   Label      ; перейти к обработчику
  333.  
  334.   ...
  335.                    ; IV[30] = адрес следующей команды
  336.   PUSH  #30        ; поместить в стэк приоритет прерывания
  337.  
  338.   Label:
  339.   MOV   SP, R15    ; настроить R15 на структуру данных прерывания (см. далее)
  340.   PUSH  R4         ; сохранить рабочие регистры (R4 - R7)
  341.   ...
  342.   PUSH  R7
  343.   PUSH  R15        ; передать параметр interrupt в обработчик (см. далее)
  344.   PUSH  @R15       ; передать параметр priority в обработчик (см. далее)
  345.   CALL  int        ; вызвать обработчик (см. далее)
  346.   ADD   #4, SP     ; удалить из стэка параметры обработчика
  347.   POP   R7         ; восстановить рабочие регистры (R7 - R4)
  348.   ...
  349.   POP   R4
  350.   ADD   #2, SP     ; удалить из стэка значение priority
  351.   RETI             ; возврат из прерывания (восстановить SR и PC)
  352.  
  353. ------------------------------------------------------------------------------
  354.         Обработка ошибок
  355.  
  356.   В случае возникновения ошибки при выполнении программы, будет вызван общий
  357. обработчик ошибок, который:
  358.  
  359.   - запрещает прерывания
  360.   - сбрасывает стэк (во избежание переполнения в процессе обработки ошибки)
  361.   - передает параметры в пользовательский обработчик (см. далее)
  362.   - вызывает пользовательский обработчик (если он назначен)
  363.   - повторно запрещает прерывания
  364.   - выключает CPU и все тактовые сигналы
  365.  
  366.   Если выключать CPU не требуется, то пользовательский обработчик может,
  367. например, перезапустить программу.
  368.  
  369. ------------------------------------------------------------------------------
  370.         Инициализация и финализация программы
  371.  
  372.   В начало программы компилятор вставляет код, который:
  373.   - инициализирует регистры SP и R14
  374.   - выключает сторожевой таймер
  375.   - назначает пустой обработчик прерываний
  376.   - сбрасывает обработчик ошибок
  377.  
  378.   В конец программы добавляет команду
  379.   BIS #16, SR; выключить CPU
  380.  
  381. ------------------------------------------------------------------------------
  382.         Структура ОЗУ (RAM)
  383.  
  384.   начало -> | спец. переменные | глобальные переменные | куча/стэк | <- конец
  385.  
  386.   Компилятор поддерживает размер ОЗУ 128..2048 байт. В нижних адресах
  387. располагаются специальные переменные, и далее пользовательские глобальные
  388. переменные. Оставшаяся часть памяти отводится для кучи и стэка (не менее 64
  389. байта). При старте программы, в регистр R14 записывается адрес начала области
  390. кучи/стэка, а регистр SP настраивается на конец ОЗУ (начало_ОЗУ + размер_ОЗУ).
  391. При выделении памяти процедурой NEW, значение регистра R14 увеличивается (если
  392. есть свободная память). Таким образом, стэк и куча растут навстречу друг
  393. другу. Проверка переполнения стэка не производится.
  394.  
  395. ------------------------------------------------------------------------------
  396.         Структура ПЗУ (RОM)
  397.  
  398.   начало -> |код|свободная область|спец. данные|векторы прерываний| <- конец
  399.  
  400.   Компилятор поддерживает размер ПЗУ 2048..24576 байт. В верхних адресах
  401. располагается таблица векторов прерываний (64 байта), адреса 0FFC0H..0FFFFH.
  402. Непосредственно перед ней размещаются специальные данные. Программный
  403. код начинается с адреса (10000H - размер_ПЗУ), этот адрес является также и
  404. точкой входа в программу. Между кодом и спец. данными может оставаться
  405. свободное пространство. Если размер ПЗУ больше, чем указан при компиляции,
  406. то перед кодом будет свободная область. Таким способом можно зарезервировать
  407. нижние сегменты флэш-памяти для записи во время выполнения программы.
  408.  
  409. ==============================================================================
  410. MODULE MSP430
  411.  
  412. CONST
  413.  
  414.     биты регистра SR:
  415.  
  416.     GIE     = {3}
  417.     CPUOFF  = {4}
  418.     OSCOFF  = {5}
  419.     SCG0    = {6}
  420.     SCG1    = {7}
  421.  
  422.  
  423. TYPE
  424.  
  425.     TInterrupt = RECORD priority: INTEGER; sr: SET; pc: INTEGER END
  426.         структура данных прерывания
  427.  
  428.         priority - приоритет прерывания:
  429.  
  430.         адрес    приоритет
  431.         0FFFEH     31
  432.         0FFFCH     30
  433.         0FFFAH     29
  434.         ...
  435.         0FFC0H      0
  436.  
  437.         sr - сохраненное значение регистра SR
  438.         pc - сохраненное значение регистра PC
  439.  
  440.  
  441.     TTrapProc = PROCEDURE (modNum, modName, err, line: INTEGER);
  442.         Процедура-обработчик ошибок.
  443.  
  444.         modNum  - номер модуля (в отчете о компиляции:
  445.                   compiling (modNum) "modName" )
  446.         modName - адрес имени модуля
  447.         err     - номер ошибки
  448.         line    - номер строки
  449.  
  450.  
  451.     TIntProc = PROCEDURE (priority: INTEGER; interrupt: TInterrupt)
  452.         Процедура-обработчик прерываний.
  453.  
  454.         priority  - приоритет прерывания
  455.         interrupt - структура данных прерывания
  456.  
  457.  
  458.     PROCEDURE SetTrapProc (TrapProc: TTrapProc)
  459.         Назначить обработчик ошибок.
  460.  
  461.  
  462.     PROCEDURE SetIntProc (IntProc: TIntProc)
  463.         Назначить обработчик прерываний.
  464.  
  465.         Нельзя вызывать эту процедуру с параметром NIL, т. к. для экономии
  466.         тактов, значение адреса обработчика прерываний не проверяется на NIL.
  467.  
  468.  
  469.     PROCEDURE Restart
  470.         Перезапустить программу.
  471.         При этом: очищается регистр SR, повторно выполняется код инициализации
  472.         программы (см. выше). Всё прочее состояние ОЗУ и регистров устройств
  473.         сохраняется.
  474.  
  475.  
  476.     PROCEDURE SetIntPC (interrupt: TInterrupt; NewPC: INTEGER)
  477.         interrupt.pc := NewPC
  478.         После возврата из прерывания, регистр PC получит значение NewPC.
  479.  
  480.  
  481.     PROCEDURE SetIntSR (interrupt: TInterrupt; NewSR: SET)
  482.         interrupt.sr := NewSR
  483.         После возврата из прерывания, регистр SR получит значение NewSR.
  484.  
  485.  
  486.     PROCEDURE DInt
  487.         Запретить прерывания.
  488.  
  489.  
  490.     PROCEDURE EInt
  491.         Разрешить прерывания.
  492.  
  493.  
  494.     PROCEDURE CpuOff
  495.         Выключить CPU (установить бит CPUOFF регистра SR).
  496.  
  497.  
  498.     PROCEDURE Halt
  499.         Запретить прерывания, выключить CPU и все тактовые сигналы.
  500.  
  501.  
  502.     PROCEDURE SetSR (bits: SET)
  503.         Установить биты bits регистра SR.
  504.  
  505.  
  506.     PROCEDURE ClrSR (bits: SET)
  507.         Сбросить биты bits регистра SR.
  508.  
  509.  
  510.     PROCEDURE GetFreeFlash (VAR address, size: INTEGER)
  511.         Получить адрес и размер свободной области Flash/ROM
  512.         (между кодом и данными).
  513.  
  514.  
  515.     PROCEDURE Delay (n: INTEGER)
  516.         Задержка выполнения программы на 1000*n тактов,
  517.         но не менее чем на 2000 тактов.
  518.  
  519.  
  520. ==============================================================================