Jump to content
    

vTaskSuspendAll или taskENTER_CRITICAL

Подскажите, что лучше использовать например при создании задачи и других подобных случаях, vTaskSuspendAll или taskENTER_CRITICAL ?

Задачи создаются и удаляются регулярно. Посмотрел код, taskENTER_CRITICAL taskEXET_CRITICAL короче, и стало быть выполняется быстрее.

Если запрещение прерываний ни чему не мешает, то стало быть из соображений скорости нужно использовать taskENTER_CRITICAL, а про vTaskSuspendAll вообще забыть, я верно рассуждаю ?

 

 

 

 vTaskSuspendAll();  // taskENTER_CRITICAL();

if(v_Task1_Handle==NULL)
      xTaskCreate(v_Task1,"v_Task1", 100 , NULL , tskIDLE_PRIORITY + 1, &v_Task1_Handle);

vTaskResumeAll();  //taskEXET_CRITICAL();

Share this post


Link to post
Share on other sites

Guest nill

Всё зависит от задачи. taskENTER_CRITICAL действует более грубо и лучше подходит для случаев, когда критична скорость выполнения. vTaskSuspendAll действует на уровне планировщика и используется для защиты длинных участков кода. В Вашем случае использование критических секций мне кажется более уместным.

Share this post


Link to post
Share on other sites

Подскажите, что лучше использовать например при создании задачи

При создании и удалении задачи вообще ничего из этого использовать не требуется в принципе. Вся критическая работа обеспечиватся собственно функциями создания и удаления задач и критическая секция внутри этих функций невелика о обеспечивается запрещением прерываний. Заложен так-же механизм удаления задачей самой себя. Так-никаких обрамлений НЕ ТРЕБУЕТСЯ.

и других подобных случаях

