Миландр

Ключевым подразделением нашей компании
является Центр Проектирования интегральных микросхем
Текущее время: 2020-фев-25 05:36

Часовой пояс: UTC+03:00




Начать новую тему  Ответить на тему  [ 10 сообщений ] 
Автор Сообщение
 Заголовок сообщения: HardFaultExit - Выход из исключения
СообщениеДобавлено: 2019-окт-09 12:53 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1423
Откуда: Тула
Поскольку не знаю иного способа обратной связи с командой портала https://startmilandr.ru/ пишу тут.

Речь о статье Работа со стеком - Выход из исключения.

На данный момент там есть примечание о интересной проблеме:
Открыть Общий способ решения данной проблемы, +4 или +2, нам не известен. Если кто-то знает решение, поделитесь
Цитата:
UPDATE: С выходом из обработчика есть проблема, заключающаяся в том, что в общем случае неизвестно сколько байт занимает инструкция приведшая к исключению. Набор инструкций Thumb2 содержит 32-битные инструкции, поэтому в Cortex-M3/M4 высока вероятность того, что инструкция окажется 4-х байтной. Тогда действительно для выхода на следующую инструкцию необходимо увеличить PC на +4. Но если инструкция вызвавшая исключение была 2-х байтной, тогда при модификации +4 мы либо перескочим следующую 16-битную инструкцию, либо попадем в середину следующей 32-битной инструкции. В Cortex-M0/M1 почти все инструкции 2-х байтные - Instruction_sets.

В рассматриваемом далее примере деление производится 32-битной инструкцией, поэтому для данного варианта оправдан выход по +4. Но при чтении памяти обычно компилятором используются 16-битные инструкция. Поэтому, например, в 1986ВЕ8Т когда при чтении памяти не согласованной с ECC возникает исключение HardFault, то выход из него на следующую инструкцию необходимо делать через +2.

Общий способ решения данной проблемы, +4 или +2, нам не известен. Нашелся подобный вопрос в блоге ARM, но он остался без ответа. Если кто-то знает решение, поделитесь пожалуйста на info@startmilandr.ru.
Закрыть
Предлагаю: разобрать опкод инструкции, вызвавшей прерывание, на предмет её размера - два или четыре байта.
Для этого нужно проверить пять старших бит:
Цитата:
If bits [15:11] of the halfword being decoded take any of the following values, the halfword is the first halfword of a 32-bit instruction:
• 0b11101.
• 0b11110.
• 0b11111.
Otherwise, the halfword is a 16-bit instruction.
ARM®v7-M Architecture Reference Manual
https://static.docs.arm.com/ddi0403/eb/ ... 7m_arm.pdf

UPD: То есть, опираясь на код из статьи, получается так:
void HardFault_Handler_C(uint32_t stack[])
{
   //  Изменяем значение регистра PC
   //  на адрес инструкции на которую произойдет выход из исключения.
   unsigned address = stack[pc] & ~1U;
   unsigned opcode = *((unsigned *) address); // одна 32битная или две 16битных инструкции
   opcode = (opcode >> 11) & 0x1F;

   if( opcode > 12) {
      // опкоды, старшие 5 бит которых равны 13, 14, 15 указывают на 32-битную команду.
      stack[pc] = stack[pc] + 4;
   } else {
      stack[pc] = stack[pc] + 2;
   }
}
Не знаю, вроде бы нужно сбрасывать младший бит адреса инструкции, считанный как stack[pc].
Всё это нужно проверить!!!))))

UPD2: подкорректировал код.

_________________
сочувствующий…


Вернуться к началу
 Заголовок сообщения: Re: HardFaultExit - Выход из исключения
СообщениеДобавлено: 2019-окт-09 14:14 
Не в сети

Зарегистрирован: 2018-мар-18 15:49
Сообщения: 21
Организация: StartMilandr.ru
Спасибо большое, шикарный вариант!!!
Про опкоды думали, но представлялось что придется перебирать слишком много условий. Оказалось все просто!

PS: На этом форуме у нас почему-то постоянно отваливается пароль, поэтому обычно только читаем. Но ящик вроде должен работать info@milandr.ru


Вернуться к началу
 Заголовок сообщения: Re: HardFaultExit - Выход из исключения
СообщениеДобавлено: 2019-окт-09 14:58 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1423
Откуда: Тула
StartMilandr писал(а):
Спасибо большое, шикарный вариант!!!
Про опкоды думали, но представлялось что придется перебирать слишком много условий. Оказалось все просто!

PS: На этом форуме у нас почему-то постоянно отваливается пароль, поэтому обычно только читаем. Но ящик вроде должен работать info@milandr.ru
Пожалуйста.
Про опкоды я тоже так думал, но полчаса гугления... и нашёлся документ, уже сохранённый на компе. :wink:

_________________
сочувствующий…


Вернуться к началу
 Заголовок сообщения: Re: HardFaultExit - Выход из исключения
СообщениеДобавлено: 2019-окт-09 16:50 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 470
Организация: Milandr
Откуда: ПКК "Миландр"
Полезная штука, спасибо!


Вернуться к началу
 Заголовок сообщения: Re: HardFaultExit - Выход из исключения
СообщениеДобавлено: 2019-окт-18 15:37 
Не в сети

Зарегистрирован: 2014-май-15 11:04
Сообщения: 133
Откуда: Москва
Да, спасибо.
Для М0. стр. 76.
The Thumb instruction stream is a sequence of halfword-aligned halfwords. Each Thumb instruction is either a
single 16-bit halfword in that stream, or a 32-bit instruction consisting of two consecutive halfwords in that stream.
If bits [15:11] of the halfword being decoded take any of the following values, the halfword is the first halfword of
a 32-bit instruction:
• 0b11101.
• 0b11110.
• 0b11111.
Otherwise, the halfword is a 16-bit instruction


