ошибка micros ()??

Пито
Ср 26 апреля 2017 г. 16:44
Продолжение от http: // www.STM32duino.com/viewtopic.PHP ... 065#P27066

Во время управления демонстрацией скамейки SDFAT на Black407ze, ядро ​​Дэниела:

Может быть, ошибка? Во время игры с SDFAT я время от времени получаю это странное огромное количество.
Число всегда одно и то же 42949665553, кажется,.
Источник говорит, что он измеряет максимальную отдачу через micros (), сравнивает и делает простое дополнение. Все подлины.
Затем он распечатывает материал: cout << s/t <<',' << maxLatency << ',' << minLatency; cout << ',' << totalLatency/n << endl;

Пито
Ср 26 апреля 2017 г., 17:10
Он также связывается со стандартом SDFAT и небольшим буфером 512B (печатные задержки проходят через серийные.print ()): read speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 865.00,2446,476,591 866.50,1355,476,590 867.25,1656,476,589 866.50,4294966815,476,589 866.50,1439,476,590 866.50,1380,476,590 866.50,4294966873,476,589 866.50,1367,476,590 866.50,1410,476,590 866.50,1394,476,590 Done

victor_pv
Ср 26 апреля 2017 г., 17:44
Пито написал:Он также связывается со стандартом SDFAT и небольшим буфером 512B (печатные задержки проходят через серийные.print ()): read speed and latency speed,max,min,avg KB/Sec,usec,usec,usec 865.00,2446,476,591 866.50,1355,476,590 867.25,1656,476,589 866.50,4294966815,476,589 866.50,1439,476,590 866.50,1380,476,590 866.50,4294966873,476,589 866.50,1367,476,590 866.50,1410,476,590 866.50,1394,476,590 Done

