Запрос относительно правила 11.6 Misra (MISRA C:2012)

Я не могу решить предупреждение о правиле 11.6 мисры в этой строке:

uint32_t * delay = (uint32_t *)0x40086D0C ;

[К сведению: typedef long unsigned int uint32_t;]

PC-Lint: Примечание 923: преобразование из int в указатель [правило MISRA 2012 11.6, обязательно]

Что я сделал:

  • Явно типизировано, но это не работает
  • Используйте memset(), он работает, но это не правильный способ устранения предупреждения Misra. потому что это было ненужным повышенным вызовом функций в системе и могло снизить производительность системы.

Не могли бы вы поделиться полезной мыслью по моей проблеме? Это будет действительно оценено.


person Kanji Viroja    schedule 08.12.2016    source источник
comment
Этот код не может быть приведен в соответствие.   -  person    schedule 08.12.2016
comment
Да, ты был прав. Но как решить предупреждение о мисре в этой строке? Я ищу решение. У вас есть идеи, как исправить это предупреждение?   -  person Kanji Viroja    schedule 08.12.2016
comment
Что именно ты пытаешься сделать? Вы хотите указать delay на заданный адрес памяти или создать указатель с этим целочисленным значением?   -  person    schedule 08.12.2016
comment
да. На самом деле, я хочу получить доступ к низкоуровневой части памяти, для которой я назначаю адрес указателю, и этот адрес уже сопоставлен с памятью.   -  person Kanji Viroja    schedule 08.12.2016
comment
stackoverflow.com/ вопросы/25720358/   -  person n. 1.8e9-where's-my-share m.    schedule 08.12.2016
comment
Я думаю, что настоящая проблема не в назначении, а в происхождении 0x40086D0C. Откуда вы взяли этот номер? MISRA-C на самом деле пытается помешать вам делать такие слепки. Не пытайтесь обойти.   -  person eyalm    schedule 08.12.2016
comment
Я рекомендую удалить Lint, так как это активно вредоносное средство. Его использование приводит к угрозам безопасности, вызванным тем, что люди доверяют инструменту, а затем изменяют рабочий код, совместимый с MISRA.   -  person Lundin    schedule 08.12.2016


Ответы (2)


Линт как всегда сломан. Отправьте отчет об ошибке или просто удалите Lint.

Правило 11.6 MISRA-C:2012 касается приведения указателя к void к указателю арифметического типа! Таким образом, «приведение от int к указателю [Правило 11.6 MISRA 2012, обязательное]» - это неверная ерунда, не имеющая отношения к цитируемому правилу, которое они цитируют неправильно.

Существует рекомендательное правило 11.4 относительно преобразования целых чисел в указатели. Цель этого правила — отловить случаи, когда такие приведения могут привести к неправильному выравниванию указателей. Однако вы можете игнорировать правило 11.4, не поднимая отклонения, поскольку оно носит рекомендательный характер.

Таким образом, ваш код соответствует требованиям MISRA, за исключением рекомендательного правила, хотя вам необходимо добавить суффикс U к целочисленной константе, чтобы выполнить другие правила:

uint32_t* delay = (uint32_t*)0x40086D0Cu ;

И указатель, скорее всего, должен быть volatile uint32_t*, чтобы этот код имел какой-то смысл.

person Lundin    schedule 08.12.2016
comment
Lint сломан, да, но только в том случае, если он сообщает R11.6, а не R11.4. Но, как вы сказали, R11.4 является (а) только рекомендательным, но (б) признает, что бывают случаи, когда требуется доступ с отображением памяти. - person Andrew; 24.09.2019
comment
@ Эндрю Справедливости ради, если вы хотите купить сломанный инструмент, Lint - это то, что вам нужно. В 10 раз дешевле, чем такие же сломанные инструменты на рынке, большинство ошибок за доллар. - person Lundin; 24.09.2019

Это вполне разумное приведение (при условии, что ваши указатели 32-битные). В этом случае, вероятно, лучше указать программе проверки ворса игнорировать эту строку. Правила MISRA существуют для предотвращения типичных случаев ошибок, но некоторые операции, такие как доступ к периферийным устройствам с отображением памяти, не могут быть выполнены в рамках спецификации (насколько мне известно).

Использование memset — очень плохая идея — оно устанавливает отдельные байты, поэтому вам потребуется 4 вызова memset(), чтобы установить 4 байта указателя. Вы можете получить аналогичный эффект с помощью одного вызова memcpy(), хотя я не думаю, что это соответствует духу спецификации.

Как для memcpy(), так и для memset() вы не должны увидеть снижения производительности. Любой достойный оптимизирующий компилятор обнаружит memcpy фиксированного размера и заменит его одной 32-битной инструкцией MOV (или аналогом для вашей платформы). Вот пример, где clang

  1. заменил memset фиксированной длины 32-битным перемещением
  2. понял, что значение delay совпадает со значением addr
  3. удалено delay полностью
person alexkonradi    schedule 08.12.2016
comment
Вы были правы, но если мы везде добавили вызов API, то это увеличило бы операцию push pop в стеке. - person Kanji Viroja; 08.12.2016
comment
Очевидно, что это вполне разумный бросок для определенных значений «разумного». Это может быть исправлено компоновщиком способом, совместимым с MISRA C. - person ; 08.12.2016