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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> STM32 Обработка hard fault exception, Как правильно с ним работать
AHTOXA
сообщение Dec 29 2010, 13:11
Сообщение #16


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(sonycman @ Dec 29 2010, 19:58) *
А насчёт "огромной" преогромной кучи проверок не соглашусь. Несколько битовых проверок с регистрами много времени не займут.
В отличии от примитивного побайтового цикла с обращением к памяти.
wink.gif

Ха! Вот вам примерчик "нескольких регистровых проверок":
CODE
void * memcpy(void * __restrict__ dest, const void * __restrict__ src, size_t n)
{
int adjust, delta;
unsigned int soffset1, doffset1, doffset2;
vec_uchar16 *vSrc, *vDst;
vec_uchar16 sdata1, sdata2, sdata, ddata, shuffle;
vec_uchar16 mask, mask1, mask2, mask3;

vSrc = (vec_uchar16 *)(src);
vDst = (vec_uchar16 *)(dest);

/* Handle any leading destination partial quadwords as
* well a very short copy (ie, such that the n characters
* all reside in a single (destination) quadword.
*/
soffset1 = (unsigned int)(src) & 15;
doffset1 = (unsigned int)(dest) & 15;
doffset2 = ((unsigned int)(dest) + n) & 15;

/* Compute a shuffle pattern used to align the source string
* with the alignment of the destination string.
*/

adjust = (int)spu_extract(spu_cmpgt(spu_promote(doffset1, 0), spu_promote(soffset1, 0)), 0);
delta = (int)soffset1 - (int)doffset1;
delta += adjust & 16;

shuffle = (vec_uchar16)spu_add((vec_uint4)spu_splats((unsigned char)delta),
VEC_LITERAL(vec_uint4, 0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F));

vSrc += adjust;

sdata1 = *vSrc++;
sdata2 = *vSrc++;

ddata = *vDst;
sdata = spu_shuffle(sdata1, sdata2, shuffle);

/* Construct a series of masks used to data insert. The masks
* contain 0 when the destination word is unchanged, 1 when it
* must be replaced by source bytes.
*
* mask1 = mask for leading unchanged bytes
* mask2 = mask for trailing unchange bytes
* mask3 = mask indicating the more than one qword is being changed.
*/
mask = spu_splats((unsigned char)-1);
mask1 = spu_rlmaskqwbyte(mask, -doffset1);
mask2 = spu_slqwbyte(mask, 16-doffset2);
mask3 = (vec_uchar16)spu_cmpgt(spu_splats((unsigned int)(doffset1 + n)), 15);

*vDst++ = spu_sel(ddata, sdata, spu_and(mask1, spu_or(mask2, mask3)));

n += doffset1;

/* Handle complete destination quadwords
*/
while (n > 31) {
sdata1 = sdata2;
sdata2 = *vSrc++;
*vDst++ = spu_shuffle(sdata1, sdata2, shuffle);
n -= 16;
}

/* Handle any trailing partial (destination) quadwords
*/
mask = spu_and((vec_uchar16)spu_cmpgt(spu_splats((unsigned int)n), 16), mask2);
*vDst = spu_sel(*vDst, spu_shuffle(sdata2, *vSrc, shuffle), mask);

return (dest);
}


sm.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
sonycman
сообщение Dec 29 2010, 14:37
Сообщение #17


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(AHTOXA @ Dec 29 2010, 21:11) *
Ха! Вот вам примерчик "нескольких регистровых проверок":

И откуда вы эту непотребность вытащили?
Поди, гнусь?
biggrin.gif
Вот эта строчка
Код
    memcpy((void*)ptr, (const void*)(ptr+20), 20);

