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

STM32 Обработка hard fault exception

А насчёт "огромной" преогромной кучи проверок не соглашусь. Несколько битовых проверок с регистрами много времени не займут.

В отличии от примитивного побайтового цикла с обращением к памяти.

;)

Ха! Вот вам примерчик "нескольких регистровых проверок":

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);
}

 

:)

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


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

Ха! Вот вам примерчик "нескольких регистровых проверок":

И откуда вы эту непотребность вытащили?

Поди, гнусь?

:biggrin:

Вот эта строчка

    memcpy((void*)ptr, (const void*)(ptr+20), 20);

сгенерилась вот в такой код под IAR:

   __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:

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


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

День добрый.

Нужна помощ.

Код для STM32F101BT6 написаный на Си под IAR через определеное время работы по непонятным причинам вылетает в HardFaultException(void). Из флагов выставелся FORCED в HFSR регистре, и IBUSERR в регистре CFSR. Все что в доке нашел, что проблема с шиной. Но какая? Подскажите, как найти где в коде я накосячил. Какие регистры смотреть, что анализировать?

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


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

День добрый.

Нужна помощ.

Код для STM32F101BT6 написаный на Си под IAR через определеное время работы по непонятным причинам вылетает в HardFaultException(void). Из флагов выставелся FORCED в HFSR регистре, и IBUSERR в регистре CFSR. Все что в доке нашел, что проблема с шиной. Но какая? Подскажите, как найти где в коде я накосячил. Какие регистры смотреть, что анализировать?

 

Я использую прерывание по таймеру и HSMCI, периодически вылетаю по HardFault, выставлен FORCED, в LR лежит 0xFFFFFFF9. При изменениях в программе то все работает нормально, то вылетает, такое впечатление, что изменение числа инструкций смещает по времени прерывания, и, если они накладываются, возникает исключение.

Правильно я понимаю, что вылет происходит при выходе из прерывания?

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


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

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

Правильно я понимаю, что вылет происходит при выходе из прерывания?

 

Это типичное поведение, когда забывают проинициализировать какие-либо переменные (указатели или счетчики). Может быть у Вас выключена в компиляторе начальная прочистка/инициализация памяти для переменных?

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


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

Это типичное поведение, когда забывают проинициализировать какие-либо переменные (указатели или счетчики). Может быть у Вас выключена в компиляторе начальная прочистка/инициализация памяти для переменных?

 

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

 

может есть какие то особенности работы с прерываниями у кортексов? до них писал под арм9, там все работало нормально.

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


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

Кажется, причины ясны, проблема не в моем коде. У меня чип ATSAM3S4C ревизии ES.

Подсунули Engineering Samples, не предупредили даже, а я не заметил...

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


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

И откуда вы эту непотребность вытащили?

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

nuzy8.png

(код тут).

 

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


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

Кажется, причины ясны, проблема не в моем коде. У меня чип ATSAM3S4C ревизии ES.

Подсунули Engineering Samples, не предупредили даже, а я не заметил...

Можно подумать, что ES какие-то совсем недоделанные. На них есть своя еррата, ничего страшного не содержащая.

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

- если неправильно настроена PLL (например, значение входной частоты ниже минимальной)

- если регистр EEFC_FMR записывается при выполнении программы из флеш

- таки да, из-за ошибки в коде

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


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

Можно подумать, что ES какие-то совсем недоделанные. На них есть своя еррата, ничего страшного не содержащая.

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

- если неправильно настроена PLL (например, значение входной частоты ниже минимальной)

- если регистр EEFC_FMR записывается при выполнении программы из флеш

- таки да, из-за ошибки в коде

 

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

 

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

 

Не настаиваю, что причина в ES, буду рад услышать другое объяснение!

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


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

PLL настроена правильно.

А FMR?

 

Не настаиваю, что причина в ES, буду рад услышать другое объяснение!

Бывает и совсем наоборот.

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


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

А FMR?

 

в EEFC_FMR у меня 2 цикла на обращение, но MCK на порядок больше, чем 5 MHz, указанные в еррате.

код из флеши исполняется, но к EEFC_FMR обращение единственный раз в стартапе.

 

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


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

код из флеши исполняется, но к EEFC_FMR обращение единственный раз в стартапе.

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

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


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

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

Запись в регистр str r2,[r1] Мне казалось, проблем здесь не возникает, я же не пишу/читаю из флеши в момент записи?

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


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

Запись в регистр str r2,[r1] Мне казалось, проблем здесь не возникает, я же не пишу/читаю из флеши в момент записи?

В том-то и дело, что читает не ядро непосредственно, а контроллер флеш в свои внутренние буферы. И узнать, чем он занимается в данный момент, не представляется возможным.

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


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

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

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

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

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

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

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

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

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

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