|
иструкции cortex-m3 DMB/DSB/ISB/LDREX/CLREX/TBB, читаю книгу вижу фигу |
|
|
|
May 16 2010, 09:47
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
здравствуйте. к сожалению С/C++ компиллеры не могут использовать все иструкции ядра, поскольку язык программирования (с/c++) - всетаки язык формального описания и не позволяет разработчику выразить на нем все свои желания, о которых о части позаботились разработчики ядра процессора.
в свете сказанного очевидно что без применения асма в 'узких местах" - новый процессор тановится таким же ''старым" и мы получаем дядю Васю забивающего магнитофоном гвозди.
осознание вышескзанного заставило наконецто залесть в мануал и потратить время на изучение СM3 - результат печальный. ниже приведен список команд - названи красивые и заманчивые, но мне непонятно как они работают, тоесть для чего они нужны. последняя вроде понятно как работет но непонятно кудаее можно прикрутить с максимальной пользой, в какихто алгоритмах же она заменит кучу кода - вопрос в каких. первые три особо загадочные, на них у меня большие надежды. просьба уже разобравшихся пролить свет. зарание спасибо.
Data memory barrier DMB <c> Data synchronization barrier DSB <c> Instruction synchronization barrier ISB <c> Send event SEV <c> Load register exclusive calculates an address from a base register value and an immediate offset, loads a word from memory, writes it to a register LDREX<c> <Rt>,[<Rn>{,#<imm>}] STREX <c> <Rd>,<Rt>,[<Rn>{,#<imm>}] Clear exclusive clears the local record of the executing processor that an address has had a request for an exclusive access. CLREX <c> Table branch byte TBB [<Rn>, <Rm>] Table branch halfword TBH [<Rn>, <Rm>, LSL #1]
Return number of leading zeros in register value CLZ.W <Rd>, <Rn>
|
|
|
|
|
May 16 2010, 10:39
|

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

|
Цитата(klen @ May 16 2010, 15:47)  последняя вроде понятно как работет но непонятно кудаее можно прикрутить с максимальной пользой, в какихто алгоритмах же она заменит кучу кода - вопрос в каких. Например, в scmRTOS clz используется в ф-ии GetHighPriority() - для получения наиболее приоритетного процесса из битовой маски готовых к выполнению процессов. Вот: OS_Target.h tbb вроде видел в листинге, используется при больших case. Про остальные не знаю
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
May 16 2010, 11:02
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 8-01-07
Из: Томск
Пользователь №: 24 208

|
Неплохое описание инструкций есть в юзер-мануалах на соответствующие чипы от NXP. Не смотрели их?
|
|
|
|
|
May 16 2010, 12:09
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(bseyur @ May 16 2010, 14:02)  Неплохое описание инструкций есть в юзер-мануалах на соответствующие чипы от NXP. Не смотрели их? На ну? Есть оригинальная документация от ARM. Другую рожать никто не будет. Если непонятно, то надо искать просто научно-популярные растолковывающие книжки. А из них никто еще лучше, чем Joseph Yiu не написал и не напишет. Цитата(klen @ May 16 2010, 12:47)  первые три особо загадочные, на них у меня большие надежды. Чем же они загадочны? DMB - будет требовать завершения текущих обращений к памяти до следующего обращения к памяти DSB - тоже самое, но до следующей инструкции ISB - пока pipeline не освободится. Ну как надежды? Оправдались?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
May 16 2010, 13:16
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
Цитата(zltigo @ May 16 2010, 16:09)  На ну? Есть оригинальная документация от ARM. Другую рожать никто не будет. Если непонятно, то надо искать просто научно-популярные растолковывающие книжки. А из них никто еще лучше, чем Joseph Yiu не написал и не напишет.
Чем же они загадочны? DMB - будет требовать завершения текущих обращений к памяти до следующего обращения к памяти DSB - тоже самое, но до следующей инструкции ISB - пока pipeline не освободится. Ну как надежды? Оправдались? а черт его знает, пока непонятно, а в каких случаях это может пригодится? а можете привести ситуации когда без них становится нехорошо, что бы понятно стало а то както туго, инструкции есть а вставить куда не придумаю, значит непонимаю назначение. спасибо глянул книжку Joseph Yiu по диагонали - супер. аж перевести захотелось для таких как я, только времени на это нет. магазинам Нада не киты продавать а покупать лицензию на книгу переводить и продвать сначала ее, тогда китов наверно больше можно былобы продать. я бы так бизныс построил. я уверен что большинство программеров включая меня используют кортекс как armv4, да компиляторы тоже подкосили многих - зачем напрягатся - и так скомпилил и работает
|
|
|
|
|
May 16 2010, 14:18
|
Участник

Группа: Участник
Сообщений: 65
Регистрация: 8-01-07
Из: Томск
Пользователь №: 24 208

|
Цитата(zltigo @ May 16 2010, 19:09)  На ну? Есть оригинальная документация от ARM. Другую рожать никто не будет. Если непонятно, то надо искать просто научно-популярные растолковывающие книжки. А из них никто еще лучше, чем Joseph Yiu не написал и не напишет. Ну как же. Глава 34. Где в оригинальной документации ARM столь доходчиво приведено описание ядра М3?
|
|
|
|
|
May 16 2010, 15:30
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
Цитата(igorsk @ May 16 2010, 19:18)  TBB/TBH применяются нормальными компиляторами для реализации оператора switch. Большинство остальных инструкций используются для многопоточной синхронизации - семафоры, мьютексы, критические секции и т.п. вот я так и думал а что если синхронизация задач ускорить получится в FreeRTOS, только мне пока непонятно как это сделать да, действительно gcc генерит tbb для выбора ветки в switch/case если ключи case идут подряд или с малыми дырками, иначе компилер решает что размер таблицы неприемлем и начинает генерить условный выбор ветки НУ ВОТ!, я разобрасля с tbb теперь знаю как писать switch чтоб он быстро работал - ранее я избегал этой конструкции как класса, их у мен небыло вообще. лично для меня польза от этой ветки форума уже очевидна. спасибо. едем дальше...
|
|
|
|
|
May 7 2011, 14:31
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Я вот только не пойму, как эти 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 мютекс  )
|
|
|
|
|
May 9 2011, 13:40
|
Частый гость
 
Группа: Участник
Сообщений: 169
Регистрация: 31-08-05
Из: New York
Пользователь №: 8 118

|
Вот пример программного сброса, использующий DSB: CODE void SoftRestart( void ) { NVIC_GenerateSystemReset(); __DSB(); while(1) { } }
--------------------
ASB
|
|
|
|
|
May 9 2011, 19:12
|
Участник

Группа: Участник
Сообщений: 72
Регистрация: 7-01-11
Пользователь №: 62 073

|
Вот мне тоже интересно, так уж ли в этом коде необходимо 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 */ }
|
|
|
|
|
May 9 2011, 20:10
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
не нужен стопудово. у меня хендмейд ось и все пахает отлично. DSB/DMB может на STM32 понадобится только при работе с DMA и то в редких случаях, MPU там нету. а здесь, на пример, без isb глюканет Код аsm volatile(" mrs r0,CONTROL; orr r0,2; msr CONTROL,r0; ISB" : : :"r0"); blablabla();
|
|
|
|
|
May 15 2011, 07:40
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Цитата(brag @ May 15 2011, 01:26)  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; }
|
|
|
|
|
May 15 2011, 20:16
|
Профессионал
    
