-
Постов
278 -
Зарегистрирован
-
Посещение
-
А почему вы считаете что я хочу сделать flush для кэшей чтения? Я хочу отключить кэширование совсем на время работы с внешней флэш памятью. Чтобы быть уверенным что все данные из кэша перенеслись в свои положенные места я делаю flush. Из мануала к компилятору: The disable_data_cache function does not flush back to memory any modified data in the cache that is cached in write-back mode. To flush any such data, use the flush_data_cache Да, хорошая статья. Уже встречал её пока искал ответ. Но как правильно делать отключение там не нашел)
-
Шина... ну обычная параллельная шина данных, где A0...A23, D0...D16, где SDRAM и остальное подключается 🙂 Память тоже обычная, NOR, с адресом 0x2000 0000 на шине. Я в механизме кэширования не разбирался, много там всего и задается в конфигураторе проекта. Оптимизацией этого дела не занимался, но суть в том что есть буфер в L1 кэше и данные сначала пишутся-читаются туда и контроллер каждый раз не обращается к внешней памяти для ускорения доступа к данным. Контроллер Blackfin BF-548. Про порядок вызова и запрет прерываний ничего не нашел, только про то что disable не делает flush и его надо вызывать отдельно. Думаю что общий подход с управлению кэшированием должен быть одинаковый что в ARM, что в Blackfin, поэтому я тут и создал тему. Типа, сначала отключаем, потом сливаем. Это же стандартная фича современных контроллеров. Надо унифицировать место из которого растут руки)) а то вот новая плата пришла, а там флеш новая без предупреждения, которая пишется по-другому. Зачем нам такие сюрпризы)
-
flash память, управление кэшем данных и прерывания
kochevkv опубликовал тема в Программирование
Нужно ли отключать кэширование данных при перепрошивке параллельной флеш памяти, которая сидит на общей адресной шине? А если нужно, то каков правильный порядок отключения кэширования? { uint32_t saveInts = cli(); // Отключаем прерывания flush_data_cache(); // Скидываем все данные из кэша disable_data_cache(); // Отключаем кэширование sti( saveInts ); // Включаем прерывания } Или, может быть сначала disable, а потом flush? И нужно ли отключать прерывания в этот момент. Ведь, в прерываниях возможна запись в память и, соответственно, изменения в кэше данных. И, так, вопросик вдогонку. Почему флеш памяти имеют разные команды для работы с ними и даже одинаковые команды имеют разные пред-команды перед ними? У одной команда 0x90 просто одним тактом задается, у другой надо 0x55 0xAA записать сначала. Что за анти-унификация в мире электроники? Может быть есть какой-то стандарт, которого придерживаются не все и надо искать производителя делающего память по стандарту? -
Опрос по системам хранения данных
kochevkv ответил Segment тема в Программирование
Да, по описанию обычная SD карта в корпусе микросхемы. Спасибо за даташит, я на такие не натыкался -
Может тут? https://github.com/azemb-todd/azure-rtos_guix Простите, я теперь понял в чем был изначальный вопрос. Типа такого еще есть https://github.com/CURTLab/LVGLBuilder 100%
-
Вот тут ребята остановились на Azure rtos guix https://habr.com/ru/articles/673944/ Ну и в комментах предлагают QT и lvgl
-
Да, он уже старичок) лет 15 наверно точно есть. Но для слабых платформ неплох, есть все основные примитивы, антиализинг, в том числе в шрифтах. Все просто и понятно.
-
Для stm и nxp emwin был в виде lib файлов. К нему шел редактор окон под windows, конвертер шрифтов и еще чего-то там. На работе для stm вроде лежал скачаный архив. Доки наemwin хорошие
-
Опрос по системам хранения данных
kochevkv ответил Segment тема в Программирование
Это где такие водятся? И если вы их называете SD карты, то это 4 битный параллельный канал данных, а eMMC я видел обычно 8 бит. Но суть одна - NAND с контроллером интерфейса и, возможно, контроллером износа ячеек. Из плюсов - простота использования и объем. Минусом такого решения может стать необходимость выделения буфера примерно на 0.5...1 секунду записи данных, что нужно при непрерывной записи данных (т.к. контролллер флешки иногда чем-то занимается во время записи), а если там еще и обертка из файловой системы, то надо еще учесть задержки на поиск системой свободных кластеров при фрагментации (это для FAT32, может есть более быстрые ФС). Для ПК буфер не проблема, а вот в контроллере может и не быть несколько лишних сотен килобайт. -
// Настройка таймера void SampleFreqConfigure( void ) { { static const gpt_config_t gptConfig = { .clockSource = S_GPT_CLOCK_SOURCE, .divider = 1, .enableFreeRun = true, .enableRunInWait = false, .enableRunInStop = false, .enableRunInDoze = false, .enableRunInDbg = false, .enableMode = false }; GPT_Init( S_GPT, &gptConfig ); } GPT_SetClockDivider( S_GPT, 1 ); GPT_SetOutputOperationMode( S_GPT, kGPT_OutputCompare_Channel3, kGPT_OutputOperation_Toggle ); GPT_EnableInterrupts( S_GPT, kGPT_OutputCompare3InterruptEnable ); NVIC_SetPriority( S_GPT_IRQ_ID, 0 ); EnableIRQ( S_GPT_IRQ_ID ); } // Включение таймера void SampleFreqOn( float convFreq ) { { uint32_t gptClock = CLOCK_GetFreq( S_GPT_CLOCK ); uint32_t compareValue = ( (float)gptClock / convFreq ) + (float)0.5; s_conversionCycles = (float)0.0000025 * gptClock; float mult = (float)0.000001; s_conversionOffCicles = mult * gptClock; s_conversionOnCicles = compareValue - s_conversionOffCicles; s_b_convOffCycle = false; s_ocrValue = 0; s_b_firstCall = true; S_GPT_IRQ_HANDLER(); } s_dtInx = 0; for( ptrdiff_t i = 0; i < 256; i++ ) { s_dt[i] = 0; } GPT_StartTimer( S_GPT ); // Start Timer } // Прерывание __RAMFUNC(RAM2) void S_GPT_IRQ_HANDLER( void ) { // Clear interrupt flag if( GPT_GetStatusFlags( S_GPT, kGPT_OutputCompare3Flag ) ) { GPT_ClearStatusFlags( S_GPT, kGPT_OutputCompare1Flag | kGPT_OutputCompare2Flag | kGPT_OutputCompare3Flag | kGPT_InputCapture1Flag | kGPT_InputCapture2Flag | kGPT_RollOverFlag ); } else { GPT_ClearStatusFlags( S_GPT, kGPT_OutputCompare1Flag | kGPT_OutputCompare2Flag | kGPT_InputCapture1Flag | kGPT_InputCapture2Flag | kGPT_RollOverFlag ); if( !s_b_firstCall ) { return; } } uint32_t test = 0; uint32_t ocr = s_ocrValue; if( s_dtInx < s_dtInxMax ) { SysTick->VAL = 0; s_dt[s_dtInx] = S_GPT->CNT - ocr; s_st[s_dtInx] = s_stConst - SysTick->VAL; s_dtInx++; SysTick->VAL = 0; test = S_GPT->CNT; s_st[s_dtInx] = s_stConst - SysTick->VAL; s_dtInx++; SysTick->VAL = 0; s_dt[s_dtInx] = 0xFF; s_st[s_dtInx] = s_stConst - SysTick->VAL; s_dtInx++; } s_b_firstCall = false; if( s_b_convOffCycle ) { s_ocrValue += s_conversionOnCicles; GPT_SetOutputCompareValue( S_GPT, kGPT_OutputCompare_Channel3, s_ocrValue ); GPT_SetOutputOperationMode( S_GPT, kGPT_OutputCompare_Channel3, kGPT_OutputOperation_Clear ); s_b_convOffCycle = false; } else { s_ocrValue += s_conversionOffCicles; GPT_SetOutputCompareValue( S_GPT, kGPT_OutputCompare_Channel3, s_ocrValue ); GPT_SetOutputOperationMode( S_GPT, kGPT_OutputCompare_Channel3, kGPT_OutputOperation_Set ); s_b_convOffCycle = true; } // Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F, Cortex-M7, Cortex-M7F Store immediate overlapping // exception return operation might vector to incorrect interrupt SDK_ISR_EXIT_BARRIER; if( s_dtInx < s_dtInxMax ) { s_st[s_dtInx] = s_stConst - SysTick->VAL; s_dtInx++; } } s_dt - массив с разницей между установленным значением срабатывания таймера OCR и значением счетчика таймера при входе в обработчик. На картинке видно что первый раз эта разница 116 циклов таймера, а в последующих 31 и 44 в зависимости от текущей фазы 0 или 1 на выходе и значения OCR. Генерится красивый сигнал 10 кГц с импульсами 1 мкс. s_st - массив значений системного счетчика. Что к чему я подписал на картинке. Видно что читает регистр счетчика GPT очень долго. Похоже проблема где-то в этом. Частота тактирования таймера GPT 75 МГц. Т.е. в 8 раз ниже частоты ядра. Все "функции" GPT это макросы в хедере к нему. Это не должно тормозить
-
Да, наивысший приоритет назначил. Да, у меня пока там ничего больше и не вызывается.
-
Скорость вызова функции обработки прерывания на Cortex M7
kochevkv опубликовал тема в Программирование
Есть функция, которая должна обрабатывать выборки с АЦП. Привязка к событию на таймере GPT2. Тактовая частота 600 МГц. Время от события сравнения в таймере и входом в функцию обработчика прерывания при первом вызове обработчика около 1200 тактов процессора, а последующие вызовы занимают около 500 тактов. Обработчик разместил в RAM_ITC. Все глобальные переменные используемые в прерывании в RAM_DTC. Вызовов каких то других функций из FLASH или SDRAM нет. Поясните что я делаю не так и почему первый вызов занимает гораздо больше чем последующие? Притом что перед стартом таймера я уже попробовал предварительно обработчик вызывать впустую. Время первого рабочего вызова сократилось, но не до значения последующих. Получается что меньше 1,5...2 микросекунд реакции на прерывание не добиться? -
Большой текстовый файл где указаны все массивы и переменные. Хорошо бы было если б он был сделан как файл с разделителями, но там не совсем так. Если знаете ключ - то я буду рад тоже его узнать) Там все в куче - и переменные, и массивы. Десятка 2-3 это скромно очень. Открыл, ужаснулся и нашел утилиту, которой вполне удовлетворен, но думал может есть что-то более распространенное и общепринятое, а не утилита с гитхаба какого-то энтузиаста. Согласен) надо было мне написать "при сборке", тогда б не так неграмотно было бы.
-
Не. И такого окошка нет. Ну ладно. Хорошо хоть сторонняя утилитка от энтузиаста работает более менее нормально.
-
Что-то не находится такая панелька. Обе дебажные, а остальное вообще непойми зачем, пустые при открытии. У вас одна из mcuxpresso или sw4stm32 ?