Ожидал примера создания очередей и обмена данными чрез них но тут только теория. пошл разобрался на практике) не с первого раза конечно и не с третьего но разобрался, не идеально конечно писал код. теперь задача кнопки посылает команду светодиоду. Видео сподвигло пойти найти статью))
Хочется продолжения уроков по FreeRTOS . Если можно остановитесь более подробно как правильно посчитать сколько нужно выделить байт для КУЧИ, сколько выделять под задачи. Еще не могу понять как правильно организовать работу с приемником UART . у меня все это работает на прерываниях с определением конца пакета данных и дальнейшим разбором данных в пакете , пока не пойму как это правильно перенести на FreeRTOS.
Да через какое-то время продолжение будет. А по поводу прерываний они как работали так и работают ничего специфического там менять под FreeRTOS не надо.
Я сейчас попробовал. Пока лучшее, что нашел для передачи двух USART из разных тасков - DMA, там же и NVIC включить каждому прийдётся. Немного посплю, и попробую сделать приём, у narodstream вроде как есть разжёванный материал по приёму через DMA - попробую повторить))
Спасибо за продолжение темы RTOS. (момент видео - 11.47) vTaskDelete лучше переключить в положение Disabled ? (чтобы задачи не могли удалятся и фрагментировать память).
Владимир добрый день. Хорошее видео, но заинтересовал один момент про удаление задач и их нецелесообразности удаления. В своём приложении я многократно удаляю и создаю задачу, но ещё не разу не упёрся в переполнение стека или кучи (специально проверял, около 40 раз точно происходил цикл создания- удаления). Более того, при просмотре отладчиком ясно видно, что выделяется одна и та же область памяти. Возможно все таки присутствует механизм защиты от таких утечек памяти. И сам собственно вопрос, в документации по freertos есть описание данного феномена очистки памяти при удалении задач?
Если вы удаляете задачу а потом ее создаете заново ничего плохого не произойдет. Более того я ни слова не сказал про утечку памяти. Я говорил о фрагментации памяти а она возникает если одну задачу удалили, а третью создали. Т.е. если вы создаете и удаляете разные задачи. В этом случае т.к. задачи разные соответственно и памяти выделяется под них разное количество. Это и приводит к ее фрагментация. Фрагментация памяти описана в документации на FreeRTOS. Более того, есть несколько (4) модели использования памяти. Как-нибудь сделаю видео по безопасному использованию FreeRTOS. И если посмотреть на safe FreeRTOS то можно увидеть что именно ее делает safe, и прежде всего это отсутствие возможности удалять задачи.
Спасибо за ролики. Прозвучало что память не фрагментируется. Но когда изучал документацию, в каждом порте есть несколько вариантов кучи heap1, 2,3 1й как сказано 2й серединка и 3й с сильной дефрагментацией. Может это только для АТМЕЛА или в КУБЕ этого не видно?
Да в видео действительно есть определенная неточность. И связано именно с heap. В последних версиях FreeRTOS действительно осуществляется дефрагментация памяти. Однако в версиях safe по прежнему не рекомендуется удаление задач.
@@OlegBovykin На самом деле у каждого подход к программированию индивидуальный. Как правило разделение по задачам - функциональное. Вычисление отдельно, обработка отдельно, сбор данных и так далее. Все задачи это определенные функциональные узлы из которых состоит ваша программа. Скорее всего вы создадите отдельную задачу которая будет обслуживать прием-передачу данных по шине CAN. В этом я не вижу каких-либо проблем. Вы просто задействуете стандартные функции CAN для отправки, приема и фильтрации сообщений. Если про передачу и писать отдельно не стоит, то на приеме вы будете или осуществлять "входной контроль" принятых данных и соответственно корректировать ошибки или просто воспользуетесь очередями для передачи полученных данных в обрабатывающую их задачу. Это не требует использования каких-либо специальных приемов.
А как быть с прерываниями? Ну вот есть пара задач, которые выполняются операционкой и тут прилетает прерывание которое меняет данные. Как им уживаться вместе?
Есть варианты! Но в общем это есть проблема общая для всех ОС. Что поделаешь! Алгоритмы должны быть слгка иными. Например буфферизация! Или очередь событий
Использовать очередь в прерывании, а потом уже обработать значение в нужной задаче. Или использовать глобальную переменную, потом её значение сохранять в другую переменную, не меняя исходную. Это позволит не терять данные
Т.е. под каждую новую задачу память выделяется статично и последовательно. При освобождении не в конце, возникает дыра, которая больше не может быть использована. Верно? Или даже с концом всё плохо? И если снять последнюю задачу, то под новую память выделится как будто последнюю задачу не удаляли?
Если я, например, начну передачу/прием по SPI неких данных, то данная ОС не оборвет передачу/прием во время процесса для перехода обслуживания других заданий? Если предположим не обрывает, то если этот процесс будет долгим, то другие задачи будут простаивать N-е время?
Есть специальные функции, прямо запрещающие ОС прерывать критически важные секции кода. С другой стороны используйте SPI совместно с DMA и головная боль не будет возникать в принципе.
Скажу откровенно, у меня уже несколько лет не было задач с Modbus. Я даже вспоминать не хочу как это делалось. За предложение спасибо всем, кто предлагает идеи для роликов, но Modbus в ближайшее время точно не будет.
Владимир, если я хочу объявить свои функции, их нужно объявлять вне тасков и использовать так же как и при написании кода без RTOS? Или есть нюансы? Спасибо за видосы!
Это же не IBM PC, создал задачу, выделилось под нее место и пусть себе живёт родимая. Под нее ресурсы не перевыделяются. Там есть разные модели использования памяти на самом деле, в документации хорошо про это сказано.
И чем же это плохо? Мне искренне интересно это узнать. Меня аж разрывает от любопытства почему же всегда обязательно и именно очередями... А вообще... У всего есть свое предназначение и ко всему надо относится с умом. Например результаты измерений, вычислений, обмен данными разумеется правильнее делать очередями. В то же время глобальные настройки и параметры однозначно глобальными переменными.
@@VladimirMedintsev Я и писал о передаче данных между задачами, в видео Вы говорили о передаче через глобальные переменные, что не есть хорошо, поскольку возможно одновременное (относительно одновременное) обращение задач к чтению и записи глобальной переменной. С Уважением!
@@alexandrsemenkoff6935 Да это невозможно, ни относительно, ни абсолютно. В один момент времени работает только одна задача или планировщик. Вы мыслите категориями многоядерных процессоров. А данные, если, к примеру, они не прут сплошным потоком от задачи к задаче, лучше передавать через глобальную переменную. Удобно, безопасно и быстро.
Существует общеизвестная рекомендация (не правило, а именно рекомендация) не использовать глобальные переменные там, где без них можно обойтись, потому что их использование таки может быть небезопасно. Первая потенциальная опасность - глобальная область видимости: когда проект большой, а еще вероятнее если над ним работают нескольких людей, есть вероятность получить трудноуловимый баг из-за обращения не туда. Например, у вас в модуле есть глобальная переменная dataCounter, а у вашего коллеги в модуле - глобальная переменная DataCounter. Вы можете по ошибке обратиться к его переменной, полагая что это ваша. При этом компилятор предательски промолчит и не укажет вам ни на какую ошибку и придется очень долго искать что не так. Вторая опасность проявляется при отсутствии атомарности доступа к переменной. Например, на 32-битной машине вы объявили 8-битную переменную. При ее инкременте, при отсутствии у процессора этой архитектуры специальных команд для работы с 8-битными данными, компилятор добавит дополнительные команды, для проверки на максимальное значение, обнуление и т.д. В этот момент может произойти переключение задач и данные в памяти будут искажены и другая задача, которая будет полагаться на эту глобальную переменную, получит неверные данные. Ситуация конечно крайне маловероятная, но нельзя полагаться на то, что она никогда не произойдет. В таком случае нужно обеспечить атомарность доступа к переменной. Но проще все же не использовать глобальные переменные без особой надобности.
Мне так привычнее и удобнее. Меня уже пытались тут убедить что это не правильно, я с ними согласился но все-равно так делаю. Ну хотя бы по той причине что эта разница не существенна и на понимание описанного в видео не влияет. А еще я микросхемы называю мелкосхемами и микрофон - мелкофоном. Но если вас это сильно парит, то видимо нам не по пути.
@I S Да проскакивало как-то видео паренек работающий в яндексе разбирает умную колонку и рассказывает. Правда как выяснилось он разрабатывал только какую-то малую часть и в конструкции самой колонки понимает так себе. Да и схему нам так и не покажут и все такое. Ну чутка для хайпа.
Передача через глобальные вредно для новичков ... В вашем случае сработает , если процессор 32-битный и переменная одна ... иначе можно передать неполные данные , а особенно если кто-то захочет передать массив
Вот уже не первый раз я слышу такие утверждения и еще ни один человек не сумел нормально обьяснить чем же это плохо. Напишите код который приведет к ошибке и тогда мы с вами это с радостью обсудим.
@@VladimirMedintsev В первую очередь, спасибо за видео - очень помагает разобраться с stm32. Возможно имелась ввиду проблема с синхронизацией данных между потоками/задачами. Не уверен, примнимо ли это для микроконтроллера, но в прикладном программировании (с++, java) встречается когда, например один поток начинает писать в массив/список/очеред/объект и посреди этой операции другой поток начинает читать/записывать в тот же массив/список/очеред/объект. самый позитивный исход: один(или два) потока будут иметь неправильные данные, худший исключение (exception) и аварийное завершение приложения. Если rtos записывает состояние невыполненной (например) задачи(task) в стек, то есть и вероятность что другая задача повлияет на глобальную переменную. Не могу утверждать насчёт микроконтроллеров - только начинаю эту тему осваивать
@@fizarum Можно было так не расписывать долго. В данном случае процессор - одноядерный. Поток один. Параллельного доступа нету. Речь идет о том, что люди слышали что так делать нельзя, а почему нельзя они не разобрались. Вот и боятся сами не понимая чего. Так нельзя делать только на процессоре STM32MP1.
Честно сказать более информативных и понятных уроков не видел! Спасибо большое за ваше желание помочь!
Добро пожаловать.
Одни комментарии полезнее других! Автору прежде всего спасибо и всем остальным также благодарность за горячие дисскусии!
Спасибо Вам за труды!
Было бы очень здорово увидеть продолжение темы.
Варианты правильной реализации очереди и мьютексов
Rudolph Sikorskiy хороший вопрос ! Тоже жду наглядную реализацию использования
До ваших роликов не знал, что freertos такая удобная
Ждемс примеров по очередям, симофорам и мутексам.
Спасибо, в основном по вашим видео изучаю стм32
Отлично видео.Довольно ясно и просто, но не примитивно, рассказывается про FreeRTOS.
Отличное очень понятное видео. С нетерпением жду продолжение по RTOS
Ожидал примера создания очередей и обмена данными чрез них но тут только теория. пошл разобрался на практике) не с первого раза конечно и не с третьего но разобрался, не идеально конечно писал код. теперь задача кнопки посылает команду светодиоду. Видео сподвигло пойти найти статью))
спасибо за интересное видео
Отличное видео. Ждём продолжения.
Отличные видео.
Спасибо! А что если задача требует больше времени чем слот для неё?
Владимир, добрый день. А можно комбинировать вместе с ОС обычную фоновую задачу, например опрос энкодера?
Ничего этому не мешает.
Хочется продолжения уроков по FreeRTOS . Если можно остановитесь более подробно как правильно посчитать сколько нужно выделить байт для КУЧИ, сколько выделять под задачи. Еще не могу понять как правильно организовать работу с приемником UART . у меня все это работает на прерываниях с определением конца пакета данных и дальнейшим разбором данных в пакете , пока не пойму как это правильно перенести на FreeRTOS.
Да через какое-то время продолжение будет.
А по поводу прерываний они как работали так и работают ничего специфического там менять под FreeRTOS не надо.
Я сейчас попробовал. Пока лучшее, что нашел для передачи двух USART из разных тасков - DMA, там же и NVIC включить каждому прийдётся. Немного посплю, и попробую сделать приём, у narodstream вроде как есть разжёванный материал по приёму через DMA - попробую повторить))
А сколько памяти занимает операционнка?
Спасибо за продолжение темы RTOS.
(момент видео - 11.47) vTaskDelete лучше переключить в положение Disabled ? (чтобы задачи не могли удалятся и фрагментировать память).
Достаточно просто ее не использовать.
Владимир добрый день. Хорошее видео, но заинтересовал один момент про удаление задач и их нецелесообразности удаления.
В своём приложении я многократно удаляю и создаю задачу, но ещё не разу не упёрся в переполнение стека или кучи (специально проверял, около 40 раз точно происходил цикл создания- удаления).
Более того, при просмотре отладчиком ясно видно, что выделяется одна и та же область памяти.
Возможно все таки присутствует механизм защиты от таких утечек памяти.
И сам собственно вопрос, в документации по freertos есть описание данного феномена очистки памяти при удалении задач?
Если вы удаляете задачу а потом ее создаете заново ничего плохого не произойдет.
Более того я ни слова не сказал про утечку памяти. Я говорил о фрагментации памяти а она возникает если одну задачу удалили, а третью создали. Т.е. если вы создаете и удаляете разные задачи. В этом случае т.к. задачи разные соответственно и памяти выделяется под них разное количество. Это и приводит к ее фрагментация.
Фрагментация памяти описана в документации на FreeRTOS. Более того, есть несколько (4) модели использования памяти. Как-нибудь сделаю видео по безопасному использованию FreeRTOS. И если посмотреть на safe FreeRTOS то можно увидеть что именно ее делает safe, и прежде всего это отсутствие возможности удалять задачи.
@@VladimirMedintsev , спасибо за разъяснения. Буду ждать видео подобного рода, так как очень востребованы они
Не у Вас ли был видиоурок про отображение переключений задач во freertos?
все-таки, лучше звучит "планировщик", чем "шедулер")))
Не понимаю, у процессора 8к памяти, но вылазит ошибка недостатка памяти, если ставишь тотал хип сайз в 3к. Как так?
Спасибо за ролики.
Прозвучало что память не фрагментируется. Но когда изучал документацию, в каждом порте есть несколько вариантов кучи heap1, 2,3 1й как сказано 2й серединка и 3й с сильной дефрагментацией.
Может это только для АТМЕЛА или в КУБЕ этого не видно?
Да в видео действительно есть определенная неточность. И связано именно с heap. В последних версиях FreeRTOS действительно осуществляется дефрагментация памяти. Однако в версиях safe по прежнему не рекомендуется удаление задач.
Ok. Спасибо.
Чтобы дефрагментация работала, у процессора должно быть достаточно "свободного времени".
Все доходчиво, понятно, как обычно.. riotOs' а не будет случаем в обзорах?
Я не использую riot, так что сказать ничего не могу.
Спасибо за ролик! А как подружить FreeRTOS и CAN?
Вызвать функции CAN из FreeRTOS. Разумеется это на половину шутка. Потому, что я не понимаю в чем сложность.
@@VladimirMedintsev Как правильно организовать задачи, очереди и процессинг входящих и исходящих сообщений в парадигме FreeRTOS?
@@OlegBovykin На самом деле у каждого подход к программированию индивидуальный. Как правило разделение по задачам - функциональное. Вычисление отдельно, обработка отдельно, сбор данных и так далее. Все задачи это определенные функциональные узлы из которых состоит ваша программа.
Скорее всего вы создадите отдельную задачу которая будет обслуживать прием-передачу данных по шине CAN. В этом я не вижу каких-либо проблем. Вы просто задействуете стандартные функции CAN для отправки, приема и фильтрации сообщений. Если про передачу и писать отдельно не стоит, то на приеме вы будете или осуществлять "входной контроль" принятых данных и соответственно корректировать ошибки или просто воспользуетесь очередями для передачи полученных данных в обрабатывающую их задачу. Это не требует использования каких-либо специальных приемов.
А как быть с прерываниями? Ну вот есть пара задач, которые выполняются операционкой и тут прилетает прерывание которое меняет данные. Как им уживаться вместе?
Используйте DMA.
Есть варианты! Но в общем это есть проблема общая для всех ОС. Что поделаешь! Алгоритмы должны быть слгка иными. Например буфферизация! Или очередь событий
Использовать очередь в прерывании, а потом уже обработать значение в нужной задаче. Или использовать глобальную переменную, потом её значение сохранять в другую переменную, не меняя исходную. Это позволит не терять данные
Т.е. под каждую новую задачу память выделяется статично и последовательно. При освобождении не в конце, возникает дыра, которая больше не может быть использована. Верно? Или даже с концом всё плохо? И если снять последнюю задачу, то под новую память выделится как будто последнюю задачу не удаляли?
Если я, например, начну передачу/прием по SPI неких данных, то данная ОС не оборвет передачу/прием во время процесса для перехода обслуживания других заданий? Если предположим не обрывает, то если этот процесс будет долгим, то другие задачи будут простаивать N-е время?
Есть специальные функции, прямо запрещающие ОС прерывать критически важные секции кода. С другой стороны используйте SPI совместно с DMA и головная боль не будет возникать в принципе.
Как на счет рассмотреть очереди и синхронизацию задач на примере реализации клиента MODBUS RTU?
Скажу откровенно, у меня уже несколько лет не было задач с Modbus. Я даже вспоминать не хочу как это делалось.
За предложение спасибо всем, кто предлагает идеи для роликов, но Modbus в ближайшее время точно не будет.
Спасибо. Скажите, а как определить необходимый размер стека для каждой из задач? Или как понять, что стека не хватает?
Третье видео из серии смотрите, там рассказано как это делать.
@@VladimirMedintsev , спасибо. Поспешил с вопросом, виноват.
А можно сслыку на сайт документации freertos?
Freertos.org
Владимир, если я хочу объявить свои функции, их нужно объявлять вне тасков и использовать так же как и при написании кода без RTOS?
Или есть нюансы?
Спасибо за видосы!
Точто так же как и без FreeRTOS. Т.е. согласно требований языка программирования.
@@VladimirMedintsev спасибо
Фрагментированная куча может привести к нехватке памяти. А не удаление задач не может?
Это же не IBM PC, создал задачу, выделилось под нее место и пусть себе живёт родимая. Под нее ресурсы не перевыделяются. Там есть разные модели использования памяти на самом деле, в документации хорошо про это сказано.
Уважаемый, лучше всего всегда пользоваться очередями, глобальные переменные это плохо в ос
И чем же это плохо? Мне искренне интересно это узнать. Меня аж разрывает от любопытства почему же всегда обязательно и именно очередями... А вообще...
У всего есть свое предназначение и ко всему надо относится с умом. Например результаты измерений, вычислений, обмен данными разумеется правильнее делать очередями. В то же время глобальные настройки и параметры однозначно глобальными переменными.
@@VladimirMedintsev Я и писал о передаче данных между задачами, в видео Вы говорили о передаче через глобальные переменные, что не есть хорошо, поскольку возможно одновременное (относительно одновременное) обращение задач к чтению и записи глобальной переменной. С Уважением!
@@alexandrsemenkoff6935 Да это невозможно, ни относительно, ни абсолютно. В один момент времени работает только одна задача или планировщик. Вы мыслите категориями многоядерных процессоров. А данные, если, к примеру, они не прут сплошным потоком от задачи к задаче, лучше передавать через глобальную переменную. Удобно, безопасно и быстро.
Вопрос: Какой префикс лучше использовать для имен глобальных переменных? Ответ: //
Существует общеизвестная рекомендация (не правило, а именно рекомендация) не использовать глобальные переменные там, где без них можно обойтись, потому что их использование таки может быть небезопасно. Первая потенциальная опасность - глобальная область видимости: когда проект большой, а еще вероятнее если над ним работают нескольких людей, есть вероятность получить трудноуловимый баг из-за обращения не туда. Например, у вас в модуле есть глобальная переменная dataCounter, а у вашего коллеги в модуле - глобальная переменная DataCounter. Вы можете по ошибке обратиться к его переменной, полагая что это ваша. При этом компилятор предательски промолчит и не укажет вам ни на какую ошибку и придется очень долго искать что не так. Вторая опасность проявляется при отсутствии атомарности доступа к переменной. Например, на 32-битной машине вы объявили 8-битную переменную. При ее инкременте, при отсутствии у процессора этой архитектуры специальных команд для работы с 8-битными данными, компилятор добавит дополнительные команды, для проверки на максимальное значение, обнуление и т.д. В этот момент может произойти переключение задач и данные в памяти будут искажены и другая задача, которая будет полагаться на эту глобальную переменную, получит неверные данные. Ситуация конечно крайне маловероятная, но нельзя полагаться на то, что она никогда не произойдет. В таком случае нужно обеспечить атомарность доступа к переменной. Но проще все же не использовать глобальные переменные без особой надобности.
Вопрос немного не в тему: почему вы микроконтроллер называете процессором? Разные же устройства по назначению и по содержанию.
Мне так привычнее и удобнее. Меня уже пытались тут убедить что это не правильно, я с ними согласился но все-равно так делаю. Ну хотя бы по той причине что эта разница не существенна и на понимание описанного в видео не влияет. А еще я микросхемы называю мелкосхемами и микрофон - мелкофоном. Но если вас это сильно парит, то видимо нам не по пути.
Большинство микроконтрольщиков называют процом. Парень из Яндекса, который умную колонку разрабатывал, тоже все время называет проц.
@I S Да проскакивало как-то видео паренек работающий в яндексе разбирает умную колонку и рассказывает. Правда как выяснилось он разрабатывал только какую-то малую часть и в конструкции самой колонки понимает так себе. Да и схему нам так и не покажут и все такое. Ну чутка для хайпа.
@@81n90 вообще не показатель.
@@nikotinesmola ну да не показатель, можете называть как хотите, хоть утюгом, дело ваше, ну и ваше окружение. Если им так будет понятнее, почему нет.
полагаю, автору должно государство назначить оклад. вклад бесценен.
Спасибо
Передача через глобальные вредно для новичков ... В вашем случае сработает , если процессор 32-битный и переменная одна ... иначе можно передать неполные данные , а особенно если кто-то захочет передать массив
Вот уже не первый раз я слышу такие утверждения и еще ни один человек не сумел нормально обьяснить чем же это плохо. Напишите код который приведет к ошибке и тогда мы с вами это с радостью обсудим.
@@VladimirMedintsev Беру свои слова обратно , я ошибался ... ибо только что узнал о критических секциях , из вашего видео ))
@@Константин-у9у8и это где у него было, чего то пропустил я. На каком моменте, подскажи пожалуйста.
@@VladimirMedintsev
В первую очередь, спасибо за видео - очень помагает разобраться с stm32.
Возможно имелась ввиду проблема с синхронизацией данных между потоками/задачами. Не уверен, примнимо ли это для микроконтроллера, но в прикладном программировании (с++, java) встречается когда, например один поток начинает писать в массив/список/очеред/объект и посреди этой операции другой поток начинает читать/записывать в тот же массив/список/очеред/объект. самый позитивный исход: один(или два) потока будут иметь неправильные данные, худший исключение (exception) и аварийное завершение приложения. Если rtos записывает состояние невыполненной (например) задачи(task) в стек, то есть и вероятность что другая задача повлияет на глобальную переменную.
Не могу утверждать насчёт микроконтроллеров - только начинаю эту тему осваивать
@@fizarum Можно было так не расписывать долго. В данном случае процессор - одноядерный. Поток один. Параллельного доступа нету.
Речь идет о том, что люди слышали что так делать нельзя, а почему нельзя они не разобрались. Вот и боятся сами не понимая чего.
Так нельзя делать только на процессоре STM32MP1.