Группа: Свой
Сообщений: 1 047
Регистрация: 2-12-06
Из: Kyiv, Ukraine
Пользователь №: 23 046

|
Цитата В каком это смысле? Значит ли это, что следующий код не делает того, что должен? этот код работать на Cortex-M3 не будет, тк там нету инструкции SWP LDREX/STREX толку очень мало, тк флаг сбрасывается при возникновении любого исключения (во избежание напорки на to,что я выше цитировал с документа). Те, если выполнилась Ldrex и возникло исключение, то STREX всегда вылетает с ошибкой и нужно делать повтор - производительность хуже, чем просто запретить прерывания на короткий участок. а с SWP такого небыло, и ее похерили. причины они изложили,почему так сделали(можно почитать в документе DHT0008A), но могли бы и оставить... А еще лучше - сделать, чтобы флаг не сбрасывался при возникновении исключения, и чтобы STREX нормально возвращала ошибку, если адрес не совпадает с предшествующей LDREX. Тогда и красивый lock-free код получится в ядре операционки...
|
|
|
|
|
Jan 22 2014, 18:44
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Встряхну тему. Только что напоролся на интересную штуку. Код считает 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 не успевало включаться и команда сброса не отрабатывалась. Теперь работает. Надеюсь, поможет кому-нибудь не наступить на грабли.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 23 2014, 08:27
|
Местный
  
Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127

|
Цитата(Сергей Борщ @ Jan 23 2014, 04:28)  Работает. А может дело не в инструкции, а в задержке. Может и с __nop() будет работать?
|
|
|
|
|
Oct 3 2017, 17:11
|
Частый гость
 
Группа: Свой
Сообщений: 89
Регистрация: 11-01-05
Из: Беларусь, Минск
Пользователь №: 1 897

|
Наткнулся на интересный баг в STM32F767. Эзернет работает, но иногда в Wireshark проскакивают пакеты TCP DUP ACK и Retransmission. Ложится передача на 0.3с, что для моего устройства с модбас критично. Проблема устраняется редактированием файла stm32f7xx_hal_eth.c В функции HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength) перед Код /* When Tx Buffer unavailable flag is set: clear it and resume transmission */ if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET) { /* Clear TBUS ETHERNET DMA flag */ (heth->Instance)->DMASR = ETH_DMASR_TBUS; /* Resume DMA transmission*/ (heth->Instance)->DMATPDR = 0; } вставляем инструкцию __DSB(); Подозрение, что не успевают обновляться данные в DMASR и получаем ложную ошибку
--------------------
ex740104/103 БГУИР
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|