сгенерилась вот в такой код под IAR:
CODE
__aeabi_memcpy(_D, _S, _N);
0x327a: 0x2214 MOVS r2, #20 ; 0x14
0x327c: 0xf100 0x0114 ADD.W r1, r0, #20 ; 0x14
0x3280: 0xf003 0xf924 BL __aeabi_memcpy ; 0x64cc
........
__aeabi_memcpy:
0x64cc: 0xb34a CBZ r2, 0x6522
0x64ce: 0x078b LSLS r3, r1, #30
0x64d0: 0xd007 BEQ.N 0x64e2
0x64d2: 0xf811 0x3b01 LDRB.W r3, [r1], #0x1
0x64d6: 0xf800 0x3b01 STRB.W r3, [r0], #0x1
0x64da: 0x1e52 SUBS r2, r2, #1
0x64dc: 0xd021 BEQ.N 0x6522
0x64de: 0x078b LSLS r3, r1, #30
0x64e0: 0xd1f7 BNE.N 0x64d2
0x64e2: 0x0783 LSLS r3, r0, #30
0x64e4: 0xd11e BNE.N 0x6524
__aeabi_memcpy4:
__aeabi_memcpy8:
0x64e6: 0x3a10 SUBS r2, r2, #16 ; 0x10
0x64e8: 0xd307 BCC.N 0x64fa
0x64ea: 0xb430 PUSH {r4, r5}
0x64ec: 0xe8b1 0x1038 LDM r1!, {r3-r5, r12}
0x64f0: 0x3a10 SUBS r2, r2, #16 ; 0x10
0x64f2: 0xe8a0 0x1038 STM r0!, {r3-r5, r12}
0x64f6: 0xd2f9 BCS.N 0x64ec
0x64f8: 0xbc30 POP {r4, r5}
0x64fa: 0x0753 LSLS r3, r2, #29
0x64fc: 0xbf24 ITT CS
0x64fe: 0xe8b1 0x1008 LDMCS r1!, {r3, r12}
0x6502: 0xe8a0 0x1008 STMCS r0!, {r3, r12}
0x6506: 0xbf44 ITT MI
0x6508: 0xf851 0x3b04 LDRMI.W r3, [r1], #0x4
0x650c: 0xf840 0x3b04 STRMI.W r3, [r0], #0x4
0x6510: 0x07d2 LSLS r2, r2, #31
0x6512: 0xbf24 ITT CS
0x6514: 0xf831 0x2b02 LDRHCS.W r2, [r1], #0x2
0x6518: 0xf820 0x2b02 STRHCS.W r2, [r0], #0x2
0x651c: 0xbf44 ITT MI
0x651e: 0x780b LDRBMI r3, [r1]
0x6520: 0x7003 STRBMI r3, [r0]
0x6522: 0x4770 BX lr
0x6524: 0x3a08 SUBS r2, r2, #8
0x6526: 0xd307 BCC.N 0x6538
0x6528: 0xe8b1 0x1008 LDM r1!, {r3, r12}
0x652c: 0x3a08 SUBS r2, r2, #8
0x652e: 0xf840 0x3b04 STR.W r3, [r0], #0x4
0x6532: 0xf840 0xcb04 STR.W r12, [r0], #0x4
0x6536: 0xd2f7 BCS.N 0x6528
0x6538: 0x0753 LSLS r3, r2, #29
0x653a: 0xe7e4 B.N 0x6506

Оверхед, конечно, есть, но не бог весть какой значительный, в уплату универсальности.
ЗЫ: какой смысл смотреть исходник, когда подобные библиотечные функции жёстко "затачиваются" на ассемблере?
laughing.gif
Go to the top of the page
 
+Quote Post
pan_oleg
сообщение Jan 5 2011, 11:31
Сообщение #18


Частый гость
**

Группа: Участник
Сообщений: 76
Регистрация: 16-11-07
Пользователь №: 32 387



День добрый.
Нужна помощ.
Код для STM32F101BT6 написаный на Си под IAR через определеное время работы по непонятным причинам вылетает в HardFaultException(void). Из флагов выставелся FORCED в HFSR регистре, и IBUSERR в регистре CFSR. Все что в доке нашел, что проблема с шиной. Но какая? Подскажите, как найти где в коде я накосячил. Какие регистры смотреть, что анализировать?
Go to the top of the page
 
+Quote Post
Атмег
сообщение Apr 5 2011, 16:48
Сообщение #19


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 17-05-07
Пользователь №: 27 787



Цитата(pan_oleg @ Jan 5 2011, 14:31) *
День добрый.
Нужна помощ.
Код для STM32F101BT6 написаный на Си под IAR через определеное время работы по непонятным причинам вылетает в HardFaultException(void). Из флагов выставелся FORCED в HFSR регистре, и IBUSERR в регистре CFSR. Все что в доке нашел, что проблема с шиной. Но какая? Подскажите, как найти где в коде я накосячил. Какие регистры смотреть, что анализировать?


Я использую прерывание по таймеру и HSMCI, периодически вылетаю по HardFault, выставлен FORCED, в LR лежит 0xFFFFFFF9. При изменениях в программе то все работает нормально, то вылетает, такое впечатление, что изменение числа инструкций смещает по времени прерывания, и, если они накладываются, возникает исключение.
Правильно я понимаю, что вылет происходит при выходе из прерывания?
Go to the top of the page
 
+Quote Post
KnightIgor
сообщение Apr 6 2011, 12:32
Сообщение #20


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Цитата(Атмег @ Apr 5 2011, 18:48) *
При изменениях в программе то все работает нормально, то вылетает, такое впечатление, что изменение числа инструкций смещает по времени прерывания, и, если они накладываются, возникает исключение.
Правильно я понимаю, что вылет происходит при выходе из прерывания?


Это типичное поведение, когда забывают проинициализировать какие-либо переменные (указатели или счетчики). Может быть у Вас выключена в компиляторе начальная прочистка/инициализация памяти для переменных?
Go to the top of the page
 
+Quote Post
Атмег
сообщение Apr 6 2011, 17:10
Сообщение #21


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 17-05-07
Пользователь №: 27 787



Цитата(KnightIgor @ Apr 6 2011, 15:32) *
Это типичное поведение, когда забывают проинициализировать какие-либо переменные (указатели или счетчики). Может быть у Вас выключена в компиляторе начальная прочистка/инициализация памяти для переменных?


