Перейти к содержанию
    

Разные стили .h файлов описания аппаратуры в STM32 и GigaDevice.

2 часа назад, VladislavS сказал:
for(;;) {
  GPIOA->ODR ^= (1 << 5);
  GPIOC->ODR ^= (1 << 5) | (1 << 8) | (1 << 9);
  delay();
}

Вот если бы его класс сам делал подобную оптимизацию (а это на плюсах, в отличи от си возможно), то тогда и можно было засчитывать победу.

... то C++ от такой "оптимизации" тупо сел бы в лужу, ибо это два разных кода, не находите?

for(;;) {
  GPIOA->ODR ^= (1 << 5);
  GPIOC->ODR ^= (1 << 5);
  GPIOC->ODR ^= (1 << 8);
  GPIOC->ODR ^= (1 << 9);
  delay();
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Arlleex сказал:

то C++ от такой "оптимизации" тупо сел бы в лужу, ибо это два разных кода, не находите?

Не нахожу. Код автора статьи (без delay, он тут ни на что не влияет) я бы написал так.

using LEDS = PinList<PA_5,PC_5,PC_8,PC_9>;

for(;;) LEDS::toggle();

Что для STM32 в процессе компиляции превратиться во что-то такое

for(;;)
{
  // PA5 toggle
  if (GPIOA->ODR & (1<<5))  
    *((volatile uint16_t *)&GPIOA->BSRR+1) = (1<<5);
  else
    GPIOA->BSRR = (1<<5);
  // PC5,PC8,PC9 toggle
  GPIOC->BSRR = (((1<<5)|(1<<8)|(1<<9)) << 16) 
              | (~GPIOC->ODR & ((1<<5)|(1<<8)|(1<<9)));
}

Естественно не в ODR ^=, ибо это неправильно. Ну и из-под ARM Compiler v6 будет как-то так

       MOVS          r0,#0x14
       MOVW          r2,#0x320
       MOVW          r3,#0x818
       MOVT          r0,#0x4800     // R0 = &GPIOA->ODR
       MOV           r12,#0x20
       MOVT          r2,#0x320
       MOVT          r3,#0x4800     // R3 = &GPIOC->BSRR

main:  
// if (GPIOA->ODR & (1<<5))
       LDR           r1,[r0,#0x00]
       LSLS          r1,r1,#26
       ITE           PL
// GPIOA->BSRR = (1<<5)	   
       STRPL         r12,[r0,#0x04]
// *((volatile uint16_t *)&GPIOA->BSRR+1) = (1<<5);	   
       STRHMI        r12,[r0,#0x06]

// GPIOC->BSRR = (((1<<5)|(1<<8)|(1<<9)) << 16) | (~GPIOC->ODR & ((1<<5)|(1<<8)|(1<<9)));
       LDR           r1,[r0,#0x800]
       AND           r1,r1,#0x320
       EORS          r1,r1,r2
       STR           r1,[r3,#0x00]

       B             main

И никто в лужу не сел, как ни странно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

GPIOC->ODR ^= (1 << 5) | (1 << 8) | (1 << 9);

!=

GPIOC->ODR ^= (1 << 5);
GPIOC->ODR ^= (1 << 8);
GPIOC->ODR ^= (1 << 9);

и упаси Господь, если бы оптимизация сводила второе к первому.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задача - помигать четырьмя диодами, приведёнными в списке. На С вы решаете сами первым или вторым способом её решать. А на С++ я просто говорю "переключи состояние всех диодов из списка". Есественно, заменить первое<=>второе он не имеет права. Но сформировать одну операцию вместо трёх для решения задачи на этапе компиляции и есть джедайство.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Эммм.. Вы спорте о том, как лучше ногами дрыгать? Я бы ещё понял, если бы разбирали какие-то архивысокие материи. Но это?... 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда о чем? О том, как написать пицот погдготовительных строк, а в итоге получить ровно то же самое, что и непосредственная запись в одну строку? 

Зачем спорить об инструментах? Давно уже ясно, что и как работает. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 минут назад, EdgeAligned сказал:

Тогда о чем?

Об ошибочном заключении, что автор статьи получил сложным способом тот же результат и поэтому делать так не имеет смысла. Имеет, просто надо более сильное кунг-фу использовать, тогда результат будет лучше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 минут назад, EdgeAligned сказал:

а в итоге получить ровно то же самое, что и непосредственная запись в одну строку?

А потом перекинуть один из светодиодов на другой порт. И сравнить - сколько времени программиста займет такое перекидывание.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Которое в принципе даст снова то же самое. Ценой бОльшего кол-ва подготовительных портянок. Я все это, как вы изволили выразиться, кунг-фу знаю, посему и говорю, что ну не там и не для того оное. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, VladislavS сказал:

Но сформировать одну операцию вместо трёх для решения задачи на этапе компиляции и есть джедайство.

Ну а откуда у компилятора будет право смешать volatile-доступы в один? На это он не имеет право, либо ему об этом нужно как-то явно сказать. Причем так явно, чтобы это было видно программисту при первом взгляде на исходник. Какой пример написал автор статьи - его дело, но раз он написал последовательные обращения к GPIOC, пусть они и останутся последовательными, а никак не оптимизированными.

Я прекрасно понимаю, где Ваш замысел был бы весьма уместен. Например, у меня бывает так, что нужно перепаковывать биты портов в структуры обмена. Разумеется, там все хитросплетено. Если это делать Си-шными макросами, то для универсальности каждый описанный пин повлечет за собой программный доступ к соответствующему регистру, что есть неоптимальность. Поэтому приходится руками сначала считать все нужные регистры 1 раз, а затем по ним работать макросами. Но и там есть свои неудобства, когда какой-то пин переезжает куда-то или целая группа. Да и оптимизировать групповое выделение битов проблематично - чтобы, например, учитывать, что при "переезде" бита с одного порта на другой, тот образовал пару с несколькими другими и их можно объединить одной инструкцией UBFX, например. Вот здесь C++ был бы очень полезен (хотя я детально не знаю как это сделать) - пусть на вход некому шаблону давали список считанных volatile-регистров, а он уже знал, где какой бит есть и как их максимально оптимально перетасовать. Где-то была даже статья, где метадвижок проходился сначала по списку портов, потом по списку пинов, выявлял смежные пины и т.д.

И то... Необходимость в таком шаблоне возникла лишь вследствие создания дюжины одинаковых по сути устройств, но разного исполнения по разводке печатной платы и конкретного типа МК. Будь оно такое одно, все эти чтения и перетасовка пинов сделались бы руками по мере написания соотв. драйвера.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 минут назад, Arlleex сказал:

Ну а откуда у компилятора будет право смешать volatile-доступы в один?

Он их не совмещает, а изначально формирует так как вы описали во втором абзаце вашего сообщения.

12 минут назад, Arlleex сказал:

Причем так явно, чтобы это было видно программисту при первом взгляде на исходник.

Зачем? При взгляде на исходник должно быть видно ЧТО делает код, а не КАК. Часто вы кишки printf изучаете при его использовании?

12 минут назад, Arlleex сказал:

Какой пример написал автор статьи - его дело, но раз он написал последовательные обращения к GPIOC, пусть они и останутся последовательными, а никак не оптимизированными.

При такой постановке задачи и результата ноль. И выводы ложные. А реальная задача автора "мигать списком диодов".

12 минут назад, Arlleex сказал:

Например, у меня бывает так, что нужно перепаковывать биты портов в структуры обмена.

Ну это оно и есть. 

12 минут назад, Arlleex сказал:

где метадвижок проходился сначала по списку портов, потом по списку пинов, выявлял смежные пины и т.д.

Именно так и делается. Именно поэтому нет совмещения volatile, а есть их оптимальное формирование.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...