Получается, что "подобные случаи" оказались совершенно НЕ описанными :( и советовать что либо невозможно.

Из личного опыта мног-много постоянного использования FreeRTOS подобной системы, воспользоваться vTaskSuspendAll() как-то не приходилось. Хотя, конечно, система в которой я работаю, уже заметно отличается от исходной FreeRTOS в части добавления разных более узкоспециализированных системных вызовов нацеленых в том числе и на вызов из прерываний и на уменьшене длительности критических секций.

Share this post


Link to post
Share on other sites

При создании и удалении задачи вообще ничего из этого использовать не требуется в принципе.

 

 

А что если в момент после проверки условия if(v_Task1_Handle==NULL) но перед созданием задачи v_Task1_Handle изменится ? Какая-то задача создаст эту задачу, или удалит ?

При удалении задачи по указателю это ещё критичнее, т.к. если указатель стал 0, то удалится совсем другая задача, и будет непоправимый глюк.

 

Share this post


Link to post
Share on other sites

А что если в момент после проверки условия if(v_Task1_Handle==NULL) но перед созданием задачи v_Task1_Handle изменится ? Какая-то задача создаст эту задачу, или удалит ?

При удалении задачи по указателю это ещё критичнее, т.к. если указатель стал 0, то удалится совсем другая задача, и будет непоправимый глюк.

Господи! А какого черта так строить систему, что какие-то множественные задачи с неведомыми приоритетами наперегонки с друг другом могут создавать и убивать одну и ту-же задачу?

Даже если такой ужас как-то вдруг может быть обоснован, то по любому система на то и система, что имеет разграничение доступа - создайте очередь, семафор,..... Да и сам v_Task1_Handle может на крайний случай флагом работать - кроме NULL еще одно волшебное значене ему заведите.

Если куча задач только и занимается созданием и гроханием задачи, то может ее вообще не убивать - пусть себе живет.

Share this post


Link to post
Share on other sites

Господи! А какого черта так строить систему, что какие-то множественные задачи с неведомыми приоритетами наперегонки с друг другом могут создавать и убивать одну и ту-же задачу?

 

Такого ужаса конечно нет. Но для пущей уверенности, я всё равно предпочитаю проверять чему равен хэндлер.

Share this post


Link to post
Share on other sites

Но для пущей уверенности...

Ну все-же определитесь, либо надо, либо не надо.

Если "надо", то тогда думайте, как изменить подход к решению задачи.

Если не надо, то тогда к чему все эти телодвижения?

Пока похоже на "не знаю", посему буду делать всякие разные вещи которые может помогут от того, что я не знаю. Ситуация по крупному ничем не отличается от принесения, на всякий случай, в жертву барана :(.

 

Share this post


Link to post
Share on other sites

Да, еще в догонку - taskENTER_CRITICAL() для "дополнительного" закрытия системных и неведомых функций в общем случае использовать НЕЛЬЗЯ кактегорически. Дело в том, что те-же системные вызовы содержать внутри себя такие-же простейшие критические секции. И если taskENTER_CRITICAL() не подерживает вложенность или конфликтует с portENTER_CRITICAL(), то ой!

 

 

Share this post


Link to post
Share on other sites

Да, еще в догонку - taskENTER_CRITICAL() для "дополнительного" закрытия системных и неведомых функций в общем случае использовать НЕЛЬЗЯ кактегорически. Дело в том, что те-же системные вызовы содержать внутри себя такие-же простейшие критические секции. И если taskENTER_CRITICAL() не подерживает вложенность или конфликтует с portENTER_CRITICAL(), то ой!

 

По крайней мере для CortexM3/M4 taskENTER_CRITICAL == portENTER_CRITICAL, а последняя содержит счетчик и может дергаться рекурсивно

Share this post


Link to post
Share on other sites

Всё-таки ясности так и нету.

В описании функций taskENTER_CRITICAL сказано, что она может повредить стек

"NOTE: This may alter the stack (depending on the portable implementation) so must be used with care!" .

А в описании vTaskSuspendAll про стек не сказано, хотя taskENTER_CRITICAL там то же вызывается. И вообще, в каком интересно случае taskENTER_CRITICAL испортит стек ?

Share this post


Link to post
Share on other sites

Всё-таки ясности так и нету.

В описании функций taskENTER_CRITICAL сказано, что она может повредить стек

"NOTE: This may alter the stack (depending on the portable implementation) so must be used with care!" .

Не повредить, а изменить. Не ясно, что имеется в виду...

 

Но на самом деле просто посмотрите реализацию для вашей платформы. Или вам надо написать переносимо на любую платформу с фриртос?

 

vTaskSuspendAll останавливает шедулер, не трогает прерывания и тормознее, чем taskENTER_CRITICAL

taskENTER_CRITICAL запрещает прерывания с приоритетом меньше(на кортексе - больше) configMAX_SYSCALL_INTERRUPT_PRIORITY (соответственно и шедулер останавливается) и быстрее, чем vTaskSuspendAll

 

Share this post


Link to post
Share on other sites

Всё-таки ясности так и нету.

В описании функций taskENTER_CRITICAL сказано, что она может повредить стек

"NOTE: This may alter the stack (depending on the portable implementation) so must be used with care!" .

А в описании vTaskSuspendAll про стек не сказано, хотя taskENTER_CRITICAL там то же вызывается. И вообще, в каком интересно случае taskENTER_CRITICAL испортит стек ?

1) все-же не портит, а изменяет стек

2) не всегда, а зависит от порта и действительно порты, котрые используют стек при запрещении прерывания есть. Я, например, на 186 процессор использую не счетчик запретов прерываний, а сохранение сотояния в стеке. Удобно тем, что работает не только при вызове некой системной функции, но и при работе, например, с драйверами живущими своей жизнью.

 

 

 

 

vTaskSuspendAll останавливает шедулер, не трогает прерывания

Внутри себя трогает и не раз. Просто секции закрытия прерываний относительно короткие.

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...