Пито
Ср 26 апреля 2017 г. 18:09
С вашими микропроводами в STM32_Clock.H, и печать «t» (в миллисе) в первом столбце (вместо S/T), кажется, T в порядке. inline uint32_t micros() { // return (HAL_GetTick()*1000) + ((SysTick->LOAD - SysTick->VAL) * 1000 / SysTick->LOAD); //return (HAL_GetTick()*1000) + (((SysTick->LOAD - SysTick->VAL) * 1000) / SysTick->LOAD); return (HAL_GetTick()*1000) + (SysTick->VAL / (SystemCoreClock / 1000000)); }

Даниэфф
Ср 26 апреля 2017 г. 18:36
Я верю в Систер->Вэл отсчитывает от Systick->Загрузить до 0.
Поэтому, если вы используете `return (hal_gettick ()*1000) + (systick->Val / (SystemCoreClock / 1000000)); `
и печать Serial.println(micros()); Serial.println(micros()); delay(3000);

Пито
Ср 26 апреля 2017 г. 18:46
Я возвращаю Millis () из вышеупомянутого micros () в качестве теста, не перезаписываются ли цифры микросхемы, повторяются несколько раз: inline uint32_t micros() { // return (HAL_GetTick()*1000) + ((SysTick->LOAD - SysTick->VAL) * 1000 / SysTick->LOAD); // return (HAL_GetTick()*1000) + (((SysTick->LOAD - SysTick->VAL) * 1000) / SysTick->LOAD); // return (HAL_GetTick()*1000) + (SysTick->VAL / (SystemCoreClock / 1000000)); return millis(); }

victor_pv
Ср 26 апреля 2017 г. 18:51
Пито написал:С вашими микропроводами в STM32_Clock.H, и печать «t» (в миллисе) в первом столбце (вместо S/T), кажется, T в порядке. inline uint32_t micros() { // return (HAL_GetTick()*1000) + ((SysTick->LOAD - SysTick->VAL) * 1000 / SysTick->LOAD); //return (HAL_GetTick()*1000) + (((SysTick->LOAD - SysTick->VAL) * 1000) / SysTick->LOAD); return (HAL_GetTick()*1000) + (SysTick->VAL / (SystemCoreClock / 1000000)); }

Пито
Ср 26 апреля 2017 г., 19:08
С -O0 и inline uint32_t micros() { return (HAL_GetTick()*1000) + ((SysTick->LOAD - SysTick->VAL) * 1000 / SysTick->LOAD); //return (HAL_GetTick()*1000) + (((SysTick->LOAD - SysTick->VAL) * 1000) / SysTick->LOAD); //return (HAL_GetTick()*1000) + (SysTick->VAL / (SystemCoreClock / 1000000)); }

Пито
Ср 26 апреля 2017 г., 19:25
inline uint32_t micros() { return (HAL_GetTick()*1000) + ((SysTick->LOAD - SysTick->VAL) * 1000 / SysTick->LOAD); //return (HAL_GetTick()*1000) + (((SysTick->LOAD - SysTick->VAL) * 1000) / SysTick->LOAD); //return (HAL_GetTick()*1000) + (SysTick->VAL / (SystemCoreClock / 1000000)); }

Пито
Ср 26 апреля 2017 г., 19:44
Может это помогает: return (HAL_GetTick()*1000ULL) + ((SysTick->LOAD - SysTick->VAL) * 1000ULL / SysTick->LOAD);

victor_pv
Ср 26 апреля 2017 г., 19:47
Пито написал:inline uint32_t micros() { return (HAL_GetTick()*1000) + ((SysTick->LOAD - SysTick->VAL) * 1000 / SysTick->LOAD); //return (HAL_GetTick()*1000) + (((SysTick->LOAD - SysTick->VAL) * 1000) / SysTick->LOAD); //return (HAL_GetTick()*1000) + (SysTick->VAL / (SystemCoreClock / 1000000)); }

victor_pv
Ср 26 апреля 2017 г. 20:02
Я думаю, что лучше всего разбить его в отдельных инструкциях с промежуточными переменными, поэтому компилятор лучше вынужден делать то, что хочет.
inline uint32_t micros() { uint32_t tmp, tmp2; tmp = (SysTick->LOAD - SysTick->VAL) * 1000 / SysTick->LOAD); tmp2 = (HAL_GetTick()*1000); return tmp+tmp2; }

Пито
Ср 26 апреля 2017 г. 20:55
Я пытался, точно так же. расщепление (несколько вариантов) на (нестабильные) vars a, b, c - то же самое.
Я начинаю думать, что это не о Micros (), а что -то со стеком или как.
Когда я печатаю «m» от m = micros (), я получаю число, скажем, от 254 до 257. Нет проблем. Я могу распечатать это. Я вижу это, никаких аномалий (я не комментирую саму ценность). Редактировать: Нет, M сравнивается внутри цикла.
Затем в максимальной степени (где это требует больше M), я вижу Bignumber Printed.

И это история о максимальной степени - это делается в циклах, петли - n = файлы размером/буферизации: m = micros() - m; if (maxLatency < m) { maxLatency = m; }

Пито
Чт 27 апреля 2017 г. 2:41
Это сработало лучше всего вчера вечером :) inline uint32_t micros() { // by Pito 4/2017 uint32_t m = HAL_GetTick(); uint32_t u = SysTick->LOAD - SysTick->VAL; uint32_t m1 = HAL_GetTick(); uint32_t u1 = SysTick->LOAD - SysTick->VAL; if (m1 > m) { return ( m1 * 1000 + (u1 * 1000) / SysTick->LOAD); } else { return ( m * 1000 + (u * 1000) / SysTick->LOAD); } }

Пито
Чт 27 апреля 2017 г. 9:42 утра
После ночи, проведенной с проблемой - измерения показывают, что это ошибка в оригинальном способе создания micros ().
Оригинал Micros (): return (HAL_GetTick()*1000) + ((SysTick->LOAD - SysTick->VAL) * 1000 / SysTick->LOAD);

victor_pv
Чт 27 апреля 2017 г. 13:38
Пито написал:После ночи, проведенной с проблемой - измерения показывают, что это ошибка в оригинальном способе создания micros ().
Оригинал Micros (): return (HAL_GetTick()*1000) + ((SysTick->LOAD - SysTick->VAL) * 1000 / SysTick->LOAD);

Пито
Чт 27 апреля 2017 г. 14:16
Я понимаю, что моя реализация Micros () звучит безумно, но она работает, это кажется.
Ошибка связана с «моментом», когда вы обратите внимание на Millis VS. дробная часть (проблема метастабильности). В многоступном трубопроводе и ситуации с прерывами это может произойти Миллис, а дробная часть не совпадает..
Имейте в виду, что возникновение ошибки составляет ~ 1: xxx000, в то время как вы читаете Micros () 3000x в секунду с внешним временем отклика устройства «CPU Clock Clock (то есть SDCARD).
Я распечатал дробную часть - это нормально. Единственный источник ошибки - Миллис против. дробная часть.
Вы можете создать свои собственные тесты, чтобы подтвердить это, но мое нынешнее понимание, да, существует «высокая» вероятность, что процессор испортит Миллис против. дробная часть на основе циллионных факторов, таких как Millis 1, меньше, как и ожидалось.

Даниэфф
Чт 27 апреля 2017 г. 15:20
Libmaple также делает это «проверьте, изменился ли Миллис» https: // github.com/rogerclarkmelbourne/ ... время.H#L56

Я буду использовать вашу реализацию, если не найдено лучше.

victor_pv
Чт 27 апреля 2017 г. 15:33
Даниэль, я бы сказал, что на данный момент Пито лучше, чем что -либо еще, так что, возможно, захотел его толкнуть, тогда, если мы найдем что -то лучшее заменить. Его может занять немного больше времени, но если это приводит к правильной стоимости, намного лучше, чем риск в текущем.

Что касается Libmaple, он проверяет регистр в таймере Systick, чтобы проверить, переполняется ли он после прочтения. (или недостаточно, так как это, кажется, рассчитывается) /** * @brief Check for underflow. * * This function returns 1 if the SysTick timer has counted to 0 since * the last time it was called. However, any reads of any part of the * SysTick Control and Status Register SYSTICK_BASE->CSR will * interfere with this functionality. See the ARM Cortex M3 Technical * Reference Manual for more details (e.g. Table 8-3 in revision r1p1). */ static inline uint32 systick_check_underflow(void) { return SYSTICK_BASE->CSR & SYSTICK_CSR_COUNTFLAG; }

Пито
Пт 28 апреля 2017 г., 19:05
Есть еще один вариант, даже сексуальнее.. :)
Есть «специальный» 32 -битный счетчик часов, который просто считается (вверх), навсегда.. :)
Разрешение счетчика 5.95NS на 168 МГц.
Счетчик переполняется в 25.56 секунды.
Поэтому, когда вы хотите связываться с Nanos (), это может работать нормально. С надеждой.. : P

Пито
Пт 28 апреля 2017 г., 19:06
Есть еще один вариант, даже сексуальнее.. :)
Существует «специальный» 32 -битный счетчик CPU, который просто считается (вверх), навсегда.. :)
Разрешение счетчика 5.95NS на 168 МГц (4.166ns @240 МГц).
Счетчик переполняется в 25.56 секунды.
Поэтому, когда вы хотите связываться с micros () на основе этого счетчика или с наносом (), он может работать нормально. С надеждой.. : P
http: // www.STM32duino.com/viewtopic.PHP?F = 18&T = 2004 uint32_t elapsed = CpuGetTicks(); delayMicroseconds(1); elapsed = CpuGetTicks()- elapsed;

victor_pv
Пт 28 апреля 2017 г., 19:55
Это имеет смысл для задержкимикроса (), но как бы вы использовали его для Micros ()?