я все переменные инициализирую при объявлении, привычка такая. на счет библиотек - не знаю, я пользовался атмеловским драйвером HSMCI. с ним изначально проблемы были, потом работал нормально, я его больше не трогал.

может есть какие то особенности работы с прерываниями у кортексов? до них писал под арм9, там все работало нормально.
Go to the top of the page
 
+Quote Post
Атмег
сообщение Apr 7 2011, 17:45
Сообщение #22


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 17-05-07
Пользователь №: 27 787



Кажется, причины ясны, проблема не в моем коде. У меня чип ATSAM3S4C ревизии ES.
Подсунули Engineering Samples, не предупредили даже, а я не заметил...
Go to the top of the page
 
+Quote Post
igorsk
сообщение Apr 7 2011, 21:45
Сообщение #23


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 22-03-10
Пользователь №: 56 131



Цитата(sonycman @ Dec 29 2010, 16:37) *
И откуда вы эту непотребность вытащили?

Это цветочки. Вот как выглядит memcpy у айфона (ARMv7).

(код тут).
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 7 2011, 22:11
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Атмег @ Apr 7 2011, 21:45) *
Кажется, причины ясны, проблема не в моем коде. У меня чип ATSAM3S4C ревизии ES.
Подсунули Engineering Samples, не предупредили даже, а я не заметил...

Можно подумать, что ES какие-то совсем недоделанные. На них есть своя еррата, ничего страшного не содержащая.
А описанные вами проблемы могут возникать в нескольких случаях:
- если неправильно настроена PLL (например, значение входной частоты ниже минимальной)
- если регистр EEFC_FMR записывается при выполнении программы из флеш
- таки да, из-за ошибки в коде
Go to the top of the page
 
+Quote Post
Атмег
сообщение Apr 8 2011, 07:53
Сообщение #25


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 17-05-07
Пользователь №: 27 787



Цитата(aaarrr @ Apr 8 2011, 01:11) *
Можно подумать, что ES какие-то совсем недоделанные. На них есть своя еррата, ничего страшного не содержащая.
А описанные вами проблемы могут возникать в нескольких случаях:
- если неправильно настроена PLL (например, значение входной частоты ниже минимальной)
- если регистр EEFC_FMR записывается при выполнении программы из флеш
- таки да, из-за ошибки в коде


Я не склонен валить все косяки на производителя, честно ковырялся в своем коде, но увиденное вчера меня добило окончательно: еще до разрешения прерываний просто шагаю по коду, вхожу в одну функцию, выхожу, все норм, вхожу в следующую - исключение с флагом IMPRECISERR (ошибка на шине, но адрес не определен?). При том что данный кусок кода (библиотечный) вполне успешно работал и работает при изменениях в любом другом месте программы. Т.е. от перегруппировки памяти периодически возникает какой то неработоспособный код.

Правда тут более странный момент заметил, один и тот же код на одной плате может вызвать HardFault, а на другой нет. Внешнюю шину не использую. PLL настроена правильно. Были мысли насчет нестабильности частоты, но причины, недомытая плата? Тогда почему только при определенном коде?

Не настаиваю, что причина в ES, буду рад услышать другое объяснение!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 8 2011, 08:49
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Атмег @ Apr 8 2011, 11:53) *
PLL настроена правильно.

А FMR?

Цитата(Атмег @ Apr 8 2011, 11:53) *
Не настаиваю, что причина в ES, буду рад услышать другое объяснение!

Бывает и совсем наоборот.
Go to the top of the page
 
+Quote Post
Атмег
сообщение Apr 8 2011, 09:48
Сообщение #27


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 17-05-07
Пользователь №: 27 787



Цитата(aaarrr @ Apr 8 2011, 11:49) *
А FMR?


в EEFC_FMR у меня 2 цикла на обращение, но MCK на порядок больше, чем 5 MHz, указанные в еррате.
код из флеши исполняется, но к EEFC_FMR обращение единственный раз в стартапе.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 8 2011, 09:54
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Атмег @ Apr 8 2011, 13:48) *
код из флеши исполняется, но к EEFC_FMR обращение единственный раз в стартапе.

Как показывает практика, этого достаточно для появления сбоя совсем в другом месте.
Go to the top of the page
 
+Quote Post
Атмег
сообщение Apr 8 2011, 10:23
Сообщение #29


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 17-05-07
Пользователь №: 27 787



Это я взял как есть из примера. Как будет очередной сбой - проверю, это ли явилось причиной.
Запись в регистр str r2,[r1] Мне казалось, проблем здесь не возникает, я же не пишу/читаю из флеши в момент записи?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 8 2011, 10:28
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Атмег @ Apr 8 2011, 14:23) *
Запись в регистр str r2,[r1] Мне казалось, проблем здесь не возникает, я же не пишу/читаю из флеши в момент записи?

В том-то и дело, что читает не ядро непосредственно, а контроллер флеш в свои внутренние буферы. И узнать, чем он занимается в данный момент, не представляется возможным.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 22:14
Рейтинг@Mail.ru


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