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

Keil uVision. Баги, приколы, подводные камни

13 часов назад, Sidoroff сказал:

переменную типа 'float' через звездочку из невыровненного указателя, то проц виснет

Вы почитайте документ ARMv7-M Аrchitecture Refrence Manual, главу А2.5.4, конкретно Floating-point single precision format, последнее предложение перед рисунком. Что там сказано про выравнивание данных такого типа?

И при чем тут компилятор? Он делае ровно то, что вы ему написали. А корректность написанного на совести программиста.

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


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

1 hour ago, Darth Vader said:

Вы почитайте документ ARMv7-M Аrchitecture Refrence Manual, главу А2.5.4, конкретно Floating-point single precision format, последнее предложение перед рисунком. Что там сказано про выравнивание данных такого типа?

И при чем тут компилятор? Он делае ровно то, что вы ему написали. А корректность написанного на совести программиста.

К сожалению, пока это все почитаешь и запомнишь, постареешь и помрешь.

Поэтому как все, пока не наткнешся...

Кстати при эмуляции float все работает, пофиг на выравнивание. Никогда не понимал, почему компиляторы С не

делают любое выравнивание автоматически, пусть и с потерей производительности. Как по мне лучше медленно но правильно.

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


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

38 минут назад, Sidoroff сказал:

Никогда не понимал, почему компиляторы С не

делают любое выравнивание автоматически, пусть и с потерей производительности.

Наверное потому что вы не указали ему это сделать?

38 минут назад, Sidoroff сказал:

Как по мне лучше медленно но правильно.

Правильно: читать мануал, и только потом садиться за написание ПО. А не наоборот.

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


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

4 minutes ago, jcxz said:

вы не указали ему это сделать?

И как это указать? Имеется в  виду глобально, не директивами перед каждой переменной.

 

 

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


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

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

И как это указать? Имеется в  виду глобально, не директивами перед каждой переменной.

В Кейле - без понятия. А в IAR - создать пакованный тип:

typedef __packed float floatP8;

Его и использовать.

 

PS: Но лучше научиться писать код так, чтобы этого не требовалось.

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


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

3 часа назад, Sidoroff сказал:

Никогда не понимал, почему компиляторы С не

делают любое выравнивание автоматически, пусть и с потерей производительности

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

char - выравнивается по границе 1 байта (т.е. специально не выравнивается никак)

short - выравнивается по границе 2 байт

long, int, float - выравниваются по границе 4 байт.

Так что где бы вы в программе не объявили переменные: 

float a; int b;

a, b гарантированно всегда будут расположены в памяти по адресам, кратным 4 байтам. Умный компоновщик позаботится об этом. Он это гарантирует.

А если вы считаете себя умнее компоновщика и решили поиграться с приведением указателей:

char c;

float a = *(float*)&c;

то все последствия на вашей совести. Вы сами должны обеспечить корректность такой операции.

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


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

В Keil с ARM Compiler 6 есть нечто подобное IAR-овскому "Multi-file Compilation"? В ARMCC, вроде, было, а вот в LLVM не могу найти...

P.S. Получается, это LTO.

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


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

ARM Compiler 6.16, оптимизация balanced, LTO включен.

Сглаживаю аппаратные особенности STM-ных МК: конкретно - реализую механизм разделения совмещенных обработчиков прерываний периферии. Да да, спасибо ST за любезно предоставленные костыли в виде TIM1_UP_TIM10_IRQHandler(), TIM6_DAC_IRQHandler() и т.д. при том, что ничего не мешало повесить прерывания на раздельные вектора:negative: Из-за этого ломается подход к написанию драйверов периферии - я стремлюсь к тому, чтобы драйвер, работающий, например, только с TIM1, не имел внутри кода, работающего с TIM10. Потому что драйверы становятся созависимыми.

Решение такое. Создаю промежуточный isr_splitter.c

void TIM6_DAC_IRQHandler(void) {
  __attribute__((weak)) void TIM6_IRQHandler(void);
  __attribute__((weak)) void DAC_IRQHandler(void);
  
  TIM6_IRQHandler();
  DAC_IRQHandler();
}


Слабые символы линковки очень помогают: если какой-то драйвер использует прерывания по TIM6, он определяет обработчик TIM6_IRQHandler() {} и при линковке будет действительный вызов этой функции из обобщенного TIM6_DAC_IRQHandler(). Если обработчика нет (ну, не нужна никому эта периферия), то и вызова не будет, и даже ошибки линковки. Ну, это тут все итак прекрасно понимают.

Так вот, что напрягает: по умолчанию, когда никаких обработчиков нигде не определено, каждая строчка вызова заменяется инструкцией NOP.W. Сколько бы там этих вызовов не было - каждый заменится на NOP.W. Если идентификатор какой-то функции стал "сильным" символом (обработчик определили), то, естественно, NOP.W заменяется на ее вызов (или встраивание). Но все остальные NOP.W остаются:sad: А хотелось бы прям без любого мусора, в идеале даже без пролога в виде push r7, lr на входе в обработчик (ни R7, ни LR по факту не используются).

Есть мнения на этот счет?

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


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

3 hours ago, Arlleex said:

Есть мнения на этот счет?

А как быть компилятору, если этот weak может в любой момент материализоваться?

В логике LTO, возможно, специально не стали заморачиваться - сколько weak обычно в программе? Ноль.

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


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

16 минут назад, aaarrr сказал:

А как быть компилятору, если этот weak может в любой момент материализоваться?

Ну как... просто никаких инструкций не генерировать🙂 NOP генерируется, а можно (наверное) было ничего не генерировать.

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

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


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

4 minutes ago, Arlleex said:

Или Вы про то, что компилятор должен зарезервировать место под некую инструкций возможного вызова, которую линкер заменит при необходимости?

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

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


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

2 минуты назад, aaarrr сказал:

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

Компилятор да, не в курсе. А вот линковщик как раз мог бы в рамках своей LTO повыкидывать все лишнее за компилятором. Ну, это лишь мое предположение. Т.е. есть ли реальные причины на строгую необходимость в NOP-заполнителях, или же это просто так получилось.

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


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

8 minutes ago, Arlleex said:

А вот линковщик как раз мог бы в рамках своей LTO повыкидывать все лишнее за компилятором

Мог бы, если бы в этом был практический смысл. Экономия 0.5 копейки в 0.0001% случаев.

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


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

Только что, aaarrr сказал:

Мог бы, если бы в этом был практический смысл. Экономия 0.5 копейки в 0.0001% случаев.

Тут мне даже больше из академического интереса любомытно было, почему NOP генерировался.

Конечно же, 2 NOP-а это ничто. Я то исхожу из предположения, что если что-то сделано, оно сделано не просто так🙂

Благодарю!

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


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

6 hours ago, Arlleex said:

оно сделано не просто так🙂

Не работаю с "кейлом", но поумничаю: иногда банан - это просто банан. Возможно, остался такой подход от каких-то старых версий компилятора, например, даже созданный из ошибочных предположений. С таким подходом - вставлять NOP вместо вызова - всё работает. А начнёшь сейчас эту логику убирать в новых версиях инструментария, и получишь почти ничтожный выигрыш в производительности сгенерированного кода, как выше сказал уважаемый @aaarrr, но множество проблем при тестировании продукта. Надо же полагать, что компиляторы у производителя как-то тестируются.

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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