Jump to content

    

AVI-crak

Участник
  • Content Count

    251
  • Joined

  • Last visited

Everything posted by AVI-crak


  1. stm32 SPI

    Неужели так важна нулевая задержка между сообщениями? По сути, если не гоняться за минимальной задержкой - она сама по себе уменьшится, как-бы глупо это не звучало. Просто не нужно вот так кровь из носу отдавать или принимать сообщения, всё гораздо проще. Два кольцевых буфера на каждой стороне. И по два указателя голова/хвост. На стороне мастера: буфер на передачу с разрешением записи в него, указатель головы для него с разрешением записи, указатель хвоста для буфера приёма - с разрешением записи, сам буфер приёма - только чтение, хвост буфера передачи - только чтение, голова буфера приёма - только чтение. На стороне слейва такая-же структура, с небольшими изменениями. А теперь запускаем мастер через таймер, с выхлопом на ногу ce, на максимально допустимой скорости, и просто пользуемся кольцевыми буферами - что может быть проще? Ну да, кольцевые буферы будут постоянно перезаписываться и обновляться. Но при сохранении целостности алгоритма - изменения будут только в свободной области. То-есть сначала проверка возможности записи, потом обновление инфы (которая возможно улетит в неполном варианте), потом обновление указателя. Пока приёмная сторона не обновит указатель хвоста - вся эта область считается занятой. Размеры кольцевых буферов нет смысла делать больше 512 байт, будет только медленнее. При таких условиях задержка получается меньше 1мс. Ошибки могут возникнуть по вине дма на очень высокой скорости и общем напряге системы. Но такое ещё нужно додуматься нагородить - не каждому под силу.
  2. Для arm можно собирать независимый от адреса код, но для одного проекта это будет две независимых настройки компиляции - и целый океан боли. Сначала собирается статический код - максимально возможно без ошибок, даже самых незначительных. И уже поверх статики - компилируется перемещаемый код. Бользаключаетсявследующем, когда вам нужно чуть-чуть изменить уровень железа - придётся откатываться почти на самое начало, и проходить весь путь заново. В этом процессе появляются новые ошибки, в самых непредсказуемых местах. Есть хорошие ошибки - которые видит сам компилятор, и есть скрытые, которые имеют зависимость от интерфейса пользователя или от внешнего воздействия. Вот тут начинается самое весёлое. Отладка в реальном времени с использованием логов - очень сильно отличается по оперативности от внутрисистемного отладчика. Для перемещаемого кода есть один большой бонус - этого кода может быть безумно много. Почти весь он связан с графикой, звуком и пост_обработкой данных. Процессы связанные с реальным временем запускать таким способом глупо, они будут гораздо медленнее исполняться из-за двойного преобразования адресов статики. То-есть в статике те-же функции реального времени будут почти в два раза меньше весить и работать в два и более раз быстрее.
  3. Ещё можно купить MT48LC32M16A2P-75, всё остальное кануло в лету.
  4. На STM32F4-Discovery стоит немощный стаб 3,3в, и отвратительная разводка силовых цепей. Эта плата годится для мигания светодиодом, и не более. Хотите получить нечто работающее -делайте собственную плату, со всеми плюшками. Помехи в цифровых системах почти всегда проходят по линии земли, вам просто необходимо выбрать точку подключения земли - чтобы не возникало токовой петли. Проще всего это выглядит на бумаге: одна точка для всех, линия с поочерёдным подключением нагрузки, изолированная земля. Как рисуется - так и должно проектироваться, в этом нет ничего сложного. Главное вовремя вспомнить товарища Кирхгофа.
  5. Это так, но при длительной записи - встроенный в карту микропроцессор оптимизирует запись, проще говоря - не снимает режим записи. Это часть оптимизации на скорость. Когда чтение чередуется с записью - команды выполняются безусловно. Этот эффект можно увидеть на графиках скорости записи разных карт одного класса, всегда есть такие что чуть-чуть вырываются в перёд.
  6. https://www.lijingquan.net/wp-content/uploa...icationV6.0.pdf Страница 35. Переходы межу операциями чтения и записи - должны подтверждаться сменой статуса режима карты. Через определённое время бездействия (зависит от карты) - алгоритм сам переходит в состояние Stand-by State, даже без проверки статуса. Но это время не нормированное, почти лотерея. И да, писать драйвер для SD - это наверное второе по увлекательности занятие.
  7. JTAG + STM32

    Я тоже так думал, пока не открыл доки на используемые чипы в программаторе. Подозрения подтвердились, когда захотелось полной скорости usb на собственной отладочной плате. Без внешнего трансивера - исключительно программная поддержка usb2. Вроде бы как подключение usb2 - а скорости нет... Интерфейс JTAG (на качественном программаторе) способен работать на частотах внешнего клока в 60 МГц, что в сочетании с шестнадцатью линиями трассы - даёт скорость опроса чипа в 80 мбайт/сек. Такой поток не имеет смысла гнать напрямую, по этой причине в программаторе есть собственная память для триггеров - в комп сливаются данные которые успели измениться. Хочу сделать акцент - JTAG предназначен для очень быстрого опроса чипа в режиме отладки, скорости программирования не являются приоритетом. Нормальный JTAG - подключается почти ко всему что шевелится, он достаточно простой по протоколу, фактически стандарт. Чего нельзя сказать о программаторе на единственном чипе st - там буквально всё программное. На всех чипах st выше 100 ног - JTAG включен по умолчанию, и он таки работает. Но только не с китайскими программаторами.
  8. JTAG + STM32

    Насчёт JTAG. Если чип посредник в программаторе не имеет полноценной аппаратной поддержки usb2 - то у вас программный эмулятор JTAG, с чем вас и поздравляю.
  9. Вариант практического использования для регистров часов и даты stm32f4-7. Устанавливает дату и время на момент сборки прошивки, макрос сокращается до одиночной записи в регистр. RTC->TR = ((__TIME__[0]-'0') << 20) // hour 10 | ((__TIME__[1]-'0') << 16) // hour 1 | ((__TIME__[3]-'0') << 12) // minutes 10 | ((__TIME__[4]-'0') << 8) // minutes 1 | ((__TIME__[6]-'0') << 4) // seconds 10 | (__TIME__[7]-'0'); // seconds 1 RTC->DR = ((__DATE__[9]-'0') << 20) // year 10 | ((__DATE__[10]-'0') << 16) // year 1 | ((__TIMESTAMP__[2]=='e'?2:__TIMESTAMP__[2]=='d'?3 \ :__TIMESTAMP__[2]=='u'?4:__TIMESTAMP__[2]=='i'?5 \ :__TIMESTAMP__[2]=='t'?6:__TIMESTAMP__[0]=='M'?1:7) << 13) // Week day | ((((__DATE__[2]=='n'?(__DATE__[1]=='a'?0:5):__DATE__[2]=='b'?1 \ :__DATE__[2]=='r'?(__DATE__[0]=='M'?2:3):__DATE__[2]=='y'?4 \ :__DATE__[2]=='l'?6:__DATE__[2]=='g'?7:__DATE__[2]=='p'?8 \ :__DATE__[2] =='t'?9:__DATE__[2]=='v'?10:11)+1)/10) << 12) // Month 10 | ((((__DATE__[2]=='n'?(__DATE__[1]=='a'?0:5):__DATE__[2]=='b'?1 \ :__DATE__[2]=='r'?(__DATE__[0]=='M'?2:3):__DATE__[2]=='y'?4 \ :__DATE__[2]=='l'?6:__DATE__[2]=='g'?7:__DATE__[2]=='p'?8 \ :__DATE__[2] =='t'?9:__DATE__[2]=='v'?10:11)+1)%10) << 8) // Month 1 | ((__DATE__[4]==' ' ? 0 : __DATE__[4]-'0') << 4) // day 10 | (__DATE__[5]-'0'); // day 1
  10. У меня всё согласованно, даже бумаги с гербовой печатью есть, от этих самых старших товарищей. Но смысл того что я написал выше - намного проще. Не нужно вдаваться в мелкие детали - основное лежит на поверхности. Те модули что продаются от больших компаний - не пригодны для практического применения. Ни со стороны экономии, ни со стороны надёжности (свой колхоз всё убьёт), ни со стороны наличия требуемых интерфейсов. Идеальный модуль создать просто невозможно, найдётся задача в которой он будет не оптимален. Однако если самому делать такой модуль - то выгода есть. И кстати - получается даже дешевле чем покупной.
  11. Показать не могу, NDA и всё такое. Даже специального человека наняли - чтобы он бормашиной сдирал названия вражеских микросхем. Частотник внешний, тоже отполирован бормашиной. Потому что у нас самая защищённая вычислительная техника в мире. Драйвера для сервоприводов на майне, но там нет экстрима. Ахтунг в требовании опторазвязки для всех внешних датчиков. Движки военные, качественные, тяжёлые, коллекторные, и дико искрящие. Металл наш, по ходу с консервации. А самое прикольное. Раньше на этом станке стаяла электроника собранная на советской рассыпухе, и каким-то невероятным образом позволяла изготавливать кривые зеркальные поверхности на металле и стекле (линзы, параболы и так далее). А у меня по началу получалась аккуратная ступенька... Логично. На шести слоях нет надобности в дополнительных экранах. А вот на двухслойке... без разделения землёй провести линию рядом с другой шумной линей - просто невозможно. К тому-же эта ситуация начинается уже в шлейфе - так зачем тянуть...
  12. Давай считать: usb 2+(3 земля)+2(управление)+1(детектор)= 8 - otg порт usart 2+2(cts/rts)+1(земля)=5 - развязка по оптике на основной плате usart*2 2+1(земля)= 6 - два ведомых интерфейса на майне tim(encoder)*5 2+1(земля)+1(подтяжка)= 20 - энкодеры с развязкой по оптике tim 1= 1 - шим для управления питанием adc*3 1+(1 аналоговая земля)+1(vreg) = 9 - mcp6s28 3 штуки на майне spi 4+3(земля)= 7 - управление внешним mcp6s28 и расширителем портов на 74hc594+74hc165 tim*3 1= 3 - шим для сервомоторов spi 4+3(земля)= 7 - ведомый st чип sdmmc 6+1+6(земля)+1(питание)= 14 - разъём для sd карты eth 6+3(земля)= 9 - выход на трансформаторы развязки rj45, физика стоит на многослойке. 4 линии +2(земля)= 6 подключение резистивного тачскрина, разъём на многослойке, мозги на майне. dac*2 2+2(земля)= 4 -управление шпинделем, +динамик. 1 видеовход 1+1(земля)= 2 - ацп подключен к dcmi интерфейсу на многослойке, чёрно-белое изображение используется для юстировки инструмента. 10 горячих контактов с прямым подключением к чипу st (через защиту)= 10 - управление питанием, режимом инструмента, большая красная кнопка стоп... питание 5в = 7 контактов, земля распределена между экранами. Используется два разъёма FPC-60 по краям шестислойной печатной платы 6*5см. Майн 20*15см - двух_слойка. Этот бутерброд используется для ручного и автономного управления токарным станком. Цена разработки космическая, впрочем - я всей этой суммы не увидел... Использовать для этой цели готовые модули с линуксом - не выгодно. Хоть там и гигабайты с гигагерцами - а отклик в режиме реального времени получается чудовищным.
  13. У вас модуль имеет размеры чуть больше площади используемых бга компонентов. Предложенный вами штыревой переходник займёт площадь больше чем сами чипы. Второе, использование разъёмов с очень мелким шагом (и габаритами) - переносит технологические нормы разводки пп на основную печатную плату. С чем боролись... Есть выход: FPC- коннекторы разного шага но одинакового количества пинов + шлейф изготовленный печатным способом на пластике (есть такие). Это единственный вменяемый способ выполнить соединение на 40+ контактов без роста стоимости многослойной печатной платы. Ну и возможность оперативно почесать пузико у многослойки - как бонус.
  14. Слишком долго считает. Регистры TIM1->CCR1 не имеют теневых аналогов как у TIM1->ARR, записанное в них значение сразу начинает сравниваться. Но выход есть, завести статическую переменную, в которую считать новое значение, и при прерывании переполнения (не сравнения!!!) - записывать в регистр значение статической переменной. Получится минимальная задержка обновления, и стабильная задержка на один отчёт - которую уже можно компенсировать.
  15. М7 может выполнять код из ITCM в режиме шины AXI. Это нулевая задержка. Памяти мало, может уместиться вектора, перемывания и критический код. Стек нужно натравить на DTCM, что не совсем очевидно(стек ниже данных). Там-же расположить критические данные. А всё остальное - на свободные банки памяти и флеша. Задержка 5 тактов на 200 МГц вполне возможна, однако бессмысленна. Чип обладает развитой периферией, в которой эти задержки программируются в режиме инстала. Разная память, разные правила, настраивать регионы памяти - обязательно. http://forum.ixbt.com/topic.cgi?id=48:11266:2178#2178
  16. В чипах STM32F4 и выше - ремапа нет, в реальности нога процессора выбирает периферию. Однако можно получить вечный жёсткий отказ шины данных в случае двух ног мк на одной периферии в случае входа, выход успешно переваривается - но не имеет смысла.
  17. А что произойдёт с адресом выделенной памяти после вторичного вызова функции?
  18. Дык это программный ресет, при аппаратном ресете отладчик не успевает подключиться, по крайней мере у меня.
  19. Я говорю о том, что в момент аппаратного срабатывания триггера выбора загрузочного интерфейса - всё остальное отключается!!!!. Потому как сам механизм записи в память флеша - не имеет арбитра. Да и всего остального фарша - тоже.
  20. КАК? Каким образом смотреть содержимое ядра и адресного пространства мк в режиме явного срабатывания загрузчика по usart??? Вопрос на миллион баксов!!!
  21. Режим отладки в памяти. Программа в флеш выполняет две функции: запись адреса стека (аппаратная команда), меняет адрес массива векторов прерываний (аппаратный переход на ресет), повторный переход на новый ресет в памяти мк. При физическом нажатии ресета - память sram не искажается. Запуск кода из допустимых для данного мк областей памяти - память sram не искажается. Ресет не искажает память. Запуск бута в режиме программирования (после успешной синхронизации!!!) - всегда портит stam и стирает флеш при включённой защите (сразу!!!), стирает сам флеш по секторам при программировании (последовательно). Без успешной синхронизации - содержимое памяти не искажается при ресете. Бут является аппаратным механизмом, без использования ресурсов ядра и памяти. Но в момент полноценной работы - память stam используется в качестве буфера. Адреса массивов являются аппаратными, изменить их нельзя. Максимальный бардак в памяти получается при загрузке через usb. Вас не должно волновать содержимое памяти после срабатывания бута - к этому моменту у вас уже поменялась прошивка.
  22. case(OpenTCP): //Открытие TCP { // printf("\rOpen TCP Session\r");// GSM_State_Mashine = ConnMQTT;//Успешно GSM_Mashine_Errors = 0; // if(GPRSConnect1(TCP, MQTT_BROKER_SERVER, PORT, DEFAULT_TIMEOUT*8, DEFAULT_INTERCHAR_TIMEOUT*5) == 0) // { // эта функция всегда возвращает аргумент в регистре R0, выделять новую переменную для этого не нужно. printf("\rError TCP Open... Try Again...\r");// // int T = GPRSClose();// не вижу повторного использования Т GPRSClose(); GSM_Mashine_Errors++;// break; // } // GSM_State_Mashine = ConnMQTT;//Успешно GSM_Mashine_Errors = 0; // printf("\rTCP Session Open\r");// break;
  23. Чтобы не ресетить девайс - нужно изначально закладывать архитектуру здоровой OS, с отдельным стеком прерываний и куче стеков задач. В этом случае запуск/отключение и управление уровнем прерывания - осуществляется через активную задачу, которая вызывает системное прерывание с заведомо максимальным уровнем. Без блокировки!!! Править уровни прерываний и их очереди в теле пользовательских прерываний - это есть громадный костыль, означающий что программист накосячил в нескольких местах и не смог исправить. Если прерывание пользователя зависает в бесконечном цикле - то лучше сразу сменить род деятельности, пока более опытные товарищи вам ноги руки не по отрывали. Уход в глубокий сон выполняется по команде OS, после чего все активные задачи должны свернуть свою деятельность и уйти в зависимость, вот после этого можно сохранять на флеш - активную память задач и их стеки, с последующим отключением питания. Предусмотреть все ньюансы работы периферии - просто невозможно. Однако в самой активной задаче - вполне реально. Просто блок инициализации будет выполняться повторно при перезапуске в каждой задаче отдельно. Глубокий сон - весьма специфическое требование, его трудно выполнить качественно, всегда придётся идти на компромисс. Гораздо чаще делают более простой вариант - сохраняют только данные объявленные как статические - в энергонезависимой памяти. С копированием их в память при запуске и сохранением перед отключением.