Тем, кто боится перейти с 8 на 16 разрядов (PIC24/dsPIC33)
Добавлено: Пн янв 07, 2019 08:17:17
Обычно те, кто пишет на Си, достаточно полигамны в смысле выбора платформ МК. Поэтому сия тема не для них. Ну, во всяком случае, не специально для них.
Речь будет идти для тех, кто желает разобраться в архитектуре 16-разрядной платформы и начать писать простые программы на АСМе этой платформы.
Итак.
Пару слов о программной модели.
Вообще, очень хорошо все расписано в первой части специального мануала Микрочипа по программированию 16-разрядных МК этой фирмы:
http://ww1.microchip.com/downloads/en/D ... 00157g.pdf
Рискну изложить коротко и на русском языке.
1. Платформа делится на PIC24 и dsPIC. Они отличаются наличием/отсутствием DSP-ядра и ряда команд связанных с этим ядром, а так же еще некоторых фич, которые будут упомянуты в дальнейшем. В остальном система команд и программная модель полностью идентичны.
2. Длина команды - 24 бита, в которых 8 бит занимает код операции, а остальное связано с адресацией операндов.
3. Счетчик команд - 23 бита. Это значит, что возможна адресация программной памяти размером 4М*24 (4М инструкций). Естественно, что физически реализована лишь малая часть этого адресного пространства. Счетчик команд всегда четный (0, 2, 4 ...). Нечетные адреса занимают старшие байты команд. Нечетная адресация возможна лишь при байтном чтении программной памяти. Попытка чтения 16 битного слова из нечетного адреса программного флеша вызывает ошибку с переходом по вектору обработки этой ошибки. Очень полезно при отладке. Подробнее - позже.
Код исполняется только из программной памяти. Это чисто гарвардская архитектура. В новейших двухядерных МК этой платформы второе ядро исполняет код из PRAM - программной ОЗУ. Но эта ОЗУ не имеет отношения к ОЗУ данных.
Все команды обработки данных исполняются в один цикл, кроме деления. Деление исполняется в 18 циклов. Команды переходов и ветвления (связанные с конвейером) исполняются более, чем 1 цикл. Команды чтения из флеша могут исполнятся более, чем за 1 цикл. Это связано с организацией шин в конкретном семействе платформы.
4. Длина данных - 16 бит. Адресное данных пространство ОДНОБАЙТНОЕ. Четные адреса - младшие байты 16-разрядных слов, нечетные адреса - старшие байты. Часть команд могут быть байтными.
5. Адресное пространство данных позволяет адресовать 64К байт (32К слов), но есть страничная адресация, позволяющая расширить это пространство (EDS). А так же есть PSV - видимость младших двух байт программной памяти в адресном поле данных. Это дает возможность формирования таблиц во флеше с обращением к ним как к ОЗУ.
6. Ядро содержит 16 регистров общего назначения (РОНов), два из которых загружена функциями ядра (W14 и W15). РОНы попарно образуют 32-разрядные слова в части арифметических операций (умножение и деление). РОНы так же используются для косвенной адресации.
7. Адресация операндов указывается в команде (инструкции). Адресация команд бывает:
- безадресная (типа nop)
- непосредственная (операнд в команде - константа) add #20, W0 (W0=W0+20)
- прямая (адрес операнда в команде) inc temp (temp=temp+1)
- косвенная (адрес операнда в РОНе) mov [W0], W1 (содержимое в ОЗУ с адресом в W0 копируется в W1)
Косвенная адресация бывает:
- без модификации указателя (содержимого РОНа) [W0]
- пост автоинкрементная [W1++]
- пост автодекрементная [W1--]
- пре автоинкрементная [++W1]
- пре автодекрементная [--W1]
- со смещением на константу [W2+26]
- индексная (со смещением на переменную) [W0+W7]
DSP команды в dsPIC имеют ограниченное число видов адресаций. Но устраивающих задачи специфические для этих команд.
Так же есть AGU (модуль генерации адресов) реализующий:
- модульная адресация (организована через специальные регистры указатели окна), когда косвенная адресация оказывается кольцевой в этом окне адресов.
- битреверсная адресация (специфическая адресация для FFT (быстрого преобразования Фурье)
8. Стек реализован с помощью указателя стека (вершины стека) расположенного в W15 и регистра SPLIM - контролирующего выход стека за обозначенный в нем предел адреса - вызывает обработчик ошибки стека. Удобно при отладке.
Эти регистры обязаны быть инициализированы в начале программы, если предполагается использовать стек, естественно.
9. Локальный стек (фрейм) позволяет при входе в вызов (call или прерывание) открывать указатели на локальные переменные. Эти указатели размещены сразу за вершиной стека. Указатель локального стека размещен в W14. При входе в вызов локальный стек объявляется командой lnk #N . При выходе из вызова локальный стек закрывается командой ulnk . Это Си ориентированный механизм определения локальных переменных.
10. Регистры ядра:
Все РОНы W0...W15, из них W0...W3 имеют шадоу-стек загружаемый/выгружаемый в один цикл безоперандными командами push.s/pop.s. Этими же командами в тот же шадоу-стек сохраняется весь контекст из STATUS регистра. Понятно, что с этих команд начинается и заканчивается любой обработчик прерываний.
SPLIM - ограничитель стека
STATUS - регистр состояний ядра
PC - программный счетчик
RCOUNT - счетчик команды repeat - однокомандный цикл
DCOUNT - счетчик команды do - многокомандный цикл (только в dsPIC)
DOSTART - стартовый адрес команды do (только в dsPIC)
DOEND - конечный адрес команды do (только в dsPIC)
CORCON - регистр управления ядром
TBLPAG - страница табличного доступа
PSVPAG - страница доступа к флешу
DSWPAG - страница расширенного адреса при записи
DSRPAG - страница расширенного адреса при чтении
Пока все. Продолжение следует.
Речь будет идти для тех, кто желает разобраться в архитектуре 16-разрядной платформы и начать писать простые программы на АСМе этой платформы.
Итак.
Пару слов о программной модели.
Вообще, очень хорошо все расписано в первой части специального мануала Микрочипа по программированию 16-разрядных МК этой фирмы:
http://ww1.microchip.com/downloads/en/D ... 00157g.pdf
Рискну изложить коротко и на русском языке.
1. Платформа делится на PIC24 и dsPIC. Они отличаются наличием/отсутствием DSP-ядра и ряда команд связанных с этим ядром, а так же еще некоторых фич, которые будут упомянуты в дальнейшем. В остальном система команд и программная модель полностью идентичны.
2. Длина команды - 24 бита, в которых 8 бит занимает код операции, а остальное связано с адресацией операндов.
3. Счетчик команд - 23 бита. Это значит, что возможна адресация программной памяти размером 4М*24 (4М инструкций). Естественно, что физически реализована лишь малая часть этого адресного пространства. Счетчик команд всегда четный (0, 2, 4 ...). Нечетные адреса занимают старшие байты команд. Нечетная адресация возможна лишь при байтном чтении программной памяти. Попытка чтения 16 битного слова из нечетного адреса программного флеша вызывает ошибку с переходом по вектору обработки этой ошибки. Очень полезно при отладке. Подробнее - позже.
Код исполняется только из программной памяти. Это чисто гарвардская архитектура. В новейших двухядерных МК этой платформы второе ядро исполняет код из PRAM - программной ОЗУ. Но эта ОЗУ не имеет отношения к ОЗУ данных.
Все команды обработки данных исполняются в один цикл, кроме деления. Деление исполняется в 18 циклов. Команды переходов и ветвления (связанные с конвейером) исполняются более, чем 1 цикл. Команды чтения из флеша могут исполнятся более, чем за 1 цикл. Это связано с организацией шин в конкретном семействе платформы.
4. Длина данных - 16 бит. Адресное данных пространство ОДНОБАЙТНОЕ. Четные адреса - младшие байты 16-разрядных слов, нечетные адреса - старшие байты. Часть команд могут быть байтными.
5. Адресное пространство данных позволяет адресовать 64К байт (32К слов), но есть страничная адресация, позволяющая расширить это пространство (EDS). А так же есть PSV - видимость младших двух байт программной памяти в адресном поле данных. Это дает возможность формирования таблиц во флеше с обращением к ним как к ОЗУ.
6. Ядро содержит 16 регистров общего назначения (РОНов), два из которых загружена функциями ядра (W14 и W15). РОНы попарно образуют 32-разрядные слова в части арифметических операций (умножение и деление). РОНы так же используются для косвенной адресации.
7. Адресация операндов указывается в команде (инструкции). Адресация команд бывает:
- безадресная (типа nop)
- непосредственная (операнд в команде - константа) add #20, W0 (W0=W0+20)
- прямая (адрес операнда в команде) inc temp (temp=temp+1)
- косвенная (адрес операнда в РОНе) mov [W0], W1 (содержимое в ОЗУ с адресом в W0 копируется в W1)
Косвенная адресация бывает:
- без модификации указателя (содержимого РОНа) [W0]
- пост автоинкрементная [W1++]
- пост автодекрементная [W1--]
- пре автоинкрементная [++W1]
- пре автодекрементная [--W1]
- со смещением на константу [W2+26]
- индексная (со смещением на переменную) [W0+W7]
DSP команды в dsPIC имеют ограниченное число видов адресаций. Но устраивающих задачи специфические для этих команд.
Так же есть AGU (модуль генерации адресов) реализующий:
- модульная адресация (организована через специальные регистры указатели окна), когда косвенная адресация оказывается кольцевой в этом окне адресов.
- битреверсная адресация (специфическая адресация для FFT (быстрого преобразования Фурье)
8. Стек реализован с помощью указателя стека (вершины стека) расположенного в W15 и регистра SPLIM - контролирующего выход стека за обозначенный в нем предел адреса - вызывает обработчик ошибки стека. Удобно при отладке.
Эти регистры обязаны быть инициализированы в начале программы, если предполагается использовать стек, естественно.
9. Локальный стек (фрейм) позволяет при входе в вызов (call или прерывание) открывать указатели на локальные переменные. Эти указатели размещены сразу за вершиной стека. Указатель локального стека размещен в W14. При входе в вызов локальный стек объявляется командой lnk #N . При выходе из вызова локальный стек закрывается командой ulnk . Это Си ориентированный механизм определения локальных переменных.
10. Регистры ядра:
Все РОНы W0...W15, из них W0...W3 имеют шадоу-стек загружаемый/выгружаемый в один цикл безоперандными командами push.s/pop.s. Этими же командами в тот же шадоу-стек сохраняется весь контекст из STATUS регистра. Понятно, что с этих команд начинается и заканчивается любой обработчик прерываний.
SPLIM - ограничитель стека
STATUS - регистр состояний ядра
PC - программный счетчик
RCOUNT - счетчик команды repeat - однокомандный цикл
DCOUNT - счетчик команды do - многокомандный цикл (только в dsPIC)
DOSTART - стартовый адрес команды do (только в dsPIC)
DOEND - конечный адрес команды do (только в dsPIC)
CORCON - регистр управления ядром
TBLPAG - страница табличного доступа
PSVPAG - страница доступа к флешу
DSWPAG - страница расширенного адреса при записи
DSRPAG - страница расширенного адреса при чтении
Пока все. Продолжение следует.