|
|
  |
STM32F4 Ethernet + Dallas: перетягивание каната |
|
|
|
Aug 28 2015, 16:23
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(SasaVitebsk @ Aug 27 2015, 17:27)  Я бы никаких критических секций не делал. И даже не сталбы синхронизировать. массив структур. 1-ая задача заполняет текущую структуру и передаёт сообщением указатель на неё 2-ой задаче. 2-ая отображает. Если вторая работает быстрее первой, что логично, то по выполнению она засыпает, ожидая нового сообщения. В этом случае, в массиве требуется лишь 2 экземпляра структур. Если вторая задача работает медленней первой, то количество структур надо рассчитать. Ну и иногда будут пропуски. Это некритично. Можно конечно усыплять и 2 задачи, но я бы не стал. Я придерживаюсь принципа регулярной работы с оборудованием и асинхронной её обработки. Если не синхронизировать взаимодействие двух задач ОС, то рано или поздно из данных получится каша. Любая задача (или её участок) в общем случае могут работать как быстрее другой так и медленее в зависимости от приоритета и вызываемых функций ОС ожидающих каких-либо событий. Полагаться, что одна будет всегда быстрее, когда заранее не известен алгоритм работы, нельзя. Только выполнение внутри критической секции можно считать предопределённым. В описанном Вами случае, сколько Вы будете резервировать экземпляров структур под передачу? Как задача 1 узнает что какая-то структура освободилась? Никак? Будет писать в неё наугад в тот момент когда задача 2 как раз обрабатывает данные этой структуры? Как Вы передаёте сообщения между задачами? С помощью какого-то механизма ОС? Почему он лучше чем семафор/кр.секция? То что Вы попытались описать называется FIFO (элементарная единица его - упомянутая структура). Этот механизм можно применять для межзадачной синхронизации (и даже - межпроцессорной что тяжелее), но в данном случае он избыточен и неэффективен для данной задачи. Если не синхронизировать межзадачный доступ к указателям записи/чтения FIFO, то в один прекрасный момент FIFO переполнится и будет каша. А синхронизировать их - с помощью тех-же кр.секций или семафоров. Ну или нужно гарантировать что задача 2 всегда успевает вычитать FIFO до его переполнения, тогда не нужна синхронизация доступа к указателям FIFO.
|
|
|
|
|
Aug 28 2015, 16:31
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(k000858 @ Aug 28 2015, 09:50)  ...в принципе то производительно довольно высокая: 168МГц камень, езернет 100мб/с фулл, даже без ос (и остальных задач). и вполне хватает для сканирования эннного кол-ва 1Wire датчиков, с поддержкой 100МБит при максимальных 65535 пинговых пакетах, непрерывно, фулл рефрэш вэб морды, модбасы, порты логические, аналоговые, управление шимом, логика работы всего устройства, поддержка wifi, обработка бродкастов входящих, опрос локальной сети и опорного вэб сервера - всё этот камень протаскивает на ура в одной задаче... Сам lwip надо грамотно посмотреть глазками. Лично сам - находил там пару косяков. Всё перетряс, где было подозрительно - переписал. Особенно сам обработчик DMA прерывания, работа с памятью, ну и TCP состояния выпрямил(а то там косячёкс был в оригинале)... Я было хотел вчерась ещё отписаться, но Вам всё уже выше грамотно изложили. Рекомендую прислушаться к товарищу scifi - судя по инет инфе - он не мало соли переел по сетевым делам...
|
|
|
|
|
Sep 1 2015, 11:20
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(k000858 @ Sep 1 2015, 13:54)  ... есть разница, как работать с данными в тасках: передавать их как аргумент при создании таска (даже если они объявлены глобально) или просто юзать как глобальные переменные... Чем меньше сокральных знаний о внешнем мире внутри функции, таска, метода - тем локаничней, легко поддерживаемый, переносимый, локальный код. Как и почему переменная глобальна - то таск не виноват. И ещё... запихивая переменную в доступную всем область видимости - озаботьтесь о синхронности доступа к этой переменной. А то спустя года, либо другой писатель может забыть об асинхронном доступе к оной...
|
|
|
|
|
Sep 1 2015, 18:37
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Переменные передаваемые при создании задачи служат как правило для других целей. Обычно так делается для идентификации задачи, либо при создании нескольких копий одной задачи. Например я пишу задачу обслуживания COM порта. В задачу передаю номер этого порта. И запускаю 3 задачи на 3 COM порта.
Как правило, в реальном проекте появляются глобальные переменные или структуры, к которым требуется доступ из разных задач. Кроме того, что надо, как уже написали, чётко продумать механизм совместного использования, желательно подробно описать это там, где вы их объявляете. Существуют различные способы обеспечить грамотную работу с такими данными. Почитайте пожалуйста. Есть хорошее описание FreeRTOS на русском у Курница. Все ОС используют похожие механизмы, выработанные десятилетия назад. Поэтому это будет вдвойне полезно.
|
|
|
|
|
Sep 3 2015, 03:45
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(k000858 @ Sep 2 2015, 13:02)  да это понятное дело, что я могу сам сваять некий такс-тик-диаг, но подумалось, вдруг там уже есть велосипед на подобии стек контроля. нет так нет ) Контроль стека часто имеется в ОС (например в uCOS есть). Но контроль там делается насколько помню, только при переключении задачи, и если Вы внутри функции переполнили стек не вызывая функций ОС, то разрушение памяти (и возможное зависание) всё равно произойдёт. Полный контроль стека по-моему можно включить в опциях некоторых компиляторов (только всё будет тормозить), либо задействовать MPU (лишние затраты памяти, так как необходимо выравниваение стека). Но обычно контролируют глазами заполняя стек шаблоном. Но в общем случае задача в ОС у Вас может повиснуть не по причине разрушения стека, а по какой-то другой ошибке, со стеком не связанной. Так что с зависанием задач контроль стека Вам вряд-ли поможет. Поможет только отладчик и голова.
|
|
|
|
|
Sep 3 2015, 07:15
|

Местный
  
Группа: Участник
Сообщений: 319
Регистрация: 31-01-12
Пользователь №: 69 978

|
Если мне необходимо выполнять некую задачу (например опрос шины 1-wire) раз в секунду и по оконцовке перезапись измерений (массив структур или указатель на данные, не важно), как лучше реализовать? Код timer { osSemaphoreRelease(Semaphore); }
task { for(;;) { if(osSemaphoreWait( Semaphore , 0) == osOK) // опрос шины } } или Код task { for(;;) { // опрос шины
osDelay(1000); } } Или может есть более изящный способ реализовать такой алгорит на тасках/таймере/семафорах?
|
|
|
|
|
Sep 4 2015, 08:07
|

Местный
  
Группа: Участник
Сообщений: 319
Регистрация: 31-01-12
Пользователь №: 69 978

|
Цитата(SasaVitebsk @ Sep 4 2015, 08:22)  Ну я так понимаю, что вам же не надо точно 1 сек? Второй способ вполне подойдёт. в плане оптимальной работы в рамках ОС оба способа равнозначны? я почему так докапался, сейчас обсуждаю простенькую задачу, в процессе масштабы изменятся. хотелось бы на берегу понимать разницу этих способов (в рамках оптимальной работы задач в ОС)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|