AHTOXA 18 29 декабря, 2010 Опубликовано 29 декабря, 2010 · Жалоба А насчёт "огромной" преогромной кучи проверок не соглашусь. Несколько битовых проверок с регистрами много времени не займут. В отличии от примитивного побайтового цикла с обращением к памяти. ;) Ха! Вот вам примерчик "нескольких регистровых проверок": 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); } :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sonycman 0 29 декабря, 2010 Опубликовано 29 декабря, 2010 · Жалоба Ха! Вот вам примерчик "нескольких регистровых проверок": И откуда вы эту непотребность вытащили? Поди, гнусь? Вот эта строчка 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: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pan_oleg 0 5 января, 2011 Опубликовано 5 января, 2011 · Жалоба День добрый. Нужна помощ. Код для STM32F101BT6 написаный на Си под IAR через определеное время работы по непонятным причинам вылетает в HardFaultException(void). Из флагов выставелся FORCED в HFSR регистре, и IBUSERR в регистре CFSR. Все что в доке нашел, что проблема с шиной. Но какая? Подскажите, как найти где в коде я накосячил. Какие регистры смотреть, что анализировать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Атмег 0 5 апреля, 2011 Опубликовано 5 апреля, 2011 · Жалоба День добрый. Нужна помощ. Код для STM32F101BT6 написаный на Си под IAR через определеное время работы по непонятным причинам вылетает в HardFaultException(void). Из флагов выставелся FORCED в HFSR регистре, и IBUSERR в регистре CFSR. Все что в доке нашел, что проблема с шиной. Но какая? Подскажите, как найти где в коде я накосячил. Какие регистры смотреть, что анализировать? Я использую прерывание по таймеру и HSMCI, периодически вылетаю по HardFault, выставлен FORCED, в LR лежит 0xFFFFFFF9. При изменениях в программе то все работает нормально, то вылетает, такое впечатление, что изменение числа инструкций смещает по времени прерывания, и, если они накладываются, возникает исключение. Правильно я понимаю, что вылет происходит при выходе из прерывания? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KnightIgor 2 6 апреля, 2011 Опубликовано 6 апреля, 2011 · Жалоба При изменениях в программе то все работает нормально, то вылетает, такое впечатление, что изменение числа инструкций смещает по времени прерывания, и, если они накладываются, возникает исключение. Правильно я понимаю, что вылет происходит при выходе из прерывания? Это типичное поведение, когда забывают проинициализировать какие-либо переменные (указатели или счетчики). Может быть у Вас выключена в компиляторе начальная прочистка/инициализация памяти для переменных? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Атмег 0 6 апреля, 2011 Опубликовано 6 апреля, 2011 · Жалоба Это типичное поведение, когда забывают проинициализировать какие-либо переменные (указатели или счетчики). Может быть у Вас выключена в компиляторе начальная прочистка/инициализация памяти для переменных? я все переменные инициализирую при объявлении, привычка такая. на счет библиотек - не знаю, я пользовался атмеловским драйвером HSMCI. с ним изначально проблемы были, потом работал нормально, я его больше не трогал. может есть какие то особенности работы с прерываниями у кортексов? до них писал под арм9, там все работало нормально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Атмег 0 7 апреля, 2011 Опубликовано 7 апреля, 2011 · Жалоба Кажется, причины ясны, проблема не в моем коде. У меня чип ATSAM3S4C ревизии ES. Подсунули Engineering Samples, не предупредили даже, а я не заметил... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
igorsk 0 7 апреля, 2011 Опубликовано 7 апреля, 2011 · Жалоба И откуда вы эту непотребность вытащили? Это цветочки. Вот как выглядит memcpy у айфона (ARMv7). (код тут). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 7 апреля, 2011 Опубликовано 7 апреля, 2011 · Жалоба Кажется, причины ясны, проблема не в моем коде. У меня чип ATSAM3S4C ревизии ES. Подсунули Engineering Samples, не предупредили даже, а я не заметил... Можно подумать, что ES какие-то совсем недоделанные. На них есть своя еррата, ничего страшного не содержащая. А описанные вами проблемы могут возникать в нескольких случаях: - если неправильно настроена PLL (например, значение входной частоты ниже минимальной) - если регистр EEFC_FMR записывается при выполнении программы из флеш - таки да, из-за ошибки в коде Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Атмег 0 8 апреля, 2011 Опубликовано 8 апреля, 2011 · Жалоба Можно подумать, что ES какие-то совсем недоделанные. На них есть своя еррата, ничего страшного не содержащая. А описанные вами проблемы могут возникать в нескольких случаях: - если неправильно настроена PLL (например, значение входной частоты ниже минимальной) - если регистр EEFC_FMR записывается при выполнении программы из флеш - таки да, из-за ошибки в коде Я не склонен валить все косяки на производителя, честно ковырялся в своем коде, но увиденное вчера меня добило окончательно: еще до разрешения прерываний просто шагаю по коду, вхожу в одну функцию, выхожу, все норм, вхожу в следующую - исключение с флагом IMPRECISERR (ошибка на шине, но адрес не определен?). При том что данный кусок кода (библиотечный) вполне успешно работал и работает при изменениях в любом другом месте программы. Т.е. от перегруппировки памяти периодически возникает какой то неработоспособный код. Правда тут более странный момент заметил, один и тот же код на одной плате может вызвать HardFault, а на другой нет. Внешнюю шину не использую. PLL настроена правильно. Были мысли насчет нестабильности частоты, но причины, недомытая плата? Тогда почему только при определенном коде? Не настаиваю, что причина в ES, буду рад услышать другое объяснение! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 8 апреля, 2011 Опубликовано 8 апреля, 2011 · Жалоба PLL настроена правильно. А FMR? Не настаиваю, что причина в ES, буду рад услышать другое объяснение! Бывает и совсем наоборот. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Атмег 0 8 апреля, 2011 Опубликовано 8 апреля, 2011 · Жалоба А FMR? в EEFC_FMR у меня 2 цикла на обращение, но MCK на порядок больше, чем 5 MHz, указанные в еррате. код из флеши исполняется, но к EEFC_FMR обращение единственный раз в стартапе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 8 апреля, 2011 Опубликовано 8 апреля, 2011 · Жалоба код из флеши исполняется, но к EEFC_FMR обращение единственный раз в стартапе. Как показывает практика, этого достаточно для появления сбоя совсем в другом месте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Атмег 0 8 апреля, 2011 Опубликовано 8 апреля, 2011 · Жалоба Это я взял как есть из примера. Как будет очередной сбой - проверю, это ли явилось причиной. Запись в регистр str r2,[r1] Мне казалось, проблем здесь не возникает, я же не пишу/читаю из флеши в момент записи? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 8 апреля, 2011 Опубликовано 8 апреля, 2011 · Жалоба Запись в регистр str r2,[r1] Мне казалось, проблем здесь не возникает, я же не пишу/читаю из флеши в момент записи? В том-то и дело, что читает не ядро непосредственно, а контроллер флеш в свои внутренние буферы. И узнать, чем он занимается в данный момент, не представляется возможным. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться