Поставил по три лайка под всеми ртос, жаль больше не могу. Уроки лучшие из тех что я видел. Судя по количеству просмотров предыдущих уроков по РТОС тема очень востребована. Да и все ваши видео очень интересны , продолжайте , у вас отлично все получается.
22:58 - и главное не забыть вкл. прерывания этого Таймера в разделе - "NVIC Settings"! Никак и ничего не шло в буфер для приема текста от ф. "vTaskGetRunTimeStats(pcWriteBuffer);" пока не нашел в отладке, что прерывания Таймера вообще не работают. И да еще раз спасибо за замечательный видеоматериал!! Очень помогли. Если бы Вы еще бы его смогли дополнить по др. "hook"-ам, то вообще бы сказка была бы. :) По отладке переполнения стека и пр. Но мечтать все-таки не вредно.
Спасибо большое за вашу работу, длительность ролика ничему не мешает. Особенно ваша работа полезна для специалистов, застрявших когда-то на AtMega, у которых есть уже база и которым нужна быстрая адаптация к переходу на новые "рельсы".
Спасибо за хороший материал!. Смотрю для освоения FreeRTOS на esp32, поскольку качественного обучающего контента для esp маловато. В основном как настроить esp idf и включить пример мигания светодиодом. Ну либо esp на Adurino. Но это уже совсем.
Теж дякую за поданий матеріал!! Колись займався AVR -ами пробував асемблер, але тепер розумію, треба вчити СІ та переходити на STM. На мою скромну думку, з того асортименту що є на просторах Ютуб, ваш блого самий цікавий, і зрозумілий. Дякую.
На этом видео при 500 просмотрах на текущий момент я заработал ( < 1$ USA) менее одного доллара США. Внимание вопрос, как долго я буду снимать эти "видосики"? Это не к вам лично вопрос, это саркастический ответ на пожелание "Главное не забрасывайте..."
@@VladimirMedintsev а за счет чего вообще начисляются деньги ? За размещение рекламы на вашем видео или за переход на рекламу с вашего видео ?Непонятен механизм начисления денег , сколько пытался вникнуть, так толком и не понял .
Там критериев много, больше всего зависит от показов рекламных обьявлений. Содержимое выбирает сама платформа. Но четкого описания никто не предоставляет.
Не переживайте смотрим до конца. Было бы не плохо если бы вы род видео оставляли ссылки на статьи или мануала (желательно на могучем) что бы если чего не понял, можно было прочитать
Автору спасибо. И что хотелось бы видеть в одном из следующих видео - это планирование/структурирование кода. Где и как вы располагаете модули, обработчики, задачи и тп. Не делаете же вы все операции в задачах в одном файле freertos.c? На мой взгляд, хорошо было бы на примере разобрать именно структуру проекта. Перехожу с 8битных на стм и вопросов по организации кода пока много. Все очень не привычно и общие рекомендации по структурированию кода никак не вяжутся с организацией кода Keilом. Сама ОСРВ, на мой взгляд, не настолько сложна, есть хорошая документация. Понятны принципы и подходы. И второй вопрос, который очень интересует, думаю многих 8битных, это режим DMA. Что это? Как это? Как это работает? Как запустить? Как остановить? Как подготавливать/обрабатывать данные? Спасибо
у тех кто хочет чему-то научиться слова "осталось совсем немножко" радости совсем не вызывают. разве что в контексте "осталось совсем немножко до повышения вашего уровня" ))
В этом сложности нет ну абсолютно никакой. Вопросы практического применения на канале есть. А с шаговыми там настолько просто, что и смотреть не интересно. У нас был недавно проект в котором самый примитивный микроконтроллер умудряется одновременно управлять 9 шаговыми двигателями с разными скоростями и все шикарно работает.
Большое спасибо! Самые толковые уроки по STM32+CubeMx+FreeRTOS! Жду продолжения:) Кстати, ST выпустили новый инструмент для CubeMx, называется X-CUBE-AI он, позволяет работать с нейронными сетями на STM32, было бы очень интересно посмотреть обзор возможностей + Hello World и ваше мнение по этому поводу.
Ну насчет "новый инструмент" я бы поспорил. Вы на номер версии этого инструмента посмотрите. Это его в куб недавно интегрировали а до этого надо было ставить. Но если в двух словах то видео конечно сделаю но рассказывать там особо не о чем. Берется созданная на компьютере модель, переносится в процессор и там вы с ней можете ограниченно взаимодействовать. С Keros моделью по крайней мере получилось именно так. Практического применения у этого не сильно много, но работает. Там "привет мир" будет размером в пару часов с концентрацией не на stm32 а на машинное обучение. Ну в общем любопытства эта тема у людей вызывает больше чем потом реального практического выхлопа.
Речь идет о машинном обучении а там нет 100% однозначного ответа. А это означает что всегда есть определенный процент ошибок. И этот процент погрешностей он не маленький. Не уверен что двигатели это простят. Ну да вам виднее. Это по большей части подходит для умных пылесосов да распознавания чего-либо. Мы на этой технологии распознаем кардиосигнал.
Здравствуйте , Владимир, очень полезный урок, спасибо вам!!!🙂👍 Пытался использовать функцию vTaskList , не получается, правда среда разработки cubeide. Возможно ли показать работу с данными функциями и отладчиком в cubeide , или может что-нибудь подскажите, заранее благодарю за ответ!!!
Здравствуйте, Владимир! На 25:40 почему бы не использовать TIM c 32х битным счетчиком. Тогда не нужны прерывания от таймера на 10 или даже 20 кГц. Нет...? Спасибо за ваш труд! __weak unsigned long getRunTimeCounterValue(void) { return htim2.Instance->CNT; }
Еще вопрос: какова целесообразность втыкать ртос везде и всюду? Сейчас делал небольшую задачку для F103 контроллера, там CAN, датчик освещенности, кодом управляемые светодиоды, кнопка и вообщем-то все. После просмотра ваших ртос-видео перепилил ее под ртос и чет понравилось, вошел во вкус. Сижу и думаю, как поступать в дальнейшем для мелких контроллеров и небольших задач.
Для меня этот вопрос решается таким образом: если алгоритм линейный то никакая операционка не нужна. Ну к примеру загрузчик. Там все операции носят последовательный характер. Если создаваемая программа имеет индикацию или ветвление процессов то удобнее под операционкой. Вообще написание под FreeRTOS серьезно экономит время т.к. приходится писать меньше кода.
Когда Вы говорите о снижении энергопотребления в IDLE задаче, какой выбор будет оптимален: снижение тактовой частоты и как следствие - увеличение времени выполнения активных задач или, как альтернатива, использование максимальной частоты и увеличение времени нахождения в одном из режимов пониженного энергопотребления в IDLE задаче? Какими инструментальными средствами можно определить правильность первого или второго (возможно комбинированного) подходов? Спасибо.
А теперь понятно почему я эти вопросы пропустил. Что касается энергопотребления то я не знаю какой вариант более правильный и дело в том, что выбор этого варианта очень сильно зависит как от специфики выполняемых микроконтроллером действий, так и от схемотехники самого устройства. По этому философствовать не буду. Расскажу как у нас сделано. В проекте мозголечилки ruclips.net/video/5hV3T2e2jWs/видео.html мы использовали комплексный подход. А именно частота ядра - минимальная для устойчивого выполнения задачи и формирования импульсов нужной частоты. Подобрана экспериментально.В сочетании со снижением напряжения питания процессора до 2,5 вольт Это дает общее энергопотребление 1,2 миллиампера во время работы устройства. А когда нет генерации сигнала и нет взаимодействия с пользователем мы отправляемся в режим наименьшего энергопотребления и снижаем потребление до 70 микроампер. Для нашей задачи этого хватает. Однако можно пойти и другим путем. Например если вы знаете сколько времени у вас есть свободного то можно именно на него уходить в сон и выходить по срабатыванию RTC. Хоть через миллисекунду. Это тоже хорошо сэкономит емкость батареи. Я к тому что тут нет универсальных рекомендаций. Все зависит от конкретного процессора, схемотехники и потребности программы. Думаю что правильнее всего это эксперимент.
Здравствуйте! Спасибо за уроки. Подскажите, пожалуйста, начинающему. При подключении функции vTaskList(), появляется ошибка - Error: L6218E: Undefined symbol vTaskList (referred from freertos.o). Какую- то библиотеку необходимо подключить?
Необходимо проверить что файл freertos.c содержит строку #include "task.h" А вообще, не обижайтесь, если вы испытываете проблему с поиском ошибок и отладкой, то вам необходимо заняться изучением языка программирования, а не изучением FreeRTOS.
@@VladimirMedintsev как раз это сейчас и нужно , еще хочу понять как остановить задачу до определенного события . Modbus на FreeRTOS запустил, вроде работает нормально .Вообще FreeRTOS отличная штука для масштабирования проектов, теперь нужно понять как правильно выделять память и понимать предел производительности. С LL в FreeRTOS разобрался .
а задача запускается сначала? или продолжается работа где остановилась? например в цикле что то долго делал, не уложился в 1мс, и прервалось, потом менеджер сначала запускает? или продолжаем работать в цикле.....
С того самого места в котором закончилось выделенное этой задаче время. Т.е. фактически диспетчер задач просто переключается на другую задачу запоминая в каком месте он остановился. Благодаря этому и достигается "одновременное" выполнение нескольких задач.
На базе f407discovery+LCD ILI9341+MP3-плеер хочу сделать систему контроля на приборной панели в авто (вместо светодиодной индикации) + голосовые подсказки об аварийных ситуациях. Выводить изображение на экран у меня наконец то получилось))) Пиктограммы я планирую разместить на внешней памяти (скорее всего через Mass Storage на флешке). В качестве буфера экрана придётся создать массив размерами 320х240 = 76800 элементов типа uint16_t для цветности 65к. В данный массив будут считываться фоновая заставка при запуске, а также в последующем - пиктограммы. Хотя можно создать и несколько массивов для каждого типа пиктограмм (в зависимости от физических размеров). Но для фоновой заставки экранный буфер "скушает" 154 Кб памяти, что достаточно много. Ведь у нас всего 192 Кб оперативки. Как по Вашему в этом случае следует поступит? Может стоить создать буфер на четверть экрана и подгружать в четыре этапа с использованием функции блокировки выполнения других задач? Правда не уверен, будет ли в этом случае экран заполняться незаметно. Или будет видно, как сначала отобразится левая верхняя четверть, потом правая и т.д. Ещё пока не подключал масс сторидж и не тестил.
Извините, возможно я недопонял, а зачем вам вообще экранная память? Ну ведь это не windows, у вас у всех элементов на экране есть свои места и координаты. Надо заменить иконку - стираем и вместо нее рисуем новую. Я бы не стал вообще создавать копию в памяти. У вас быстрый процессор, очень быстрый ну пусть и рисует. Пусть генерит изображение в реальном времени. Я сейчас далеко от компьютера, но у ST была как-то библиотека именно для экранных интерфейсов. Можно и ее использовать, можно и свое написать. Но есть у меня мнение что в современных процессорах можно уже и без видеопамяти обойтись. На начальную заставку можно в виде jpg отображать. Библиотеки тоже есть.
@@VladimirMedintsev Насчёт иконок - да. Так и планировал. Тем более, что у них чётко зафиксированные места на экране. Анимацию пока не планирую. Но что касается заставки - мне ведь нужно считать из файла байты цвета для каждого пикселя - а это 153600 байта (76800х2). Как я понял из уроков по работе с Mass storage, данные из файла с флешки нужно сначала считать в массив. А уже после данные этого массива я могу передать на экран. Если этого можно избежать и потоком передавать с флешки на экран, я только буду рад.
Привет а у вас не было проблем с использованием vTaskList ? У меня не компилится пишет sprintf\sprintf.axf: Error: L6218E: Undefined symbol vTaskList (referred from freertos.o).
Внимательно посмотрите как я активировал возможность использования vTaskList в кубе. Ну или руками исправьте в настройках FreeRTOS. Иными словами кто-то не внимателен.
Владимир, как лучше организовать логирование сбоев? Если устройство уже запущено в промышленную эксплуатацию, отлогировать например сбой превышения стека задачи.
Сейчас лень лезть в документацию, но по моему только в делителе надо -1 писать. С другой стороны не имеет значения. Там главное чтобы счетчик в 10-20 раз быстрее работал чем задачи переключаются. А с какой скоростью это не важно.
Отличные видео, спасибо автору! Но я всё ещё не понял вот что: в первом видео был пример в котором использовалась функция HAL_Delay(), но несмотря на это, прочие задачи продолжили выполняться в нормальном режиме. Как получилось так, что несмотря на то что процессор занят, он продолжает реагировать на запросы диспетчера задач? Может это оптимизация на этапе компиляции? И, если каждую милисекунду срабатывает прерывание, и ядро переключается с задачи на задачу, означает ли это что при использовании HAL_Delay( x ); ядро на самом деле потратит на сон при выполнении первой задачи N * x милисекунд (где N это число тасков)? А если ядро не успеет выполнить назначенный ему таск за 1 мс, то таск не будет выполнен в принципе?
На самом деле все немного проще. Диспетчер задач осуществляет постоянные, непрерывные переключения между задачами. Если мы вызываем osDelay то тем самым даем диспетчеру задач понять, что нам не надо давать работать столько-то миллисекунд. И он просто не дает управление этой задаче. А если мы используем HAL_Delay, то пауза выполняется внутри самой задачи, за счет цикла опроса текущего времени внутри функции HAL_Delay. Остальные задачи в системе продолжают выполняться ведь диспетчер не обделит никого. Но при этом не образуется свободного невостребованного времени. Ведь если одна или несколько задач скажут диспетчеру, что есть свободное время, он не поделит его на другие задачи, нет, он потратит его на вызов Idle процесса. А он то нам и нужен чтобы в нем приостанавливать работу процессора и экономить питание.
@@VladimirMedintsev Спасибо! Эта часть теперь понятна. Не знаю, следующий вопрос слишком тривиальный или нет, но спрошу на всякий случай. А как же ядро умудряется поработать одновременно со всеми процессами в приложениях где соблюдение временных интервалов критично? Допустим мы параллельно в разных тасках работаем с BLE, пишем что-то во FLASH и заодно пытаемся отправить/принять несуразно огромное сообщение по UART. Как же ядро будет выбирать с чем ему сейчас поработать или переключаться между ними, когда попадание в интервал критично? Сможет ли ядро выполнить все эти задачи? UPD. прошу прощения, перечитал ответ и увидел что диспетчер работает непрерывно, отредактировал свой вопрос
А вот в тех приложениях где соблюдение времени критично концепция немного меняется. Инициализируйте таймер, пусть он работает на заданной вами частоте и дергает прерывание. У прерывания наивысший приоритет и там делайте кратко свои важные и критичные вещи, а операционная система пусть работает сама по себе и готовит данные, рассовывает их в буфера, принимает решения и все такое. А критически важное будет всегда выполняться независимо и вовремя!
А такой вопрос. Система freertos может прервать выполнение прерывания и отобрать время у такой задачи? Я стм32 еще не очень знаю, здесь система прерываний посложнее. Но помнится в AVR прерывание никто не может прервать. Поскольку они глобально выключаются в этот момент (SEI-CLI) А здесь tick_rate работает сам на прерывании от таймера. И наверное имеет больший приоритет перед другим железом? Я правильно понимаю?
Нет вообще никаких проблем с дебагом. Не буду много букв писать, но если кратко, код внутри задачи можно легко отладить временнь повысив ее приоритет, а мультизадачные тонкости и так нормально отлаживаются. Ну скажем не сложнее чем обычную программу с обработчиками прерываний.
Пытаюсь перевести работу USART на DMA , попался пример где есть DMA и FreeRTOS и мне не понятна функция связанная с FreeRTOS . Вот пример обработчика прерывания с этими функциями , не понятна последняя vPortYieldFromISR(); Могли бы вы описать что она делает в данном контексте ? void USART6_IRQHandler(void) { signed long Test; int status = USART6->SR;
ReceiveFromCOM0_DMA(); // Начинаем новый приём с DMA if (status & USART_SR_TC) // Передача окончена (последний байт полностью передан в порт) USART6->SR &= ~USART_SR_TC; // Снимаем флаг else if (status & USART_SR_IDLE) // Между байтами при приёме обнаружена пауза в 1 IDLE байт { USART6->DR; // Снимаем флаг xSemaphoreGiveFromISR(semCOM1pak, &Test); // Симафорим задаче обработки пакетов vPortYieldFromISR(); // Вызываем перепланировку в ОС }
vPortYieldFromISR() это тоже самое что - if( xSwitchRequired != pdFALSE ) portYIELD() у меня документации под рукой нету, но скорее всего вызов этого макроса заставляет шедулер вернуть нас к задаче с наивысшим приоритетом чтобы таким образом наверстать время потраченное в обработчике прерывания.
На самом деле нет там ничего особо сложного. Просто вся сложность понимания FreeRTOS в том, что вокруг самой операционной системы накручено очень много кода в виде макросов для портирования на различные платформы.
Владимир, спасибо большое за толковый материал. В одном проекте использую оцифровку сигнала АЦП с частотой 40 КГц, выборка 2048 значений, между каждой выборкой контроллеру позволяю поспать. Как такие задачи делаются под RTOS? Нужно всю выборку обрамлять как критическую секцию, или в то время когда контроллер спит отдать управление другим задачам (при том, что частота выборок не должна "уплывать")?
Честно говоря мы подобные задачи решаем немного по другому. Если есть взаимодействие с DAC или ADC, то мы однозначно используем DMA. А вот при использовании DMA вам становятся доступными два бонуса. Во-первых процессор не занят и может заниматься своими делами пока у вас там с заданной частотой и в заданное место складываются ваши данные. А второе это есть доступ к обратным вызовам типа HAL_ADCEx_InjectedConvCpltCallback. Это такие заложенные в HAL функции которые вы можете переопределить в вашем коде и использовать при возникновении каких-либо событий. Ну например когда DMA подойдет к середине или закончит порученную работу. Таким образом вы сможете используя обратные вызовы дать своей задаче в операционной системе заменить буфер для DMA или начать обсчет полученной порции данных. При этом не возникнет "узких" мест требующих использования критических секций кода. Только такой подход сохранит вам частоту выборок в не зависимости от того чем занята ваша операционная система.
@@VladimirMedintsev пробовал я по DMA работать со встроенными АЦП, при прочих равных условиях увеличивается уровень шума считанного сигнала (на входе АЦП цепочка усиления от датчиков с коэфф усиления в несколько тысяч). В AN2834 Application note How to get the best ADC accuracy in STM32 microcontrollers говорится, что для достижения лучших результатов нужно отключить по возможности внутреннее тактирование ненужной периферии на время замера (timers, communications..), а передача через DMA, как я понимаю, является асинхронным процессом по отношению к ядру контроллера, может что-то с этим связано или я просто "не умею их правильно готовить"?
Я не знаю с чем это связано в вашем случае. У нас такого роста шума ни в одном проекте не наблюдалось. Честно говоря фразой "в несколько тысяч раз" я очень сильно обескуражен. Нет такого у нас ни разу не было. С тем что мы используем в основном DMA.
@@VladimirMedintsev Да, правильнее говорить о децибелах, но наличие проблемы это не отменяет. Ну да ладно, к FreeRTOS это не имеет никакого отношения, разберусь. PS. Код я вам отослал.
@@ivanivan3815 Как-то так получилось что я терпеть не могу говорить в децибелах. Вот не укладывается это понятие в моей голове. Кстати код по какой-то причине не пришел.
Им и до запуска и после никто не управляет. Вообще вопрос странный у таймера есть настройки они заданы при его инициализации, потом его запустили и он вызывает прерывание в котором увеличивается счетчик. Все.
Дякую за Ваші відео. Вивчаю stmки. Якщо у Вас буде можливість, будь- ласка, викладіть відео програмування роботи 2х енкодерів по переривання в RTOS. Дякую
Сам задался вопросом и погуглил. Нашел статью на хабре где сказано: Значение параметра configMINIMAL_STACK_SIZE исчисляется НЕ в байтах, а в словах! Причем размер слова меняется от одного порта ОС к другому и он определен в файле portmacro.h дефайном portSTACK_TYPE. Например, в моем случае, размер слова составляет 4 байта. Таким образом, то, что параметр configMINIMAL_STACK_SIZE в моей конфигурации равен 128 означает, что минимальный размер стека для задачи равен 512 байт. habr.com/ru/post/352782/
не совсем понимаю смысл uxTaskPriorityGet() : функция позволяет узнать приоритет задачи, который мы сами же и установили ранее в CubeMX, когда собственно и создавали эту самую задачу. Либо я дурак, либо это не совсем логичная функция...
@@VladimirMedintsev спасибо за ответ, но я новичок в программировании, и не совсем понятно как мне получить данные о памяти в CubeIDE, хотелось бы получить также как тут ruclips.net/video/wTK11IDpg7s/видео.html но не пойму где взять, как посмотреть адрес этой переменной (pcWriteBuffer), потом вы говорите "этот адрес скопировал сюда" что это за "сюда" где такое "сюда" найти в CubeIDE ? Я засунул эту переменную в Live Expressions но там в Value только [1024]
Поставил по три лайка под всеми ртос, жаль больше не могу. Уроки лучшие из тех что я видел. Судя по количеству просмотров предыдущих уроков по РТОС тема очень востребована. Да и все ваши видео очень интересны , продолжайте , у вас отлично все получается.
Как же охерительно, не меньше, смотрю данное видео как сериал, не могу оторваться, без воды, по делу и понятно, спасибо огромное и извиняюсь за мат.
22:58 - и главное не забыть вкл. прерывания этого Таймера в разделе - "NVIC Settings"! Никак и ничего не шло в буфер для приема текста от ф. "vTaskGetRunTimeStats(pcWriteBuffer);" пока не нашел в отладке, что прерывания Таймера вообще не работают. И да еще раз спасибо за замечательный видеоматериал!! Очень помогли. Если бы Вы еще бы его смогли дополнить по др. "hook"-ам, то вообще бы сказка была бы. :) По отладке переполнения стека и пр. Но мечтать все-таки не вредно.
Спасибо, постараюсь.
Этот комментарий надо бы закрепить сверху, тоже пока не поставил галку в NVIC Settings ничего не работало
Отлично подаете, отсмотрел все 3 части. Теперь будет гораздо проще эту ось осваивать. Спасибо!
Скоро еще будет.
Спасибо большое за вашу работу, длительность ролика ничему не мешает. Особенно ваша работа полезна для специалистов, застрявших когда-то на AtMega, у которых есть уже база и которым нужна быстрая адаптация к переходу на новые "рельсы".
Смотрим до конца! Спасибо за великолепную подачу материала. FreeRTOS тема очень интересная.
Смотрю и прям кайфую, насколько всё понятно объясняется!
Прошло два года, а информация осталась самой удобоперевариваемой! Курс хочу )
Спасибо за уроки и качественную подачу материала!
Огромное спасибо за труды!
Жду каждое ваше видео хоть и сам уже давно во многом разобрался.
Очень во время ролик. Спасибо за труды.
Забыли упомянуть что в TIM3 нужно включить глобальные прерывания. Иначе счетчик не будет инкрементироваться. Спасибо за видео!
Спасибо за хороший материал!. Смотрю для освоения FreeRTOS на esp32, поскольку качественного обучающего контента для esp маловато. В основном как настроить esp idf и включить пример мигания светодиодом. Ну либо esp на Adurino. Но это уже совсем.
+1 досмотрел до конца, спасибо за подробное объяснение
Очень понятно рассказано, отличный урок!
Теж дякую за поданий матеріал!! Колись займався AVR -ами пробував асемблер, але тепер розумію, треба вчити СІ та переходити на STM. На мою скромну думку, з того асортименту що є на просторах Ютуб, ваш блого самий цікавий, і зрозумілий. Дякую.
Благодарю за ваш отзыв.
Спасибо за уроки! Главное не забрасывайте)
На этом видео при 500 просмотрах на текущий момент я заработал ( < 1$ USA) менее одного доллара США.
Внимание вопрос, как долго я буду снимать эти "видосики"?
Это не к вам лично вопрос, это саркастический ответ на пожелание "Главное не забрасывайте..."
@@VladimirMedintsev а за счет чего вообще начисляются деньги ? За размещение рекламы на вашем видео или за переход на рекламу с вашего видео ?Непонятен механизм начисления денег , сколько пытался вникнуть, так толком и не понял .
Там критериев много, больше всего зависит от показов рекламных обьявлений. Содержимое выбирает сама платформа. Но четкого описания никто не предоставляет.
@@VladimirMedintsev Рассказано подробно и интересно.
Но это видео для целевой аудитории,так что на рекламе тут много увы не заработать.(
@@lesharom2405 Значит ответ очевиден. Скорее рано чем позже мне это надоест.
Дякую! Дуже цікаво дивитись Ваші відео і це стимулює до подальшого вивчення матеріалу.
спасибо что делаете такие ролики
Не переживайте смотрим до конца. Было бы не плохо если бы вы род видео оставляли ссылки на статьи или мануала (желательно на могучем) что бы если чего не понял, можно было прочитать
Спасибо ! Жду следующие ролики !!!
Автору спасибо. И что хотелось бы видеть в одном из следующих видео - это планирование/структурирование кода. Где и как вы располагаете модули, обработчики, задачи и тп. Не делаете же вы все операции в задачах в одном файле freertos.c? На мой взгляд, хорошо было бы на примере разобрать именно структуру проекта. Перехожу с 8битных на стм и вопросов по организации кода пока много. Все очень не привычно и общие рекомендации по структурированию кода никак не вяжутся с организацией кода Keilом. Сама ОСРВ, на мой взгляд, не настолько сложна, есть хорошая документация. Понятны принципы и подходы. И второй вопрос, который очень интересует, думаю многих 8битных, это режим DMA. Что это? Как это? Как это работает? Как запустить? Как остановить? Как подготавливать/обрабатывать данные? Спасибо
Спасибо, расскажу.
у тех кто хочет чему-то научиться слова "осталось совсем немножко" радости совсем не вызывают. разве что в контексте "осталось совсем немножко до повышения вашего уровня" ))
Полезные видео. Хотелось бы продолжения теории, а также снять несколько видео с конкретными примерами при решении реальных задач.
В смысле каких задач? Есть же несколько видео на канале где рассматривается именно практическое применение.
@@VladimirMedintsev ну я имею ввиду подключить пару датчиков, пару шаговых электродвигателей и дать им синхронно поработать
В этом сложности нет ну абсолютно никакой. Вопросы практического применения на канале есть. А с шаговыми там настолько просто, что и смотреть не интересно. У нас был недавно проект в котором самый примитивный микроконтроллер умудряется одновременно управлять 9 шаговыми двигателями с разными скоростями и все шикарно работает.
Господи, наконец-то стало понятно.
Так держать! и Курс на народный проц 103с8т6!
F103 я использую исключительно в программаторах. В видео этого микроконтроллера не будет.
Он багованый , поэтому его в комерческих устройствах редко пользуют.
Хехх.. писал вопрос к предыдущей серии, а в этой оказывается уже есть ответ :)
Видео настолько логично и понятно для моего базового уровня, что будь канал платным, я бы купил подписку :)
Конец вообще бомба.
Большое спасибо! Самые толковые уроки по STM32+CubeMx+FreeRTOS! Жду продолжения:) Кстати, ST выпустили новый инструмент для CubeMx, называется X-CUBE-AI он, позволяет работать с нейронными сетями на STM32, было бы очень интересно посмотреть обзор возможностей + Hello World и ваше мнение по этому поводу.
Ну насчет "новый инструмент" я бы поспорил. Вы на номер версии этого инструмента посмотрите. Это его в куб недавно интегрировали а до этого надо было ставить. Но если в двух словах то видео конечно сделаю но рассказывать там особо не о чем. Берется созданная на компьютере модель, переносится в процессор и там вы с ней можете ограниченно взаимодействовать. С Keros моделью по крайней мере получилось именно так. Практического применения у этого не сильно много, но работает. Там "привет мир" будет размером в пару часов с концентрацией не на stm32 а на машинное обучение. Ну в общем любопытства эта тема у людей вызывает больше чем потом реального практического выхлопа.
@@VladimirMedintsev Клас, буду ждать видео 🙂 если могу чем то помочь, обращайтесь
О, вообще не проблема, создайте в Keras модель и схему подходящую для испытаний и пришлите в отдельных файлах.
@@VladimirMedintsev есть применение в системах управления двигателями, но мне достаточно трудно вникнуть)
Речь идет о машинном обучении а там нет 100% однозначного ответа. А это означает что всегда есть определенный процент ошибок. И этот процент погрешностей он не маленький. Не уверен что двигатели это простят. Ну да вам виднее.
Это по большей части подходит для умных пылесосов да распознавания чего-либо. Мы на этой технологии распознаем кардиосигнал.
Здравствуйте , Владимир, очень полезный урок, спасибо вам!!!🙂👍
Пытался использовать функцию vTaskList , не получается, правда среда разработки cubeide.
Возможно ли показать работу с данными функциями и отладчиком в cubeide , или может что-нибудь подскажите, заранее благодарю за ответ!!!
Спасибо, покажу.
Радостный вижу видосик бегу наливать чай. Тыкаю видосик...а тут такое....:( ну елки маталки
Видосик как и всегда раз в неделю вторник 7:00 по Сахалинскому времени. Пока изменять ничего не будем.
@@VladimirMedintsev премьеры, с толку сбивают
Спасибо за отличное видео. Не могли бы вы пояснить как вы рассчитываете исходя из частоты какой prescarel и counter period поставить таймеру?
Будет видео про таймеры и все там расскажу.
Здравствуйте, Владимир! На 25:40 почему бы не использовать TIM c 32х битным счетчиком. Тогда не нужны прерывания от таймера на 10 или даже 20 кГц. Нет...?
Спасибо за ваш труд!
__weak unsigned long getRunTimeCounterValue(void)
{
return htim2.Instance->CNT;
}
Вполне можно
Вот я только одного не пойму, чего я так долго боялся этих STM32? Надо заказать пару отладочных младшего семейства и пачку голых чипов.
Еще вопрос: какова целесообразность втыкать ртос везде и всюду?
Сейчас делал небольшую задачку для F103 контроллера, там CAN, датчик освещенности, кодом управляемые светодиоды, кнопка и вообщем-то все.
После просмотра ваших ртос-видео перепилил ее под ртос и чет понравилось, вошел во вкус.
Сижу и думаю, как поступать в дальнейшем для мелких контроллеров и небольших задач.
Для меня этот вопрос решается таким образом: если алгоритм линейный то никакая операционка не нужна. Ну к примеру загрузчик. Там все операции носят последовательный характер. Если создаваемая программа имеет индикацию или ветвление процессов то удобнее под операционкой. Вообще написание под FreeRTOS серьезно экономит время т.к. приходится писать меньше кода.
Когда Вы говорите о снижении энергопотребления в IDLE задаче, какой выбор будет оптимален: снижение тактовой частоты и как следствие - увеличение времени выполнения активных задач или, как альтернатива, использование максимальной частоты и увеличение времени нахождения в одном из режимов пониженного энергопотребления в IDLE задаче? Какими инструментальными средствами можно определить правильность первого или второго (возможно комбинированного) подходов? Спасибо.
А теперь понятно почему я эти вопросы пропустил.
Что касается энергопотребления то я не знаю какой вариант более правильный и дело в том, что выбор этого варианта очень сильно зависит как от специфики выполняемых микроконтроллером действий, так и от схемотехники самого устройства.
По этому философствовать не буду. Расскажу как у нас сделано.
В проекте мозголечилки ruclips.net/video/5hV3T2e2jWs/видео.html мы использовали комплексный подход. А именно частота ядра - минимальная для устойчивого выполнения задачи и формирования импульсов нужной частоты. Подобрана экспериментально.В сочетании со снижением напряжения питания процессора до 2,5 вольт Это дает общее энергопотребление 1,2 миллиампера во время работы устройства. А когда нет генерации сигнала и нет взаимодействия с пользователем мы отправляемся в режим наименьшего энергопотребления и снижаем потребление до 70 микроампер. Для нашей задачи этого хватает.
Однако можно пойти и другим путем. Например если вы знаете сколько времени у вас есть свободного то можно именно на него уходить в сон и выходить по срабатыванию RTC. Хоть через миллисекунду. Это тоже хорошо сэкономит емкость батареи.
Я к тому что тут нет универсальных рекомендаций. Все зависит от конкретного процессора, схемотехники и потребности программы.
Думаю что правильнее всего это эксперимент.
@@VladimirMedintsev Спасибо за развернутый ответ, примерно в таком порядке я и предполагал поэкспериментировать
Отлично!
Здравствуйте! Спасибо за уроки. Подскажите, пожалуйста, начинающему. При подключении функции vTaskList(), появляется ошибка - Error: L6218E: Undefined symbol vTaskList (referred from freertos.o). Какую- то библиотеку необходимо подключить?
Необходимо проверить что файл freertos.c содержит строку #include "task.h"
А вообще, не обижайтесь, если вы испытываете проблему с поиском ошибок и отладкой, то вам необходимо заняться изучением языка программирования, а не изучением FreeRTOS.
эту строку файл содержит
Значит проверяйте настройки куба относящиеся к операционке yadi.sk/d/oRhuGXAeMzRC0Q
Жду .Заранее лайк.
Про LL там нет ни слова. Там управление диспетчером задач и оценку размера стека - производительность.
@@VladimirMedintsev как раз это сейчас и нужно , еще хочу понять как остановить задачу до определенного события . Modbus на FreeRTOS запустил, вроде работает нормально .Вообще FreeRTOS отличная штука для масштабирования проектов, теперь нужно понять как правильно выделять память и понимать предел производительности. С LL в FreeRTOS разобрался .
Оперативная память!)
а где вообще живут функции и как их создавать? есть такой урок? где можно такое узнать?
Я не совсем понял, почему не все 40К озу указать в настройках freertos? Почему только 12К?
Это память для стека задач и для кучи задач. А в оставшейся памяти будут жить переменные, массивы DMA и прочее.
а задача запускается сначала? или продолжается работа где остановилась? например в цикле что то долго делал, не уложился в 1мс, и прервалось, потом менеджер сначала запускает? или продолжаем работать в цикле.....
С того самого места в котором закончилось выделенное этой задаче время. Т.е. фактически диспетчер задач просто переключается на другую задачу запоминая в каком месте он остановился. Благодаря этому и достигается "одновременное" выполнение нескольких задач.
На базе f407discovery+LCD ILI9341+MP3-плеер хочу сделать систему контроля на приборной панели в авто (вместо светодиодной индикации) + голосовые подсказки об аварийных ситуациях. Выводить изображение на экран у меня наконец то получилось))) Пиктограммы я планирую разместить на внешней памяти (скорее всего через Mass Storage на флешке). В качестве буфера экрана придётся создать массив размерами 320х240 = 76800 элементов типа uint16_t для цветности 65к. В данный массив будут считываться фоновая заставка при запуске, а также в последующем - пиктограммы. Хотя можно создать и несколько массивов для каждого типа пиктограмм (в зависимости от физических размеров). Но для фоновой заставки экранный буфер "скушает" 154 Кб памяти, что достаточно много. Ведь у нас всего 192 Кб оперативки. Как по Вашему в этом случае следует поступит? Может стоить создать буфер на четверть экрана и подгружать в четыре этапа с использованием функции блокировки выполнения других задач? Правда не уверен, будет ли в этом случае экран заполняться незаметно. Или будет видно, как сначала отобразится левая верхняя четверть, потом правая и т.д. Ещё пока не подключал масс сторидж и не тестил.
Извините, возможно я недопонял, а зачем вам вообще экранная память? Ну ведь это не windows, у вас у всех элементов на экране есть свои места и координаты. Надо заменить иконку - стираем и вместо нее рисуем новую. Я бы не стал вообще создавать копию в памяти. У вас быстрый процессор, очень быстрый ну пусть и рисует. Пусть генерит изображение в реальном времени. Я сейчас далеко от компьютера, но у ST была как-то библиотека именно для экранных интерфейсов. Можно и ее использовать, можно и свое написать. Но есть у меня мнение что в современных процессорах можно уже и без видеопамяти обойтись. На начальную заставку можно в виде jpg отображать. Библиотеки тоже есть.
@@VladimirMedintsev Насчёт иконок - да. Так и планировал. Тем более, что у них чётко зафиксированные места на экране. Анимацию пока не планирую. Но что касается заставки - мне ведь нужно считать из файла байты цвета для каждого пикселя - а это 153600 байта (76800х2). Как я понял из уроков по работе с Mass storage, данные из файла с флешки нужно сначала считать в массив. А уже после данные этого массива я могу передать на экран. Если этого можно избежать и потоком передавать с флешки на экран, я только буду рад.
Ну разумеется можно и без массива.
Владимр спасибо огромное ша Ваши уроки. А не подскажите возможно ли сделать такой же вывод списка задач в STM32CubeIde?
Конечно возможно.
Привет а у вас не было проблем с использованием vTaskList ? У меня не компилится пишет sprintf\sprintf.axf: Error: L6218E: Undefined symbol vTaskList (referred from freertos.o).
Внимательно посмотрите как я активировал возможность использования vTaskList в кубе. Ну или руками исправьте в настройках FreeRTOS. Иными словами кто-то не внимателен.
Посмотрите какая у Вас версия интерфейса CMSIS (должна быть CMSIS_V1). Смотреть в CubeMx.
Владимир, как лучше организовать логирование сбоев? Если устройство уже запущено в промышленную эксплуатацию, отлогировать например сбой превышения стека задачи.
Это отдельная и весьма серьезная тема, это я тут в комментариях не расскажу. Есть статьи на эту тему поищите.
Самые лучшие ролики у вас, при настройке таймера разве в период не 9 надо писать?
Сейчас лень лезть в документацию, но по моему только в делителе надо -1 писать.
С другой стороны не имеет значения. Там главное чтобы счетчик в 10-20 раз быстрее работал чем задачи переключаются. А с какой скоростью это не важно.
Да в этом случае без разницы но вроде как и там и там -1 надо может конечно и я ошибаюсь.
Отличные видео, спасибо автору! Но я всё ещё не понял вот что: в первом видео был пример в котором использовалась функция HAL_Delay(), но несмотря на это, прочие задачи продолжили выполняться в нормальном режиме. Как получилось так, что несмотря на то что процессор занят, он продолжает реагировать на запросы диспетчера задач? Может это оптимизация на этапе компиляции? И, если каждую милисекунду срабатывает прерывание, и ядро переключается с задачи на задачу, означает ли это что при использовании HAL_Delay( x ); ядро на самом деле потратит на сон при выполнении первой задачи N * x милисекунд (где N это число тасков)? А если ядро не успеет выполнить назначенный ему таск за 1 мс, то таск не будет выполнен в принципе?
На самом деле все немного проще.
Диспетчер задач осуществляет постоянные, непрерывные переключения между задачами. Если мы вызываем osDelay то тем самым даем диспетчеру задач понять, что нам не надо давать работать столько-то миллисекунд. И он просто не дает управление этой задаче. А если мы используем HAL_Delay, то пауза выполняется внутри самой задачи, за счет цикла опроса текущего времени внутри функции HAL_Delay. Остальные задачи в системе продолжают выполняться ведь диспетчер не обделит никого. Но при этом не образуется свободного невостребованного времени. Ведь если одна или несколько задач скажут диспетчеру, что есть свободное время, он не поделит его на другие задачи, нет, он потратит его на вызов Idle процесса. А он то нам и нужен чтобы в нем приостанавливать работу процессора и экономить питание.
@@VladimirMedintsev Спасибо! Эта часть теперь понятна. Не знаю, следующий вопрос слишком тривиальный или нет, но спрошу на всякий случай. А как же ядро умудряется поработать одновременно со всеми процессами в приложениях где соблюдение временных интервалов критично? Допустим мы параллельно в разных тасках работаем с BLE, пишем что-то во FLASH и заодно пытаемся отправить/принять несуразно огромное сообщение по UART. Как же ядро будет выбирать с чем ему сейчас поработать или переключаться между ними, когда попадание в интервал критично? Сможет ли ядро выполнить все эти задачи?
UPD. прошу прощения, перечитал ответ и увидел что диспетчер работает непрерывно, отредактировал свой вопрос
А вот в тех приложениях где соблюдение времени критично концепция немного меняется. Инициализируйте таймер, пусть он работает на заданной вами частоте и дергает прерывание. У прерывания наивысший приоритет и там делайте кратко свои важные и критичные вещи, а операционная система пусть работает сама по себе и готовит данные, рассовывает их в буфера, принимает решения и все такое. А критически важное будет всегда выполняться независимо и вовремя!
Спасибо!
А такой вопрос. Система freertos может прервать выполнение прерывания и отобрать время у такой задачи? Я стм32 еще не очень знаю, здесь система прерываний посложнее. Но помнится в AVR прерывание никто не может прервать. Поскольку они глобально выключаются в этот момент (SEI-CLI) А здесь tick_rate работает сам на прерывании от таймера. И наверное имеет больший приоритет перед другим железом? Я правильно понимаю?
Прерывание - это святое. Сам диспетчер задач вызывается прерыванием, как я понял
А что у нас с отладкой, при данных постоянных переключениях с дебагером теперь не поработаешь выводить на консоль все надо?
Нет вообще никаких проблем с дебагом. Не буду много букв писать, но если кратко, код внутри задачи можно легко отладить временнь повысив ее приоритет, а мультизадачные тонкости и так нормально отлаживаются. Ну скажем не сложнее чем обычную программу с обработчиками прерываний.
Пытаюсь перевести работу USART на DMA , попался пример где есть DMA и FreeRTOS и мне не понятна функция связанная с FreeRTOS . Вот пример обработчика прерывания с этими функциями , не понятна последняя vPortYieldFromISR(); Могли бы вы описать что она делает в данном контексте ?
void USART6_IRQHandler(void)
{
signed long Test;
int status = USART6->SR;
ReceiveFromCOM0_DMA(); // Начинаем новый приём с DMA
if (status & USART_SR_TC) // Передача окончена (последний байт полностью передан в порт)
USART6->SR &= ~USART_SR_TC; // Снимаем флаг
else if (status & USART_SR_IDLE) // Между байтами при приёме обнаружена пауза в 1 IDLE байт
{
USART6->DR; // Снимаем флаг
xSemaphoreGiveFromISR(semCOM1pak, &Test); // Симафорим задаче обработки пакетов
vPortYieldFromISR(); // Вызываем перепланировку в ОС
}
vPortYieldFromISR() это тоже самое что - if( xSwitchRequired != pdFALSE ) portYIELD()
у меня документации под рукой нету, но скорее всего вызов этого макроса заставляет шедулер вернуть нас к задаче с наивысшим приоритетом чтобы таким образом наверстать время потраченное в обработчике прерывания.
@@VladimirMedintsev короче мне FreeRTOS еще учить и учить
На самом деле нет там ничего особо сложного. Просто вся сложность понимания FreeRTOS в том, что вокруг самой операционной системы накручено очень много кода в виде макросов для портирования на различные платформы.
Владимир, спасибо большое за толковый материал. В одном проекте использую оцифровку сигнала АЦП с частотой 40 КГц, выборка 2048 значений, между каждой выборкой контроллеру позволяю поспать. Как такие задачи делаются под RTOS? Нужно всю выборку обрамлять как критическую секцию, или в то время когда контроллер спит отдать управление другим задачам (при том, что частота выборок не должна "уплывать")?
Честно говоря мы подобные задачи решаем немного по другому.
Если есть взаимодействие с DAC или ADC, то мы однозначно используем DMA. А вот при использовании DMA вам становятся доступными два бонуса. Во-первых процессор не занят и может заниматься своими делами пока у вас там с заданной частотой и в заданное место складываются ваши данные. А второе это есть доступ к обратным вызовам типа HAL_ADCEx_InjectedConvCpltCallback. Это такие заложенные в HAL функции которые вы можете переопределить в вашем коде и использовать при возникновении каких-либо событий. Ну например когда DMA подойдет к середине или закончит порученную работу. Таким образом вы сможете используя обратные вызовы дать своей задаче в операционной системе заменить буфер для DMA или начать обсчет полученной порции данных.
При этом не возникнет "узких" мест требующих использования критических секций кода.
Только такой подход сохранит вам частоту выборок в не зависимости от того чем занята ваша операционная система.
@@VladimirMedintsev пробовал я по DMA работать со встроенными АЦП, при прочих равных
условиях увеличивается уровень шума считанного сигнала (на входе АЦП цепочка усиления от датчиков с коэфф усиления в несколько тысяч). В AN2834 Application note How to get the best ADC accuracy in STM32 microcontrollers говорится, что для достижения лучших результатов нужно отключить по возможности внутреннее тактирование ненужной периферии на время замера (timers, communications..), а передача через DMA, как я понимаю, является асинхронным процессом по отношению
к ядру контроллера, может что-то с этим связано или я просто "не умею их правильно готовить"?
Я не знаю с чем это связано в вашем случае. У нас такого роста шума ни в одном проекте не наблюдалось. Честно говоря фразой "в несколько тысяч раз" я очень сильно обескуражен. Нет такого у нас ни разу не было. С тем что мы используем в основном DMA.
@@VladimirMedintsev Да, правильнее говорить о децибелах, но наличие проблемы это не отменяет. Ну да ладно, к FreeRTOS это не имеет никакого отношения, разберусь. PS. Код я вам отослал.
@@ivanivan3815 Как-то так получилось что я терпеть не могу говорить в децибелах. Вот не укладывается это понятие в моей голове. Кстати код по какой-то причине не пришел.
25:30__кто управляет таймером до запуска ОС ?
Им и до запуска и после никто не управляет. Вообще вопрос странный у таймера есть настройки они заданы при его инициализации, потом его запустили и он вызывает прерывание в котором увеличивается счетчик. Все.
Tim30_min_NORM*1.25 STM32 + FreeRTOS Часть(5_DMA)
LWIP запили пожалуйста видео.
Дякую за Ваші відео. Вивчаю stmки. Якщо у Вас буде можливість, будь- ласка, викладіть відео програмування роботи 2х енкодерів по переривання в RTOS.
Дякую
Стек на задачу указывается в слове а не в байте? Только от Вас такое слышу, в других обучающих видео или статьях говорят в байтах...
Это не обучающее видео. Я никого, ничему не учу. Я просто рассуждаю на тему. Кому интересно - смотрят.
Сам задался вопросом и погуглил. Нашел статью на хабре где сказано:
Значение параметра configMINIMAL_STACK_SIZE исчисляется НЕ в байтах, а в словах! Причем размер слова меняется от одного порта ОС к другому и он определен в файле portmacro.h дефайном portSTACK_TYPE. Например, в моем случае, размер слова составляет 4 байта. Таким образом, то, что параметр configMINIMAL_STACK_SIZE в моей конфигурации равен 128 означает, что минимальный размер стека для задачи равен 512 байт.
habr.com/ru/post/352782/
не совсем понимаю смысл uxTaskPriorityGet() : функция позволяет узнать приоритет задачи, который мы сами же и установили ранее в CubeMX, когда собственно и создавали эту самую задачу. Либо я дурак, либо это не совсем логичная функция...
Это более чем логичная функция так как приоритет задачи можно менять прямо в процессе ее выполнения.
@@VladimirMedintsev спасибо за ответ
На Ардуїно я рахував час за допомогою лічильника тактів, думаю: в STM теж є щось подібне.
Да, тоже есть SysTick и еще встроенный RTC
FreeRTTM больше подходит
как все тоже самое сделать в CubeIDE ?
Нет никакой разницы в какой среде программирования это делать.
@@VladimirMedintsev спасибо за ответ, но я новичок в программировании, и не совсем понятно как мне получить данные о памяти в CubeIDE, хотелось бы получить также как тут ruclips.net/video/wTK11IDpg7s/видео.html но не пойму где взять, как посмотреть адрес этой переменной (pcWriteBuffer), потом вы говорите "этот адрес скопировал сюда" что это за "сюда" где такое "сюда" найти в CubeIDE ? Я засунул эту переменную в Live Expressions но там в Value только [1024]
юнтил)))