|
Порт как параметр функции С/С++ IAR |
|
|
|
Sep 6 2012, 10:17
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 14-04-09
Пользователь №: 47 659

|
Собственно вопрос по теме сабжа: как передать имя порта (или любой другой регистр) как параметр в функцию/класс С++ ? Пишу программный драйвер интерфейса, создал под это дело класс обертку и хочу конфигурировать интерфейс (назначать ноги МК), чтобы можно было поднять несколько интерфейсов параллельно на разных ногах, создав несколько объектов. Пробовал вот так: Код void foo (unsigned char PORTx) { *(unsigned char*)PORTx=0xFF; }
void main(void) { foo(PORTA); } такой вариант не работает.... и компилятор ругается на строку вызова функции: Код Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
|
|
|
|
|
Sep 6 2012, 10:30
|
Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123

|
Как обычный указатель. Код void foo (volatile unsigned char * PORTx) { *PORTx=0xFF; }
void main(void) { foo( & PORTA); } В этом случае компилятор при работе с портом будет использовать команды LD/ST - которые занимают два такта. И не сможет использовать команды in,out, которые один такт и sbi,cbi, которые за один такт модифицируют значение одного бита в порту. Плюс еще надо будет передавать указатель на регистры DDRx и PINx. Для начала хватит, но есть и более интересный способ...
|
|
|
|
|
Sep 6 2012, 10:37
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 14-04-09
Пользователь №: 47 659

|
char * __io или char *__ext_io
В чем разница?
|
|
|
|
|
Sep 6 2012, 10:45
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 14-04-09
Пользователь №: 47 659

|
я так понимаю что вы предлагает сделать вот так: Код void foo (char* __io Portx) { Portx=0xFF; }
foo(PORTA); если так - не работает Error[Be009]: memory attributes not allowed on auto variables or parameters Цитата Как обычный указатель. Работает, но меня смущает, что компилятор не использует in/out инструкции
|
|
|
|
|
Sep 6 2012, 10:47
|
Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123

|
Цитата(Непомнящий Евгений @ Sep 6 2012, 14:34)  neiver, а разве там все регистры мапятся в общее адресное пространство? Вроде бы __io не мапились... Мапятся. Даже регистры общего назначения r0-r31 мапятся начиная с адреса 0. Начиная с адреса 0x20 мапятся обычные IO регистры, следом расширенные.
|
|
|
|
|
Sep 6 2012, 10:58
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 14-04-09
Пользователь №: 47 659

|
Код void classname::init(volatile unsigned char * PORTx) ??init: CFI Block cfiBlock0 Using cfiCommon0 CFI Function ??init // 6 { // 7 *PORTx=0xFF; LDI R16, 255 MOV R30, R17 ST Z, R16 // 8 } RET CFI EndBlock cfiBlock0
RSEG CODE:CODE:NOROOT(1) не ссорьтесь, мапится и работает. но все-таки хочется, чтобы через "out" заработало. neiver, а можно поподробнее : Цитата но есть и более интересный способ...
|
|
|
|
|
Sep 6 2012, 11:05
|
Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123

|
Если хочется чтоб через in,out,sbi,cbi работало - у меня есть библиотечка "для работы с портами". С её помощью порты, отдельные пины и произвольные группы пинов можно передавать как шаблонные параметры функций и классов: Код template<class Port> void Foo() { Port::SetConfiguration(Port::Out); Port::Write(0xff); }
template<class Pin> void Bar() { Pin::Set(); ... Pin::Clear(); }
template<class PinGroup> void Buzz() { PinGroup::SetConfiguration(Port::Out); PinGroup::Write(0xff); }
int main() { Foo<IO::Porta>(); Bar<IO::Pa1>();
typedef IO::PinList<IO::Pa1, IO::Pa2, IO::Pb3, IO::Pb2> MyPinGroup; Buzz<MyPinGroup>(); } Тут тестовый пример для IAR AVR
|
|
|
|
|
Sep 6 2012, 12:07
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 14-04-09
Пользователь №: 47 659

|
Цитата А как вы себе представляете это хотя бы на ассемблере? Адрес регистра находится в коде команды out, как функция сможет его заменить? Имелся ввиду другой вариант реализации. Насколько я понял из представленных сдесь вариантов, простого и прозрачного способа реализации этой задачи нет, кроме как использовать указатель (с вытекающими накладными расходами).
|
|
|
|
|
Sep 6 2012, 12:12
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(Errorkpi @ Sep 6 2012, 14:45)  я так понимаю что вы предлагает сделать вот так: У ИАРа кривоватая реализация. void foo (unsigned char volatile __io * adr) - работает
|
|
|
|
|
Sep 6 2012, 12:22
|
Участник

Группа: Участник
Сообщений: 41
Регистрация: 14-04-09
Пользователь №: 47 659

|
Цитата(Непомнящий Евгений @ Sep 6 2012, 15:12)  У ИАРа кривоватая реализация.
void foo (unsigned char volatile __io * adr) - работает Неа Error[Ta034]: __io pointer/reference is not allowed. И даже попытка объявить эту переменную как член класса тоже не получится.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|