STM32.txt 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1.  Компилятор языка программирования Oberon-07/16 для
  2. микроконтроллеров STM32 Cortex-M3.
  3. ------------------------------------------------------------------------------
  4. Параметры командной строки
  5. Вход - текстовые файлы модулей с расширением ".ob07", кодировка ANSI или
  6. UTF-8 с BOM-сигнатурой.
  7. Выход - hex-файл прошивки.
  8. Параметры:
  9. 1) имя главного модуля
  10. 2) "stm32cm3"
  11. 3) необязательные параметры-ключи
  12. -out <file_name> имя результирующего файла; по умолчанию,
  13. совпадает с именем главного модуля, но с расширением ".hex"
  14. -ram <size> размер ОЗУ в килобайтах (4 - 65536) по умолчанию 4
  15. -rom <size> размер ПЗУ в килобайтах (16 - 65536) по умолчанию 16
  16. -tab <width> размер табуляции (используется для вычисления координат в
  17. исходном коде), по умолчанию - 4
  18. -nochk <"ptibcwra"> отключить проверки при выполнении
  19. -lower разрешить ключевые слова и встроенные идентификаторы в
  20. нижнем регистре (по умолчанию)
  21. -upper только верхний регистр для ключевых слов и встроенных
  22. идентификаторов
  23. -def <имя> задать символ условной компиляции
  24. -uses вывести список импортированных модулей
  25. параметр -nochk задается в виде строки из символов:
  26. "p" - указатели
  27. "t" - типы
  28. "i" - индексы
  29. "b" - неявное приведение INTEGER к BYTE
  30. "c" - диапазон аргумента функции CHR
  31. "w" - диапазон аргумента функции WCHR
  32. "r" - эквивалентно "bcw"
  33. "a" - все проверки
  34. Порядок символов может быть любым. Наличие в строке того или иного
  35. символа отключает соответствующую проверку.
  36. Например: -nochk it - отключить проверку индексов и охрану типа.
  37. -nochk a - отключить все отключаемые проверки.
  38. Например:
  39. Compiler.exe "C:\example.ob07" stm32cm3 -ram 32 -rom 256 -nochk pti
  40. Compiler.exe "C:\example.ob07" stm32cm3 -out "C:\Ex1.hex" -ram 8 -rom 32
  41. В случае успешной компиляции, компилятор передает код завершения 0, иначе 1.
  42. ------------------------------------------------------------------------------
  43. Отличия от оригинала
  44. 1. Расширен псевдомодуль SYSTEM
  45. 2. В идентификаторах допускается символ "_"
  46. 3. Усовершенствован оператор CASE (добавлены константные выражения в
  47. метках вариантов и необязательная ветка ELSE)
  48. 4. Расширен набор стандартных процедур
  49. 5. Семантика охраны/проверки типа уточнена для нулевого указателя
  50. 6. Добавлены однострочные комментарии (начинаются с пары символов "//")
  51. 7. Разрешено наследование от типа-указателя
  52. 8. "Строки" можно заключать также в одиночные кавычки: 'строка'
  53. 9. Добавлен тип WCHAR
  54. 10. Добавлена операция конкатенации строковых и символьных констант
  55. 11. Добавлены кодовые процедуры
  56. 12. Возможен импорт модулей с указанием пути и имени файла
  57. 13. Добавлен специальный синтаксис для условной компиляции (см. CC.txt)
  58. 14. Имя процедуры в конце объявления (после END) необязательно
  59. 15. Разрешено использовать нижний регистр для ключевых слов
  60. ------------------------------------------------------------------------------
  61. Особенности реализации
  62. 1. Основные типы
  63. Тип Диапазон значений Размер, байт
  64. INTEGER -2147483648 .. 2147483647 4
  65. REAL 1.17E-38 .. 3.40E+38 4
  66. CHAR символ ASCII (0X .. 0FFX) 1
  67. BOOLEAN FALSE, TRUE 1
  68. SET множество из целых чисел {0 .. 31} 4
  69. BYTE 0 .. 255 1
  70. WCHAR символ юникода (0X .. 0FFFFX) 2
  71. 2. Максимальная длина идентификаторов - 255 символов
  72. 3. Максимальная длина строковых констант - 511 символов (UTF-8)
  73. 4. Максимальная размерность открытых массивов - 5
  74. 5. Процедура NEW заполняет нулями выделенный блок памяти
  75. 6. Локальные переменные инициализируются нулями
  76. 7. В отличие от многих Oberon-реализаций, сборщик мусора и динамическая
  77. модульность отсутствуют
  78. 8. Тип BYTE в выражениях всегда приводится к INTEGER
  79. 9. Контроль переполнения значений выражений не производится
  80. ------------------------------------------------------------------------------
  81. Псевдомодуль SYSTEM
  82. Псевдомодуль SYSTEM содержит низкоуровневые и небезопасные процедуры,
  83. ошибки при использовании процедур псевдомодуля SYSTEM могут привести к
  84. повреждению данных времени выполнения и аварийному завершению программы.
  85. PROCEDURE ADR(v: любой тип): INTEGER
  86. v - переменная или процедура;
  87. возвращает адрес v
  88. PROCEDURE SADR(x: строковая константа (CHAR UTF-8)): INTEGER
  89. возвращает адрес x
  90. PROCEDURE WSADR(x: строковая константа (WCHAR)): INTEGER
  91. возвращает адрес x
  92. PROCEDURE VAL(v: любой тип; T): T
  93. v - переменная;
  94. интерпретирует v, как переменную типа T
  95. PROCEDURE SIZE(T): INTEGER
  96. возвращает размер типа T
  97. PROCEDURE TYPEID(T): INTEGER
  98. T - тип-запись или тип-указатель,
  99. возвращает номер типа в таблице типов-записей
  100. PROCEDURE INF(): REAL
  101. возвращает специальное вещественное значение "бесконечность"
  102. PROCEDURE MOVE(Source, Dest, n: INTEGER)
  103. Копирует n байт памяти из Source в Dest,
  104. области Source и Dest не могут перекрываться
  105. PROCEDURE GET(a: INTEGER;
  106. VAR v: любой основной тип, PROCEDURE, POINTER)
  107. v := Память[a]
  108. PROCEDURE GET8(a: INTEGER;
  109. VAR x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
  110. Эквивалентно
  111. SYSTEM.MOVE(a, SYSTEM.ADR(x), 1)
  112. PROCEDURE GET16(a: INTEGER;
  113. VAR x: INTEGER, SET, WCHAR, SYSTEM.CARD32)
  114. Эквивалентно
  115. SYSTEM.MOVE(a, SYSTEM.ADR(x), 2)
  116. PROCEDURE GET32(a: INTEGER; VAR x: INTEGER, SET, SYSTEM.CARD32)
  117. Эквивалентно
  118. SYSTEM.MOVE(a, SYSTEM.ADR(x), 4)
  119. PROCEDURE PUT(a: INTEGER; x: любой основной тип, PROCEDURE, POINTER)
  120. Память[a] := x;
  121. Если x: BYTE или x: WCHAR, то значение x будет расширено
  122. до 32 бит, для записи байтов использовать SYSTEM.PUT8,
  123. для WCHAR -- SYSTEM.PUT16
  124. PROCEDURE PUT8(a: INTEGER;
  125. x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
  126. Память[a] := младшие 8 бит (x)
  127. PROCEDURE PUT16(a: INTEGER;
  128. x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
  129. Память[a] := младшие 16 бит (x)
  130. PROCEDURE PUT32(a: INTEGER;
  131. x: INTEGER, SET, BYTE, CHAR, WCHAR, SYSTEM.CARD32)
  132. Память[a] := младшие 32 бит (x)
  133. PROCEDURE CODE(hword1, hword2,... : INTEGER)
  134. Вставка машинного кода,
  135. hword1, hword2 ... - константы в диапазоне 0..65535,
  136. например:
  137. SYSTEM.CODE(0BF30H) (* wfi *)
  138. Также, в модуле SYSTEM определен тип CARD32 (4 байта). Для типа CARD32 не
  139. допускаются никакие явные операции, за исключением присваивания.
  140. Функции псевдомодуля SYSTEM нельзя использовать в константных выражениях.
  141. ------------------------------------------------------------------------------
  142. Оператор CASE
  143. Синтаксис оператора CASE:
  144. CaseStatement =
  145. CASE Expression OF Case {"|" Case}
  146. [ELSE StatementSequence] END.
  147. Case = [CaseLabelList ":" StatementSequence].
  148. CaseLabelList = CaseLabels {"," CaseLabels}.
  149. CaseLabels = ConstExpression [".." ConstExpression].
  150. Например:
  151. CASE x OF
  152. |-1: DoSomething1
  153. | 1: DoSomething2
  154. | 0: DoSomething3
  155. ELSE
  156. DoSomething4
  157. END
  158. В метках вариантов можно использовать константные выражения, ветка ELSE
  159. необязательна. Если значение x не соответствует ни одному варианту и ELSE
  160. отсутствует, то программа прерывается с ошибкой времени выполнения.
  161. ------------------------------------------------------------------------------
  162. Тип WCHAR
  163. Тип WCHAR добавлен в язык для удобной поддежки юникода. Для типов WCHAR и
  164. ARRAY OF WCHAR допускаются все те же операции, как для типов CHAR и
  165. ARRAY OF CHAR, за исключением встроенной процедуры CHR, которая возвращает
  166. только тип CHAR. Для получения значения типа WCHAR, следует использовать
  167. процедуру WCHR вместо CHR. Для правильной работы с типом, необходимо сохранять
  168. исходный код в кодировке UTF-8 с BOM.
  169. ------------------------------------------------------------------------------
  170. Конкатенация строковых и символьных констант
  171. Допускается конкатенация ("+") константных строк и символов типа CHAR:
  172. str = CHR(39) + "string" + CHR(39); (* str = "'string'" *)
  173. newline = 0DX + 0AX;
  174. ------------------------------------------------------------------------------
  175. Проверка и охрана типа нулевого указателя
  176. Оригинальное сообщение о языке не определяет поведение программы при
  177. выполнении охраны p(T) и проверки типа p IS T при p = NIL. Во многих
  178. Oberon-реализациях выполнение такой операции приводит к ошибке времени
  179. выполнения. В данной реализации охрана типа нулевого указателя не приводит к
  180. ошибке, а проверка типа дает результат FALSE. В ряде случаев это позволяет
  181. значительно сократить частоту применения охраны типа.
  182. ------------------------------------------------------------------------------
  183. Дополнительные стандартные процедуры
  184. COPY (x: ARRAY OF CHAR/WCHAR; VAR v: ARRAY OF CHAR/WCHAR);
  185. v := x;
  186. Если LEN(v) < LEN(x), то строка x будет скопирована
  187. не полностью
  188. LSR (x, n: INTEGER): INTEGER
  189. Логический сдвиг x на n бит вправо.
  190. MIN (a, b: INTEGER): INTEGER
  191. Минимум из двух значений.
  192. MAX (a, b: INTEGER): INTEGER
  193. Максимум из двух значений.
  194. BITS (x: INTEGER): SET
  195. Интерпретирует x как значение типа SET.
  196. Выполняется на этапе компиляции.
  197. LENGTH (s: ARRAY OF CHAR/WCHAR): INTEGER
  198. Длина 0X-завершенной строки s, без учета символа 0X.
  199. Если символ 0X отсутствует, функция возвращает длину
  200. массива s. s не может быть константой.
  201. WCHR (n: INTEGER): WCHAR
  202. Преобразование типа, аналогично CHR(n: INTEGER): CHAR
  203. ------------------------------------------------------------------------------
  204. Импорт модулей с указанием пути и имени файла
  205. Примеры:
  206. IMPORT Math IN "./lib/math.ob07"; (* относительно текущего модуля *)
  207. IMPORT M1 IN "C:\lib\math.ob07"; (* абсолютный путь *)
  208. ------------------------------------------------------------------------------
  209. Плавающая точка
  210. Компилятор предназначен для устройств на ядре Cortex-M3 и, возможно, после
  211. небольшой доработки, также для Cortex-M0. В таких микроконтроллерах нет
  212. встроенной поддержки плавающей точки, поэтому операции с вещественными числами
  213. одинарной точности эмулируются (модуль lib/STM32CM3/FPU.ob07). Компилятор
  214. подставляет вызовы процедур в месте операций с вещественными числами.
  215. Сохраняется возможность доработки компилятора в будущем для устройств со
  216. встроенной поддержкой вещественных чисел.
  217. ------------------------------------------------------------------------------
  218. Использование регистров общего назначения R0 - R12
  219. R0 - R3: регистровый стэк (промежуточные значения выражений),
  220. волатильные регистры (не требуют сохранения)
  221. R4 - R7: не используются компилятором, могут использоваться в кодовых
  222. процедурах, неволатильные (требуется сохранять перед
  223. использованием и восстанавливать после)
  224. R8 - R12: зарезервированы для возможного специального назначения в
  225. будущем
  226. ------------------------------------------------------------------------------
  227. Вызов процедур и кадр стэка
  228. Правила вызова похожи на соглашение cdecl (x86):
  229. - параметры передаются через стэк справа налево
  230. - результат, если есть, передается через регистр R0
  231. - вызывающая процедура очищает стэк
  232. Состояние стэка при выполнении процедуры:
  233. меньшие адреса <- |var3|var2|var1|LR|arg1|arg2|arg3| -> бОльшие адреса
  234. LR - сохраненный регистр LR (адрес возврата)
  235. argX - параметры в порядке объявления (слева направо)
  236. varX - локальные переменные в порядке использования в процедуре
  237. Размер каждого элемента в стэке (кроме локальных переменных структурных
  238. типов) - 1 машинное слово (4 байта). Структурные переменные (массивы и
  239. записи) занимают место в стэке в соответствии с их размером (с учетом
  240. выравнивания).
  241. Размещение локальных переменных зависит от их размеров и порядка
  242. использования, и в общем случае неопределенно. Если переменная не
  243. используется явно, то компилятор не выделяет для нее место в стэке.
  244. ------------------------------------------------------------------------------
  245. Скрытые параметры процедур
  246. Некоторые процедуры могут иметь скрытые параметры, они отсутствуют в списке
  247. формальных параметров, но учитываются компилятором при трансляции вызовов.
  248. Это возможно в следующих случаях:
  249. 1. Процедура имеет формальный параметр открытый массив:
  250. PROCEDURE Proc (x: ARRAY OF ARRAY OF REAL);
  251. Вызов транслируется так:
  252. Proc(LEN(x), LEN(x[0]), SYSTEM.ADR(x))
  253. 2. Процедура имеет формальный параметр-переменную типа RECORD:
  254. PROCEDURE Proc (VAR x: Rec);
  255. Вызов транслируется так:
  256. Proc(SYSTEM.TYPEID(Rec), SYSTEM.ADR(x))
  257. ------------------------------------------------------------------------------
  258. Кодовые процедуры
  259. Компилятор поддерживает процедуры, написаные в машинных кодах.
  260. Синтаксис:
  261. PROCEDURE "[code]" имя [ (параметры): ТипРезультата ]
  262. МашКом, МашКом,... МашКом;
  263. ";" после заголовка и END "имя" в конце процедуры не ставятся.
  264. МашКом - целочисленная константа [0..65535] (в том числе и константное
  265. выражение).
  266. Примеры:
  267. PROCEDURE [code] WFI
  268. 0BF30H; (* wfi *)
  269. (* сумма квадратов (a*a + b*b) -> r0 *)
  270. PROCEDURE [code] SqrSum (a, b: INTEGER): INTEGER
  271. 0B430H, (* push {r4, r5} *) (* сохранить все используемые регистры,
  272. кроме r0, r1, r2, r3 *)
  273. 09C02H, (* ldr r4, [sp, 8] *) (* r4 <- a *)
  274. 09D03H, (* ldr r5, [sp, 12] *) (* r5 <- b *)
  275. 04364H, (* muls r4, r4 *) (* r4 := r4 * r4 *)
  276. 0436DH, (* muls r5, r5 *) (* r5 := r5 * r5 *)
  277. 01960H, (* adds r0, r4, r5 *) (* r0 := r4 + r5; результат в r0 *)
  278. 0BC30H; (* pop {r4, r5} *) (* восстановить регистры *)
  279. Компилятор автоматически добавляет к такой процедуре команду возврата
  280. (bx LR). Способ передачи параметров и результата не изменяется. Регистр LR,
  281. при входе в процедуру не сохраняется.
  282. Чтобы использовать кодовые процедуры, необходимо импортировать псевдомодуль
  283. SYSTEM.
  284. ------------------------------------------------------------------------------
  285. Обработка прерываний
  286. При возникновении прерывания, будет вызван обработчик (если он объявлен).
  287. Объявление обработчика:
  288. PROCEDURE handler_name [iv]; (* процедура без параметров *)
  289. iv - целочисленная константа (константное выражение), номер вектора прерывания
  290. в таблице векторов, iv >= 2:
  291. 0 начальное значение SP
  292. 1 сброс
  293. ...
  294. 15 SysTick
  295. ...
  296. 59 TIM6
  297. 60 TIM7
  298. ...
  299. например:
  300. (* обработчик прерываний от TIM6 *)
  301. PROCEDURE tim6 [59];
  302. BEGIN
  303. (* код обработки *)
  304. END tim6;
  305. Также, можно объявить общий обработчик (iv = 0), который будет вызван, если
  306. не назначен индивидуальный. Общий обработчик получает параметр - номер вектора
  307. прерывания. По значению этого параметра, обработчик должен определить источник
  308. прерывания и выполнить соответствующие действия:
  309. PROCEDURE handler (iv: INTEGER) [0];
  310. BEGIN
  311. IF iv = 59 THEN
  312. (* TIM6 *)
  313. ELSIF iv = 60 THEN
  314. (* TIM7 *)
  315. ELSIF ....
  316. ....
  317. END
  318. END handler;
  319. ------------------------------------------------------------------------------
  320. Обработка ошибок
  321. В случае возникновения ошибки при выполнении программы, будет вызван
  322. пользовательский обработчик (если он объявлен). Перед вызовом обработчика,
  323. будут запрещены прерывания.
  324. Объявление обработчика ошибок:
  325. PROCEDURE trap (modNum, modName, err, line: INTEGER) [1];
  326. BEGIN
  327. END trap;
  328. где,
  329. modNum - номер модуля (в отчете о компиляции:
  330. compiling (modNum) "modName" )
  331. modName - адрес имени модуля
  332. err - код ошибки
  333. line - номер строки
  334. Коды ошибок:
  335. 1 ASSERT(x), при x = FALSE
  336. 2 разыменование нулевого указателя
  337. 3 целочисленное деление на неположительное число
  338. 4 вызов процедуры через процедурную переменную с нулевым значением
  339. 5 ошибка охраны типа
  340. 6 нарушение границ массива
  341. 7 непредусмотренное значение выражения в операторе CASE
  342. 8 ошибка копирования массивов v := x, если LEN(v) < LEN(x)
  343. 9 CHR(x), если (x < 0) OR (x > 255)
  344. 10 WCHR(x), если (x < 0) OR (x > 65535)
  345. 11 неявное приведение x:INTEGER к v:BYTE, если (x < 0) OR (x > 255)
  346. После возврата из обработчика, программа будет перезапущена.
  347. ------------------------------------------------------------------------------