KRS 1 17 мая, 2010 Опубликовано 17 мая, 2010 · Жалоба Есть статья ARM Synchronization Primitives Development Article http://infocenter.arm.com/help/topic/com.a..._primitives.pdf У Cortex-M3 глобального монитора нет, адреса по которым делаются LDREX/STREX он не сечет. Флаг один на все, поэтому барьеры никаике ставить не надо. Но все отлично работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
brag 0 7 мая, 2011 Опубликовано 7 мая, 2011 · Жалоба Я вот только не пойму, как эти LDREX/STREX юзать на практике... Допустим,тот же пример из того же DHT0008A LDR r1, =locked 1: LDREX r2, [r0] CMP r2, r1; Test if mutex is locked or unlocked BEQ %f2; If locked - wait for it to be released, from 2 STREXNE r2, r1, [r0]; Not locked, attempt to lock it CMPNE r2, #1; Check if Store-Exclusive failed BEQ %b1; Failed - retry from 1 ; Lock acquired DMB; Required before accessing protected resource BX lr 2; Take appropriate action while waiting for mutex to become unlocked WAIT_FOR_UPDATE B %b1; Retry from 1 Допустим, 1. тред1 выполнил LDREX r2, [r0] (r0=mutex1) 2. тред3 выполнил LDREX r2, [r0] (r0=mutex2), допустим даже отработал до конца(тк время отведенное ему довольно много, по сравнению с размером данной фунцкии), т.е взял mutex2, и что-то там еще делал 3. тред1 продолжнил выполнятся, дошел до STREXNE r2, r1, [r0] (r0=mutex1) и приплыли (из arm_architecture_v7m_reference): The result of executing a Store-Exclusive instruction to an address that is different from that used in the preceding Load-Exclusive instruction is unpredictable. Получается LDREX...STREX надо пихать в критическую секцию или выполнять в SVC-обработчике, так зачем они тогда нужны ? ну разве что в приложении только 1 мютекс :)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aleksandr Baranov 1 9 мая, 2011 Опубликовано 9 мая, 2011 · Жалоба Вот пример программного сброса, использующий DSB: void SoftRestart( void ) { NVIC_GenerateSystemReset(); __DSB(); while(1) { } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
brag 0 9 мая, 2011 Опубликовано 9 мая, 2011 · Жалоба толку там от DSB, если и так в вечном цикле виснем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
akimych 0 9 мая, 2011 Опубликовано 9 мая, 2011 · Жалоба Вот мне тоже интересно, так уж ли в этом коде необходимо DSB. Но core_cm3.h от STM32 библиотеки оно тоже есть. static __INLINE void NVIC_SystemReset(void) { SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ __DSB(); /* Ensure completion of memory access */ while(1); /* wait until reset */ } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
brag 0 9 мая, 2011 Опубликовано 9 мая, 2011 · Жалоба не нужен стопудово. у меня хендмейд ось и все пахает отлично. DSB/DMB может на STM32 понадобится только при работе с DMA и то в редких случаях, MPU там нету. а здесь, на пример, без isb глюканет аsm volatile(" mrs r0,CONTROL; orr r0,2; msr CONTROL,r0; ISB" : : :"r0"); blablabla(); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
brag 0 14 мая, 2011 Опубликовано 14 мая, 2011 · Жалоба a SWP хорошая была инструкция, зря похерили. теперь думай башка, как сделать lock-free Queue с кучей райтеров и одним ридером... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 15 мая, 2011 Опубликовано 15 мая, 2011 · Жалоба a SWP хорошая была инструкция, зря похерили. теперь думай башка, как сделать lock-free Queue с кучей райтеров и одним ридером... В каком это смысле? Значит ли это, что следующий код не делает того, что должен? // Contributed by Bo Granlund. static unsigned long interlockedexchange( volatile unsigned long * oldval, unsigned long newval) { long result; asm volatile ( "\n\t" "swp %0,%2,[%1] \n\t" "" : "=&r"(result) : "r"(oldval), "r"(newval) : "memory"); return result; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
brag 0 15 мая, 2011 Опубликовано 15 мая, 2011 · Жалоба В каком это смысле? Значит ли это, что следующий код не делает того, что должен? этот код работать на Cortex-M3 не будет, тк там нету инструкции SWP LDREX/STREX толку очень мало, тк флаг сбрасывается при возникновении любого исключения (во избежание напорки на to,что я выше цитировал с документа). Те, если выполнилась Ldrex и возникло исключение, то STREX всегда вылетает с ошибкой и нужно делать повтор - производительность хуже, чем просто запретить прерывания на короткий участок. а с SWP такого небыло, и ее похерили. причины они изложили,почему так сделали(можно почитать в документе DHT0008A), но могли бы и оставить... А еще лучше - сделать, чтобы флаг не сбрасывался при возникновении исключения, и чтобы STREX нормально возвращала ошибку, если адрес не совпадает с предшествующей LDREX. Тогда и красивый lock-free код получится в ядре операционки... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 22 января, 2014 Опубликовано 22 января, 2014 · Жалоба Встряхну тему. Только что напоролся на интересную штуку. Код считает CRC: #include <stm32f10x.h> config_t::crc_t config_storage::calculate_crc(config_t const & from, uint32_t const * end) { config_t::crc_t Result; RCC->AHBENR |= (1 * RCC_AHBENR_CRCEN); // enable CRC clock CRC->CR = CRC_CR_RESET; auto pSrc = (uint32_t const *)&from; do CRC->DR = *pSrc; while(++pSrc < end); Result = CRC->DR; RCC->AHBENR &= ~(1 * RCC_AHBENR_CRCEN); // disable CRC clock return Result; } При пошаговой отладке все отлично. А при работе без точек останова при каждом проходе получается разный результат. Долго ломал голову, пока не сделал так: RCC->AHBENR |= (1 * RCC_AHBENR_CRCEN); // enable CRC clock __DSB(); CRC->CR = CRC_CR_RESET; Если я правильно предполагаю, тактирование блока CRC не успевало включаться и команда сброса не отрабатывалась. Теперь работает. Надеюсь, поможет кому-нибудь не наступить на грабли. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 22 января, 2014 Опубликовано 22 января, 2014 · Жалоба Если я правильно предполагаю, тактирование блока CRC не успевало включаться и команда сброса не отрабатывалась. Теперь работает. интересно, а с DMB будет работать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 23 января, 2014 Опубликовано 23 января, 2014 · Жалоба интересно, а с DMB будет работать?Работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vlad_new 1 23 января, 2014 Опубликовано 23 января, 2014 · Жалоба Работает. А может дело не в инструкции, а в задержке. Может и с __nop() будет работать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 23 января, 2014 Опубликовано 23 января, 2014 · Жалоба А может дело не в инструкции, а в задержке. Может и с __nop() будет работать? может не хватить! потому что текст на С, там и так скорее всего есть 1 -2 инструкции между записями (константу хотя бы загрузить) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 23 января, 2014 Опубликовано 23 января, 2014 · Жалоба А может дело не в инструкции, а в задержке. Может и с __nop() будет работать?Конечно дело в задержке. Но чем nop() лучше специально заточенной инструкции, которая занимает ровно столько же места и выполняется не быстрее и не дольше чем нужно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться