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

artemkad

Свой
  • Постов

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

  • Посещение

  • Победитель дней

    12

Весь контент artemkad


  1. Номинальное напряжение указанное в даташите. Иногда указано еще и максимальное - вот до него лучше не доводить... Если указано только одно, то это только номинальное или "Rated Voltage" Да. Скорее всего это ток при "номинальном напряжении" через трое суток измерения при этом напряжении(сразу после зарядки до номинала утечка больше). Да, сопротивление утечки там сильно нелинейное и при снижении напряжения ток утечки быстро падает. ЗЫ. И да, при высоких токах зарядки лучше иметь внешний балансир. Все же утечка это кипячение(нагрев) самого конденсатора, что негативно влияет на его срок службы.
  2. При превышении напряжения(даже уже при приближении к верхнему порогу) сильно возрастает утечка, что служит суррогатной балансировкой. Так что при примерно одинаковых ячейках особо проблемы нет.
  3. Если нет усадки, клеящий компонент становится изолятором между проводящими зернами. Именно усадка заставляет зерна прижиматься и в процессе этого рвать на гранях застывающую пленку.
  4. Сами STM свои МК делят на высокопроизводительные, широкого применения, малопотребляющие и беспроводные. Как их воспринимают потребители - неопределенный вопрос.
  5. H7, по мнению производителя, это не ширпотребные, а высокопроизводительные МК.
  6. Не, не, не - никакой лапши в коде. Есть отдельный файлик task_list.h в котором между #ifdef SYSTEM_TASK #endif и #ifdef TASK #endif вписывается те процедуры, что становится частью суперцикла. Заодно по этому файлу создаются все требуемые служебные массивы и идентификаторы битов таймеров и задач. Примерно так: #ifdef SYSTEM_TASK SYSTEM_TASK(task_System_mgr) // SYSTEM_TASK(task_sys_events) // задача обмена данными между sys и i2c_temp SYSTEM_TASK(task_timer_sys) // SYSTEM_TASK(init_configOut_bm) // обновление битовых масок выходов SYSTEM_TASK(EVENTS_to_FIFO_system_task) /// ................................... #endif #ifdef TASK #ifdef TRACE_TASK TASK(test_trace,tt_NULL,1) // тестовая задача #endif TASK(task_send_MSG,tt_250ms,0) // отправка сообщения #ifdef GPS_INC TASK(task_gps_test,tt_1s,0) // тест GPS-модуля TASK(task_gps_send,tt_1s,0) TASK(task_gps_backup_off,tt_1s,0) #endif /// ..................................... #endif Кстати, обращаю внимание, для Форточек пишется приложение, а не программа и потому там другой подход. Там надо встроить свой код в уже работающую систему предлагающую кучу сервиса. Почему сразу данных? Обработка общения с несколькими устройствами чем не устраивает? Вышеупомянутый проектик на 44 задачи это по сути шлюз между i2c на основной процессор и gps-приемником, gsm-модемом(с другой стороны сервер), i2c датчиком, spi-памятью, неким внешним блочком с uart-ом и своим протоколом, плюс несколькими входами/выходами. Данных там не много и почти все после обработки пролетают транзитом. Сейчас там используется "2 796 bytes of DATA memory" большая часть которых это буфера и очереди. Смотрю на ширпотребные STM32 и только у топа вижу 128кБ ОЗУ. А в основной массе до 32кБ. Где сотни?
  7. Они перестанут управляться только если какая-то задача "подвиснет". А если какая-то задача заснет, все остальное продолжит работать. По сути усыпление в рамках суперцикла это временное исключение из него части кода. Как писал выше - тут всего лишь разный подход к написанию задач. void SleepTask ( task_ht t, tt_state_t n) { n++; task_table_state[t] = n; } после чего отдать управление дальше(выйти) Ну и в диспетчере(см. выше) при появлении флага таймера(не обязательно таймера - флаг может быть и по любому событию) на который настроена задача происходит декремент значения и так до нуля. При переходе значения из 1 в 0 этот кусок суперцикла (задача) снова запускается.
  8. Смотрим на "парадигму суперцикла" StopTask ( task_ht t) SleepTask ( task_ht t, tt_state_t n) Отдать управление остальным: return; И все в рамках суперцикла. Причем я тут глянул task_list на моем средненьком проекте на xmega32A4 (32+4кБ флеши и 4kB оперативки) на почти вышеупомянутом диспетчере было 20+24=44 задачи ...
  9. Который И все в одной задаче. Пытаюсь предположить, откуда у пишущих на РТОС такое желание запихнуть как можно больше в одну задачу вместо того, что-бы разбить ее на десяток. Подозреваю, что ОЗУ не резиновое. Т.е. 576 байт на задачу. Если запустить под сотню задач, это примерно 60кБ ОЗУ тупо на обслуживание вытесняющей многозадачности.
  10. AES отдельно, gzip отдельно и парсер отдельно. Разными задачами. Причем видится мне, что парсер можно даже разделить на несколько задач для прохода по дереву. Опять-же и AES и GZIP обрабатываются кусками после обработки которых можно заняться чем угодно. Несколько задач каждая из которых начинает серьезно работать после появления у нее на входе достаточного куска данных. Впрочем, я подозреваю, что в Вашем коде для РТОС для "парсинга HTML" я увижу то, что вы же выше назвали как Т.е. громадный цикл в надежде на то, что РТОС сама время на остальное нарежет. А что мешает обрабатывать, а затем уже принимать решение корректно принятое и обработанное или нет? В противном случае тупо потратишь вполне реальное время. Т.е. Вы хотите задачу которая отвечает за безопасность оборудования поставить в зависимость от ее блокировки заглючившей флешкой? Боюсь тут задержкой в 100мс можно не отделаться. Напомните, вы что-то там говорили про быдлокодинг? И что мешает разделить мух от котлет или работу с разделяемыми ресурсами и работу с критически важными по времени событиями? С чего вдруг это надо объединять в одну задачу? У вас в доме телевизор автоматом на щитке тоже управляет? Почему нет - там ведь мощный процессор и почти наверняка с ОС(может даже с РТОС)?
  11. И каждой задаче откусывать кусок оперативки. Как по мне, множить задачи в суперлупе обходится как-то дешевле... Ну так РТОС сама переключит контекст. На что многие и рассчитывают. Причем речь не всегда о тупом ожидании - иногда это оооо-чень длинные циклы. Не останется. Флаги не сканируются, а читаются. Атомарно. Как достичь атомарности чтения/записи в байт состояния это уже отдельный вопрос. Ну или биты аварии читать последними если хочется полностью разделить рабочие и аварийные флаги.
  12. А браузеры-то этого и не знают начиная выводить страницу еще до окончания ее полного приема. Забавно бы выглядело иное во времена связи через телефонные модемы. По любому, при парсинге всегда есть ключевые слова и разделители по границе которых можно отдавать управление в кольцо. 100мс это 100 000 мкс или 0.8...2млн операций на древней AVR-ке. Опять-же, сколько времени займет ее прием? Помнится там тоже обработка идет кусками по завершению которых никто не мешает заняться остальным. Если для котла критичны 100мс, то что мешает отработать аварийные цепи в прерываниях? Судя по тому, что у камня хватает ресурсов для парсинга зипованных web-страниц, время подобной реакции будет исчисляться микросекундами.
  13. Спит это если задача отдает управление RTOS, а не тупо ожидая чего-то еще в цикле. Два флага(разрешение алгоритма и разрешение защиты) и одна общая процедура включения/отключения всего и вся вызываемая в прерывании и по завершении таймера
  14. На кой задаче распределяемое время? Если для выполнения чего либо, то как и в любом суперцикле сперва выполнится одна задача, а затем вторая. Суммарно это займет даже меньше процессорного времени чем если они бы в процессе переключались между собой. Не вижу в чем проблема в парсинге страниц - там по любому самый медленный процесс в приеме и вызов задачи можно осуществлять по факту приема строки или чанка. Декодирование MPEG предполагает, что производительности хватает на декодирование кадра пока приходит следующий, а отсюда для управления чем либо с частотой как минимум 25 раз за секунду будет море времени. В чем проблема с отрисовкой - тоже большой вопрос. Чай не на Басике пишем.
  15. Вот там выше я привел простейший диспетчер задач для суперлупа суть которого заключается в анализе флагов(битовых или таймерных - не суть важно) и запуске в зависимости от них того или иного куска кода. Ничего не мешает впихнуть в анализ флагов и анализ приоритетов. Впрочем, почти всегда система приоритетов является костылем. В подавляющем большинстве задач достаточно тех двух приоритетов которые обеспечиваются системой прерываний - то что требует немедленной реакции и то что исполняется как получится. И связываются эти два слоя буферами(очередями) и флагами. Разница суперлупа от вытесняющей операционки лишь в способе оформления задач. В суперлупе они пишутся как проходные с как можно более быстрым завершением, а в вытеснялках как бесконечные циклы с учетом переключения на другую задачу в любой момент цикла. Ну и накладные расходы с этими подходами связанные. В частности, для вытеснялок критическим является объем ОЗУ сжираемый на каждую следующую задачу. Или вообще не делается, потому как парочка задач с высоким приоритетом отбирает все процессорное время. И, что самое забавное, обычно эти задачи с высоким приоритетом ничего не делают(зачастую ожидают результатов тех самых расчетов с низким приоритетом). Длинные вычисления на которые можно забить болт зачастую говорят о том, что проблема в консерватории. А для тех, кто хоть раз пытался разделить задачи между ядрами ESP32, слово "запросто" вызывает недоумение. Единственное что там "запросто" получается это усыпить(отключить) все ядра оставив лишь одно с убогой системой команд на дежурке. В остальном-же для каждого ядра пишется свой отдельный код который мало взаимодействует между ядрами. И первый и второй и двадцатый раз от документации на ОС не оторвешься. Если конечно проекты сложнее моргания светодиодом.
  16. К примеру, могут быть таблицы заполняемые по мере развития проекта и каждый раз обновлять руками после добавления очередного элемента еще и размер как-то напрягает. По любому константа отвечающая за длину нужна Делать ее "волшебным числом" в циклах не вариант т.к. помнить о необходимости его смены при изменении размера - нарываться на ошибки. Ну и если ее создать рядом с объявлением массива, всегда есть некоторая вероятность в коде взять константу от другого массива. Потому проще будет если размер массива вычисляет сам компилятор в месте его использования. Компилятор по любому сообщит о сравнении переменной типа unsigned char с константой превышающей 255, так что в этом нет проблем. Будет что-то типа такого " pointless integer comparison, the result is always true".
  17. А как по мне как раз тут возможно разночтение. Первый же вопрос - это размер в байтах или число элементов buf? Судя по названию - ожидается размер...
  18. Че непонятно в "размер buf деленный на размер его нулевого элемента"? Это классика для начинающих. Впрочем, цикл по всему содержимому массива полезная вещь вплоть до того, что я когда-то такое забабахал в свои Сишные проекты через #define LOOP_ARRAY(n,array) for(U8 n=0; n<(sizeof(array)/sizeof(*array)); n++ ) /// пример из примера выше int buf[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; int sum = 0; LOOP_ARRAY(i, buf) { sum += buf[i]; } А вот лямда-выражения - в топку, абсолютно интуитивно непонятный инструмент.
  19. Эпоксидка не усаживается, а значит зерна порошка не стягиваются, а потому чаще всего будет "индейская национальная изба"
  20. И не дай Бог они уйдут или умрут - у тех кто будет продолжать проект будет наблюдаться вечный геморрой... Да вроде и в Си можно объявлять где угодно, не забывая, впрочем о контейнерах ограниченных {}
  21. Ну так суперцикл тут SystemTask() #define SYSTEM_TASK(fun) fun , __root __flash void (*system_task_func_table[]) (void) = { #include "task_list.h" }; #define MAX_SYSTEM_TASKS (sizeof(system_task_func_table)/sizeof(void(*)(void))) #pragma inline = forced static inline void SystemTask (void) { for (char t=0; t<MAX_SYSTEM_TASKS; t++) { // запуск системных задач (*system_task_func_table[t])();// запуск задачи } //#include "task_list.h" } #undef SYSTEM_TASK И там внутри каждой задачи можно делать как угодно...
  22. А че его писать? __no_init volatile unsigned char task_timer_flags; __no_init unsigned char work_task_timer_flags; // рабочий регистр текущих обрабатываемых флагов /// Диспетчер задач void DispatchTask (void) { { __disable_interrupt(); work_task_timer_flags=task_timer_flags; task_timer_flags=0; // все таймера обработаны __enable_interrupt(); } SystemTask(); for (char t=0; t<MAX_TASKS; t++) { // запуск отключаемых задач if(work_task_timer_flags & task_table[t].mask) { // есть ли нужный таймер if ( task_table_state[t]> 0x01) { // отсчет до запуска task_table_state[t]--; } } if ( task_table_state[t]== 0x01) { // задача требует запуска task_table_state[t]--; if(task_table[t].fun) {// запускаю если такая задача существует (*task_table[t].fun)();// запуск задачи } } } } ...
  23. Кстати, стоит заметить почему 100pF - эти кондеры имеют частоту последовательного резонанса примерно в нижнем диапазоне GSM. Соответственно, он там работает наилучшим образом. При этом на верхнем диапазоне он работает хуже, но там и мощность передатчика в 2 раза ниже. А вот нарисованная в даташите "батарея" конденсаторов (10+33+10посл10+33посл33) как раз потому такая и нарисована, что там резонансы как на верхнем, так и на нижнем и на 2.4ГГц. Оно конечно правильнее, вот только занимает много места и как результат в схему влезают индуктивности соединяющих дорожек(1нГн на 1мм), что негативно сказывается на результате.
  24. Значит главная причина - попадание GSM-сигнала внутрь микрофона с последующим детектированием его на внутреннем полевике. После чего сигнал становится неотличимым от родного и все дальнейшие фильтры его успешно пропускают.
  25. Это плохое решение. На частотах 800+МГц лучше использовать NP0, а помимо этого частота последовательного резонанса 220пФ находится ниже 700МГц отчего его ESR в нижнем диапазоне GSM раза в 3 хуже чем у 100pF , а потому последовательно 2x220пФ в разы хуже одного 100pF. Даже просто один 220pF лучше последовательно включенных. Можете впаять 100pF один на контакты на самом микрофоне(не на выводы, а на контакты к которым они припаяны) и два между массой контакта SIM-карты и контактами MIC+ и MIC- на плате - примерно как на рисунке
×
×
  • Создать...