Вернуться к началу
 Заголовок сообщения: Re: HardFaultExit - Выход из исключения
СообщениеДобавлено: 2019-окт-18 17:23 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1423
Откуда: Тула
רגוזין רומאן писал(а):
Для М0. стр. 76.
Бегло посмотрел - с точки зрения проблемы +2/+4 всё то же самое. Правильно или Вы намекаете на какое-то расхождение для М0?

_________________
сочувствующий…


Вернуться к началу
 Заголовок сообщения: Re: HardFaultExit - Выход из исключения
СообщениеДобавлено: 2019-окт-18 20:31 
Не в сети

Зарегистрирован: 2014-май-15 11:04
Сообщения: 133
Откуда: Москва
prostoRoman, не совсем. Я программирую сейчас для M0, по тому и стал проверять, будет ли работать этот метод на этом ядре.
Другими совами подтверждаю, что на ядре M0 построенном на архитектуре ARMv6-M этот метод тоже работает.


Вернуться к началу
 Заголовок сообщения: Re: HardFaultExit - Выход из исключения
СообщениеДобавлено: 2019-окт-21 13:49 
Не в сети

Зарегистрирован: 2014-май-15 11:04
Сообщения: 133
Откуда: Москва
Вот так будет выглядеть для M0 (для M0 невозможно использовать "условные" инструкции добавлением разных суффиксов).
;==================================================================================================	
;==================================================================================================
;==================================================================================================
Hard_Fault_Handler		PROC
;	По LR определяем какой указатель стека активный. (EXC_RETURN).
;	MSP - это указатель стека в системном режиме работы (Операционная система).
;	PSP - это указатель стека в пользовательском режиме работы (Приложение).		
		MOVS	R0,	#0x04;
		MOV		R1,	LR;
        TST		R1,	R0;
		BEQ		L_HFH_MSP;
		MRS		R0,	PSP;
		B		L_HFH_TopOfStack;
L_HFH_MSP
		MRS		R0,	MSP;
L_HFH_TopOfStack
;	Получили адрес вершины стека.
		LDR		R1,	[R0,	#24];	Забираем из стека адрес инструкции приведшей к ошибке. (SP+24байта=PC).
		LDRH	R2,	[R1];			Считываем код самой инструкции приведшей к ошибке.
		LSRS	R2,	R2,	#11;		Нам интересны последние 5-ть бит инструкции.
		CMP		R2,	#0x1D;			Сравниваем с 0x0001 1101.  Как с наименьшей из 32-х битной инструкцией.
;	Если к ошибке привела 16-ти битная инструкция, то прибавляем 2-а к адресу инструкции вызвавшей ошибку.
;	Если к ошибке привела 32-ух битная инструкция, то прибавляем 4-е к адресу инструкции вызвавшей ошибку.
		BCS		L_HFH_Plus4;
		ADDS	R1,	#0x02;			Прибавляем 2-а к адресу инструкции вызвавшей ошибку.
		B		L_HFH_ExitFromFault;
L_HFH_Plus4
		ADDS	R1,	#0x04;			Прибавляем 4-е к адресу инструкции вызвавшей ошибку.
L_HFH_ExitFromFault
		STR		R1,	[R0,	#24];	Сохраняем в стек на месте PC новый адрес возврата из исключения.
		LDR		R0,	=GPIOA;			Зажигаем диодик для индикации. В последствии разработать журнал.
		MOVS	R1,	#0x40;
		STR		R1,	[R0,	#GPIO_BSRR];
		BX		LR;					Возвращаемся из исключения.
						ENDP;
;==================================================================================================
;==================================================================================================
;==================================================================================================


Последний раз редактировалось רגוזין רומאן 2019-окт-21 15:57, всего редактировалось 7 раз.

Вернуться к началу
 Заголовок сообщения: Re: HardFaultExit - Выход из исключения
СообщениеДобавлено: 2019-окт-21 14:52 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1423
Откуда: Тула
רגוזין רומאן писал(а):
Вот так будет выглядеть для M0
		LDRH	R2,	[R1];			Считываем код самой инструкции приведшей к ошибке.
		LSRS	R2,	R2,	#12;
		MOVS	R3,	#0x0F;			Нам интересны последние 5-ть бит инструкции (но хватит и 4-х).
		ANDS	R3,	R2,	R3;
		MOVS	R2,	#0x0E;
		TST		R3,	R2;
Если я всё правильно понял (фактически вы проверяете наличие трёх единиц в старших разрядах кода команды), то незаслуженно обижена оказывается команда безусловного перехода B в варианте кодировки Т2. Её код начинается на 0b11100....
Cм. A6.7.10 on page 110; A5.2 on page 78 в приведённом Вами ARMv6-M Architecture Reference Manual DDI0419D_armv6m_arm.pdf

_________________
сочувствующий…


Вернуться к началу
 Заголовок сообщения: Re: HardFaultExit - Выход из исключения
СообщениеДобавлено: 2019-окт-21 15:10 
Не в сети

Зарегистрирован: 2014-май-15 11:04
Сообщения: 133
Откуда: Москва
Да да, вы правы. Поправил. И TST там не правильно. Правильно CMP.


Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 10 сообщений ] 

Часовой пояс: UTC+03:00


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 4 гостя


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти: 

cron
Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB