реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Привязка структур к аппаратуре
Dog Pawlowa
сообщение Feb 19 2008, 16:09
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Обычный С.
В системе есть несколько идентичных узлов (управление температурой, двигатели), описываемых структурами переменных. Стоит задача сокращения текста программы. Вариантов три - макросы, функции и их комбинации.

Вначале сделал вариант с макросами, и он работает

Код
#define MOTOR_SERVICE(OBJ, MOT)                        \
    if (!OBJ##.time)                                 \
        {        PWM##MOT=PWM_TOP+1; HIGH_MODE##MOT;        \
                OBJ##.state=moSTOPPED;                \
        }                                    \
    else     {    if (OBJ##.speed==0)                         \
                    {    PWM##MOT=PWM_TOP+1; HIGH_MODE##MOT;    \
ну и так далее...

В этом макросе параметры - имя структуры и номер, который служит для обращения к нужным портам через другие макросы.

Но у макросов есть недостатки:
- трудность отладки (в отладчике IAR в этом случае нет привязки к строкам кода С)
- трудности привязки ошибки компиляции к месту в макросе
- ну и размер кода, конечно.

Хотелось бы использовать функции с параметром указателя на структуру, причем чтобы и работа с портами легко укладывалась в этот стройный подход.
Вопрос - как это сделать красиво, если там разные входы, выходы, и собственно сами регистры.
Добавить с структуру указатели на функции? Добавить в параметры функции индекс, который использовать для выбора функций работы с портами из массива, как в примере макроса?
Может, что-то еще?


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
prottoss
сообщение Feb 19 2008, 16:32
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Цитата(Dog Pawlowa @ Feb 19 2008, 23:09) *
Может, что-то еще?
Перейти на С++


--------------------
Go to the top of the page
 
+Quote Post
KRS
сообщение Feb 19 2008, 20:17
Сообщение #3


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Dog Pawlowa @ Feb 19 2008, 19:09) *
Хотелось бы использовать функции с параметром указателя на структуру, причем чтобы и работа с портами легко укладывалась в этот стройный подход.

С указателем на порт в общем случае IMHO не получится - во первых таймеры разные и могут быть биты в разных местах, доступ к порту через указатель часто не оптимален.
Хотя если указатель на PWM регистр можно его рассматривать как указатель на volatile (главное если 16 бит по байтам писать в нужном порядке). Но доступ к GPIO особенно на уровне бит будет кривой совсем.

Я реализовывал как и у вас через макросы! и ##


Цитата(prottoss @ Feb 19 2008, 19:32) *
Перейти на С++

Есть и такой вариант использовать template
главное что бы компилер не глючил!
Go to the top of the page
 
+Quote Post
singlskv
сообщение Feb 19 2008, 20:56
Сообщение #4


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(KRS @ Feb 19 2008, 23:17) *
С указателем на порт в общем случае IMHO не получится - во первых таймеры разные и могут быть биты в разных местах, доступ к порту через указатель часто не оптимален.
Хотя если указатель на PWM регистр можно его рассматривать как указатель на volatile (главное если 16 бит по байтам писать в нужном порядке). Но доступ к GPIO особенно на уровне бит будет кривой совсем.
ИМХО, все это зависит от конкретного проца и от конкретной задачи,
Если речь об управляющих регистрах, и биты попутаны местами то там и макросы не очень...,
а если речь о регулярных регистрах(там где задается значение в 16ричном виде), там вариантов
масса, например массивы адресов регистров и к примеру масок для них.
Только все равно, по хорошему, для таких вариантов нужно четко определять volatile доступ
к таким адресам, и проще всего это сделать через макросы.
Вобщем, ИМХО, нужно видеть задачу что бы сказать как будет выгоднее.
Go to the top of the page
 
+Quote Post
KRS
сообщение Feb 19 2008, 21:18
Сообщение #5


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Есть еще вариант использовать
#pragma inline=forced
примерно так
Код
#pragma inline=forced
void Action(unsigned num,val)
{
  counter[num]=val;
  .....
  
  if (num==0) PORTA|=1;
  else if (num==1) PORTA|=2;
  else if (num==2) PORTB|=4;
  
  pos[num] =....


  if (stop[num]) {
    if (num==0) PORTA&=~1;
    else if (num==1) PORTA&=~2;
    else if (num==2) PORTB&=~4;
  }
}

т.е. там где доступ к регистрам переферии использовать тупо перебор if elseif... т.к. функция всегда инлайн все if оптимизатор уберет и код будет оптимален
Go to the top of the page
 
+Quote Post
singlskv
сообщение Feb 19 2008, 21:41
Сообщение #6


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(KRS @ Feb 20 2008, 00:18) *
Есть еще вариант использовать
.......
т.е. там где доступ к регистрам переферии использовать тупо перебор if elseif... т.к. функция всегда инлайн все if оптимизатор уберет и код будет оптимален
Такой вариант получается очень процессорозависимым, те при переходе
на новый проц придется пересмотреть все функции в которых это встречается.

Хотя я например использую оба варианта, и спец быстрые функции для доступа к конкретным
портам/битам когда нужно очень быстро, и абстрактные массивы из пар (адрес порта, маска)
когда нужно много и переносимость значит чуть больше чем скорость...
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Feb 20 2008, 07:11
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(KRS @ Feb 20 2008, 01:18) *
Есть еще вариант использовать
#pragma inline=forced
примерно так

Да, ночью мне вместо таблицы Менделеева и бутылки водки inline приснился smile.gif Как средство восстановления быстродействия, поскольку мои мысли крутятся вокруг использования массива указателей на функции:

Код
void SetPosSpeed1(void)        {    OCR1AL=PWM_TOP - last_speed1 - (last_speed1>>1);            }
void SetPosSpeed2(void)        {    OCR1BL=PWM_TOP - last_speed2 - (last_speed2>>1);            }
PROCEDURE        SetPosSpeed[2]=    {    SetPosSpeed1,    SetPosSpeed2};

void MoService( char i)
{ mo_type * mop=tm[i-1];  // pointer to structure
  ...
  SetPosSpeed[i]();   // call hardware support function by index of "object"
  ...
}

Только я не уверен, что IAR проглотит inline для функции, вызываемой по индексу из массива. Не будет получаться - попробую Ваш вариант.

Я помню, у меня были проблемы с индивидуальным inline и какими-то общими установками проекта в IAR, я даже писал про это здесь, на форуме.

Цитата(singlskv @ Feb 20 2008, 01:41) *
Такой вариант получается очень процессорозависимым, те при переходе
на новый проц придется пересмотреть все функции в которых это встречается.

Это часть фактически описывает подключение оборудования к конкретным ножкам конкретного контроллера, тут и невозможно сделать процессорно-независимо.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
KRS
сообщение Feb 20 2008, 07:23
Сообщение #8


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Dog Pawlowa @ Feb 20 2008, 10:11) *
Только я не уверен, что IAR проглотит inline для функции, вызываемой по индексу из массива. Не будет получаться - попробую Ваш вариант.

Указатель на inline=forced функцию нельзя получить это практически тоже самое что и макрос.
Надо массив на свитч заменить.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Feb 20 2008, 07:29
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(KRS @ Feb 20 2008, 11:23) *
Указатель на inline=forced функцию нельзя получить это практически тоже самое что и макрос.
Надо массив на свитч заменить.

Ага, это я размечтался.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Feb 20 2008, 09:47
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(KRS @ Feb 20 2008, 11:23) *

Проверил, вроде все работает. Главное - не забыть включить оптимизацию , иначе inline игнорируется. И это хорошо, потому что иначе трудно отладиться - в окне дизассемблера при полной оптимизации привязка к строкам исходного текста отсутствует.
Итого - достоинство по сравнению с макросами
- более читаемый текст,
- управление кодом с помощью оптимизации.
Спасибо.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 19:59
Рейтинг@Mail.ru


Страница сгенерированна за 0.0146 секунд с 7
ELECTRONIX ©2004-2016