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

 
 
> Команда "STM r0!, {r1}" на Cortex M3, При невыровненном адресе возникает Hard Fault.
ISK2010
сообщение Sep 6 2011, 13:37
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 205
Регистрация: 21-09-10
Из: г.Зеленоград
Пользователь №: 59 631



Добрый день!

Железо - STM32F105VC rev.Z.

ПО - Keil 4.21, компилятор armcc 4.1.0.644

Случилось вот что. Понадобилось мне одну 32битную сохранить в буфер, и адрес поменять на следующую ячейку буфера:

Код
*((u32*)pPDU) = __REV16_W(*((u32*)( MB_HoldRegs + Address))); //да хоть просто число туда записывать
  
             pPDU += 4;


Ситуация стандартная. Но на мою голову компилятор засовывает инструкцию "STM":

Код
0x080018A0 F7FEFC70  BL.W     __REV16_W (0x08000184)
  0x080018A4 C601      STM      r6!,{r0}
тем самым пытаясь выполнить запись+инкремент за раз, но при выполнении которой происходит ошибка (HardFault).

Пока выяснял почему, начитался всякого. Вплоть до того, что вставленная 16битная инструкция STM является устаревшей и не используется для ядер ARMv6 и выше. А в другом месте (в ссылке про STM) вообще написано, что 16битная STM не поддерживается в Thumb-2EE, который для ARMv7, т.е. нашего Cortex-M3.

Но тогда почему именно эта инструкция была вставлена? Неужели косяк компилятора? Или же все-таки эта инструкция поддерживается Cortex-M3, но есть ограничения для ревизиии Z?

Все эти вопросы я себе задавал, а между этим провел эксперимент. Написал на ассемблере функцию, в которой с помощью этой инструкции заполняю массив 32битных элементов.

Результат экспериментов: инструкция работает, но если адрес массива не кратен 4, то вылетаем в Hard Fault.

Люди добрые, прокомментируйте случившееся. Помогите подвести итог.

Сообщение отредактировал ISK2010 - Sep 6 2011, 13:39
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ISK2010
сообщение Sep 7 2011, 06:51
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 205
Регистрация: 21-09-10
Из: г.Зеленоград
Пользователь №: 59 631



Может у них так и было задумано)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Sep 7 2011, 07:02
Сообщение #3


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(ISK2010 @ Sep 7 2011, 09:51) *
Может у них так и было задумано)

Реверсируется-то порядок байтов в обоих полусловах, и в младшем, и в старшем. wacko.gif
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Sep 7 2011, 08:04
Сообщение #4


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Получается, что фолт на cm3 может произойти лишь при адресации не выравненных объектов больших байта?
А указатели на байт в принципе не нуждаются в атрибуте packed.
Я правильно мыслю?

Цитата(ViKo @ Sep 7 2011, 11:02) *
Реверсируется-то порядок байтов в обоих полусловах, и в младшем, и в старшем. wacko.gif
Поэтому аргумент и 16-ти битный в старшем полуслове будут всегда нули. Баги в CMSIS я не вижу.

Кстати, в литературе есть мнение, что
Код
b = ((a & 0x00ff) << 8) | ((a & 0xff00) >> 8); // This should generate the REV16 instruction.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Sep 7 2011, 08:57
Сообщение #5


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(demiurg_spb @ Sep 7 2011, 11:04) *
Поэтому аргумент и 16-ти битный в старшем полуслове будут всегда нули. Баги в CMSIS я не вижу.

Кстати, в литературе есть мнение, что
Код
b = ((a & 0x00ff) << 8) | ((a & 0xff00) >> 8); // This should generate the REV16 instruction.

Понятно, что при 16-битовом аргументе будет работать. А если нужно проинвертировать порядок в обоих полусловах, придется писать свою функцию, как сделал ISK2010. Хотя команда та же.
А можно было задать в функции REV16 32-битовый аргумент. Если кому-то нужно было проинвертировать порядок байтов в 16-битовой переменной, то эту 32-битовую функцию можно было бы использовать без переделок.

Кстати, в приведенной вами литературе есть пример, показывающий неэффективность использования в функциях переменныхс размерностью, меньше, чем int32. То же относится и к аргументам функций и возвращаемому результату.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Sep 7 2011, 09:42
Сообщение #6


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(ViKo @ Sep 7 2011, 12:57) *
А можно было задать в функции REV16 32-битовый аргумент. Если кому-то нужно было проинвертировать порядок байтов в 16-битовой переменной, то эту 32-битовую функцию можно было бы использовать без переделок.
Это да.
Цитата
Кстати, в приведенной вами литературе есть пример, показывающий неэффективность использования в функциях переменныхс размерностью, меньше, чем int32. То же относится и к аргументам функций и возвращаемому результату.
Разумеется.

Цитата(ViKo @ Sep 7 2011, 12:57) *
Понятно, что при 16-битовом аргументе будет работать. А если нужно проинвертировать порядок в обоих полусловах, придется писать свою функцию, как сделал ISK2010.
Вопрос зачем ему это? Какой-то middle-endian формат получается. Ведь для смены эндианизма есть инструкции REV и REVSH.
Как я понял речь идёт в контексте формирования PDU одного из протоколов (modbus?), где используется не нативный для cm3 сетевой порядок следования байт.
ИМХО расширять функционал CMSIS - крайняя мера...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- ISK2010   Команда "STM r0!, {r1}" на Cortex M3   Sep 6 2011, 13:37
- - ViKo   А почему вы не определили pPDU как указатель на 32...   Sep 6 2011, 14:06
- - KRS   Цитата(ISK2010 @ Sep 6 2011, 17:37) Пока ...   Sep 6 2011, 14:25
- - ISK2010   To ViKo: pPDU - указатель на байт, поэтому прибав...   Sep 6 2011, 15:55
|- - aaarrr   Цитата(ISK2010 @ Sep 6 2011, 19:55) как б...   Sep 6 2011, 16:56
|- - KRS   Цитата(ISK2010 @ Sep 6 2011, 19:55) Подск...   Sep 6 2011, 18:08
- - ViKo   Процитирую помощь к Кейлу, правда, не уверен, что ...   Sep 6 2011, 17:32
- - ISK2010   Огромное СПАСИБО! Использовал _packed для стру...   Sep 6 2011, 19:15
- - 777777   Цитата(ISK2010 @ Sep 6 2011, 17:37) Код*...   Sep 7 2011, 05:53
- - ISK2010   ЦитатаА что это за макрос __REV16_W? Эта фу...   Sep 7 2011, 06:21
|- - ViKo   Цитата(ISK2010 @ Sep 7 2011, 09:21) Но,ка...   Sep 7 2011, 06:41
- - ISK2010   Да, ModBus) Решил оптимизировать функции обработки...   Sep 7 2011, 12:04
|- - demiurg_spb   Ой не там экономите. Завтра нужно будет для 8-ми б...   Sep 7 2011, 12:10
- - ISK2010   Везде по чуть-чуть. Еще с расчета CRC немного высв...   Sep 7 2011, 16:47
|- - aaarrr   Цитата(ISK2010 @ Sep 7 2011, 20:47) На да...   Sep 7 2011, 16:54
- - ISK2010   От всего   Sep 8 2011, 04:42


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

 


RSS Текстовая версия Сейчас: 26th July 2025 - 01:41
Рейтинг@Mail.ru


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