Перейти к содержанию
    

kochevkv

Участник
  • Постов

    278
  • Зарегистрирован

  • Посещение

Репутация

1 Обычный

Информация о kochevkv

  • Звание
    Местный
    Местный
  • День рождения 14.09.1982

Контакты

  • ICQ
    Array

Информация

  • Город
    Array

Посетители профиля

3 733 просмотра профиля
  1. А почему вы считаете что я хочу сделать 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 Да, хорошая статья. Уже встречал её пока искал ответ. Но как правильно делать отключение там не нашел)
  2. Шина... ну обычная параллельная шина данных, где A0...A23, D0...D16, где SDRAM и остальное подключается 🙂 Память тоже обычная, NOR, с адресом 0x2000 0000 на шине. Я в механизме кэширования не разбирался, много там всего и задается в конфигураторе проекта. Оптимизацией этого дела не занимался, но суть в том что есть буфер в L1 кэше и данные сначала пишутся-читаются туда и контроллер каждый раз не обращается к внешней памяти для ускорения доступа к данным. Контроллер Blackfin BF-548. Про порядок вызова и запрет прерываний ничего не нашел, только про то что disable не делает flush и его надо вызывать отдельно. Думаю что общий подход с управлению кэшированием должен быть одинаковый что в ARM, что в Blackfin, поэтому я тут и создал тему. Типа, сначала отключаем, потом сливаем. Это же стандартная фича современных контроллеров. Надо унифицировать место из которого растут руки)) а то вот новая плата пришла, а там флеш новая без предупреждения, которая пишется по-другому. Зачем нам такие сюрпризы)
  3. Нужно ли отключать кэширование данных при перепрошивке параллельной флеш памяти, которая сидит на общей адресной шине? А если нужно, то каков правильный порядок отключения кэширования? { uint32_t saveInts = cli(); // Отключаем прерывания flush_data_cache(); // Скидываем все данные из кэша disable_data_cache(); // Отключаем кэширование sti( saveInts ); // Включаем прерывания } Или, может быть сначала disable, а потом flush? И нужно ли отключать прерывания в этот момент. Ведь, в прерываниях возможна запись в память и, соответственно, изменения в кэше данных. И, так, вопросик вдогонку. Почему флеш памяти имеют разные команды для работы с ними и даже одинаковые команды имеют разные пред-команды перед ними? У одной команда 0x90 просто одним тактом задается, у другой надо 0x55 0xAA записать сначала. Что за анти-унификация в мире электроники? Может быть есть какой-то стандарт, которого придерживаются не все и надо искать производителя делающего память по стандарту?
  4. Да, по описанию обычная SD карта в корпусе микросхемы. Спасибо за даташит, я на такие не натыкался
  5. Может тут? https://github.com/azemb-todd/azure-rtos_guix Простите, я теперь понял в чем был изначальный вопрос. Типа такого еще есть https://github.com/CURTLab/LVGLBuilder 100%
  6. Вот тут ребята остановились на Azure rtos guix https://habr.com/ru/articles/673944/ Ну и в комментах предлагают QT и lvgl
  7. Да, он уже старичок) лет 15 наверно точно есть. Но для слабых платформ неплох, есть все основные примитивы, антиализинг, в том числе в шрифтах. Все просто и понятно.
  8. Для stm и nxp emwin был в виде lib файлов. К нему шел редактор окон под windows, конвертер шрифтов и еще чего-то там. На работе для stm вроде лежал скачаный архив. Доки наemwin хорошие
  9. Это где такие водятся? И если вы их называете SD карты, то это 4 битный параллельный канал данных, а eMMC я видел обычно 8 бит. Но суть одна - NAND с контроллером интерфейса и, возможно, контроллером износа ячеек. Из плюсов - простота использования и объем. Минусом такого решения может стать необходимость выделения буфера примерно на 0.5...1 секунду записи данных, что нужно при непрерывной записи данных (т.к. контролллер флешки иногда чем-то занимается во время записи), а если там еще и обертка из файловой системы, то надо еще учесть задержки на поиск системой свободных кластеров при фрагментации (это для FAT32, может есть более быстрые ФС). Для ПК буфер не проблема, а вот в контроллере может и не быть несколько лишних сотен килобайт.
  10. // Настройка таймера 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 это макросы в хедере к нему. Это не должно тормозить
  11. Да, наивысший приоритет назначил. Да, у меня пока там ничего больше и не вызывается.
  12. Есть функция, которая должна обрабатывать выборки с АЦП. Привязка к событию на таймере GPT2. Тактовая частота 600 МГц. Время от события сравнения в таймере и входом в функцию обработчика прерывания при первом вызове обработчика около 1200 тактов процессора, а последующие вызовы занимают около 500 тактов. Обработчик разместил в RAM_ITC. Все глобальные переменные используемые в прерывании в RAM_DTC. Вызовов каких то других функций из FLASH или SDRAM нет. Поясните что я делаю не так и почему первый вызов занимает гораздо больше чем последующие? Притом что перед стартом таймера я уже попробовал предварительно обработчик вызывать впустую. Время первого рабочего вызова сократилось, но не до значения последующих. Получается что меньше 1,5...2 микросекунд реакции на прерывание не добиться?
  13. Большой текстовый файл где указаны все массивы и переменные. Хорошо бы было если б он был сделан как файл с разделителями, но там не совсем так. Если знаете ключ - то я буду рад тоже его узнать) Там все в куче - и переменные, и массивы. Десятка 2-3 это скромно очень. Открыл, ужаснулся и нашел утилиту, которой вполне удовлетворен, но думал может есть что-то более распространенное и общепринятое, а не утилита с гитхаба какого-то энтузиаста. Согласен) надо было мне написать "при сборке", тогда б не так неграмотно было бы.
  14. Не. И такого окошка нет. Ну ладно. Хорошо хоть сторонняя утилитка от энтузиаста работает более менее нормально.
  15. Что-то не находится такая панелька. Обе дебажные, а остальное вообще непойми зачем, пустые при открытии. У вас одна из mcuxpresso или sw4stm32 ?
×
×
  • Создать...