реклама на сайте
подробности

 
 
9 страниц V  « < 4 5 6 7 8 > »   
Reply to this topicStart new topic
> FreeRTOS - минимальное время тика?
maxntf
сообщение May 30 2018, 07:51
Сообщение #76


Частый гость
**

Группа: Участник
Сообщений: 107
Регистрация: 13-05-09
Пользователь №: 49 008



Цитата(Forger @ May 30 2018, 10:32) *
Я смотрю Ваш код, по поиску (CTRL-F) вижу enableInterruptTIM10 только в одном месте ((

Да так и есть. Включаем, когда готовы принимать семафор.

Цитата(jcxz @ May 30 2018, 10:36) *
При частоте таймера ==100кГц и частоте ядра==16МГц, у Вас как только обнуляется ctim10ms, то в каждом прерывании вызывается xSemaphoreGiveFromISR(), а так как она наверняка длительная (и следующая за ней функция - скорей всего ещё более длительная, так как скорей всего делается решедулинг задач), то к моменту выхода из ISR успевает пройти >= 160 тактов ядра. А значит - ждёт уже новое прерывание таймера и сразу снова входит в ISR и всё повторяется. Естественно, что всё блокируется на постоянных входах в ISR.


Ага. Но только если я долблю таймером xSemaphoreGiveFromISR без обработки переменной каждые 10мкс все работает. xSemaphoreGiveFromISR() не должна повторно устанавливать семафор пока задача его не заберет, соответственно возвращает FALSE и portEND_SWITCHING_ISR ничего не переключает.
Код
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired != pdFALSE ) portYIELD()




Я как бы увидел что происходит.
В неработающем варианте
Код
xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken);

всегда возвращается pdTREU - соответственно постоянно перевызывается планировщик - почему так?

Сообщение отредактировал maxntf - May 30 2018, 07:50
Go to the top of the page
 
+Quote Post
Arlleex
сообщение May 30 2018, 08:05
Сообщение #77


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Цитата(maxntf @ May 30 2018, 11:51) *
Да так и есть. Включаем, когда готовы принимать семафор.
Я как бы увидел что происходит.
В неработающем варианте
Код
xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken);

всегда возвращается pdTREU - соответственно постоянно перевызывается планировщик - почему так?

Потому что задача находится в состоянии READY и готова к выполнению.
Приведите пожалуйста файл настройки FreeRTOSConfig.h.

Цитата(maxntf @ May 30 2018, 11:51) *
xSemaphoreGiveFromISR() не должна повторно устанавливать семафор пока задача его не заберет, соответственно возвращает FALSE и portEND_SWITCHING_ISR ничего не переключает.

Нет. Это означает, что после выдачи семафора планировщик не видит задач, готовых к выполнению, находящихся в состоянии READY, поэтому решедулинга задач не производится.

Сообщение отредактировал Arlleex - May 30 2018, 08:09
Go to the top of the page
 
+Quote Post
maxntf
сообщение May 30 2018, 08:06
Сообщение #78


Частый гость
**

Группа: Участник
Сообщений: 107
Регистрация: 13-05-09
Пользователь №: 49 008



Все разобрался, не верно обрабатывал семафор.
Нужно было так:
Код
void TIM10_IRQHandler(void)
{
    static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    
    if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET)
    {
        TIM_ClearFlag(TIM10, TIM_FLAG_Update);
        if(ctim10ms) ctim10ms--;
        else
        {
            if(xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken) != pdFAIL) portEND_SWITCHING_ISR(1);
        }
    }
}


Осталось понять нафиг xHigherPriorityTaskWoken.
И почему во всех примерах так
Код
            xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken);
            portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);

А у меня не работает?

P.S.
Все понял.
У меня задача всегда READY. Но в нее не успеваем попасть, и все время выполняем решедулинг!

Сообщение отредактировал maxntf - May 30 2018, 08:13
Go to the top of the page
 
+Quote Post
Arlleex
сообщение May 30 2018, 08:17
Сообщение #79


Местный
***

Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264



Код
if(xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken) != pdFAIL) portEND_SWITCHING_ISR(1);

Да не правильно так делать!

Проверять на возвращаемое значение выдачи семафора - зачем? Да и portEND_SWITCHING_ISR(1) не с 1 должно быть, а с xHigherPriorityTaskWoken.
Семафор Вы можете выдавать всегда сколько раз угодно - другое дело, что пока задача его не заберет, выдать его Вы не сможете.
Повысьте тактовую частоту CPU и проверьте еще раз свой нерабочий вариант. У меня на F4 приблизительно похожая задача, и все прекрасно успевает и обрабатывается как нужно.

Сообщение отредактировал Arlleex - May 30 2018, 08:21
Go to the top of the page
 
+Quote Post
maxntf
сообщение May 30 2018, 08:25
Сообщение #80


Частый гость
**

Группа: Участник
Сообщений: 107
Регистрация: 13-05-09
Пользователь №: 49 008



Цитата(Arlleex @ May 30 2018, 11:17) *
Код
if(xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken) != pdFAIL) portEND_SWITCHING_ISR(1);

Да не правильно так делать!

Проверять на возвращаемое значение выдачи семафора - зачем? Да и portEND_SWITCHING_ISR(1) не с 1 должно быть, а с xHigherPriorityTaskWoken.
Семафор Вы можете выдавать всегда сколько раз угодно - другое дело, что пока задача его не заберет, выдать его Вы не сможете.
Повысьте тактовую частоту CPU и проверьте еще раз свой нерабочий вариант. У меня на F4 приблизительно похожая задача, и все прекрасно успевает и обрабатывается как нужно.

В моем случае не совсем так.
у меня запускается планировщик, где то по середине прерывается, и запускается снова и так бесконечно. Так как задача всегда READY, но семафор обработать не успевает.
Конкретно в моем варианте нужно так:
Код
void TIM10_IRQHandler(void)
{
    static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, fGiveResult = pdFALSE;
    
    if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET)
    {
        TIM_ClearFlag(TIM10, TIM_FLAG_Update);
        if(ctim10ms) ctim10ms--;
        else
        {
            fGiveResult = xSemaphoreGiveFromISR(xSemNx, &xHigherPriorityTaskWoken);
            portEND_SWITCHING_ISR(xHigherPriorityTaskWoken & fGiveResult);
        }
    }
}


P.S.
На своей плате поднять частоту я не могу (на данный момент), а пропустить несколько отсчетов по 10мкс. в данном случае не критично и всегда можно подкорректировать.
Задача в первую очередь была понять почему так, а путей решения всегда бывает больше чем один!

Сообщение отредактировал maxntf - May 30 2018, 08:29
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 30 2018, 08:32
Сообщение #81


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(maxntf @ May 30 2018, 11:25) *
На своей плате поднять частоту я не могу (на данный момент), а пропустить несколько отсчетов по 10мкс. в данном случае не критично и всегда можно подкорректировать.
Задача в первую очередь была понять почему так, а путей решения всегда бывает больше чем один!

Я вам уже несколько раз объяснил и пример дал, но вы так и не поняли.... и опять всё то же самое накатали. Да ещё какой-то бред добавили с ПОБИТОВЫМ ИЛИ между логическими (видимо) типами...
Go to the top of the page
 
+Quote Post
maxntf
сообщение May 30 2018, 13:03
Сообщение #82


Частый гость
**

Группа: Участник
Сообщений: 107
Регистрация: 13-05-09
Пользователь №: 49 008



На семафоре полностью развязать задачу я не смог, а вот с очередями получилось.
Реальная задача динамически запускается и удаляется примерно на сотню миллисекунд - передает команду через ИК диод.
В общем сделал так, все работает без проблем на любой частоте таймера.
Код
void TIM10_IRQHandler(void)
{
    static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE, fGiveResult = pdFALSE;
    
    if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET)
    {
        TIM_ClearFlag(TIM10, TIM_FLAG_Update);
        if(ctim10ms) ctim10ms--;
        else
        {
            fGiveResult = xQueueSendToBackFromISR(xQueue, (const void *)0, &xHigherPriorityTaskWoken);
            if(xHigherPriorityTaskWoken & fGiveResult)
            {
                portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
            }
                else cal_ctim10ms++;
        }
    }
}
void Task_temp(void *pParams)
{
    uint32_t newValue = 100;
    uint32_t q_buf;
    
    xQueue = xQueueCreate(1, sizeof(uint32_t));


    ctim10ms = newValue;
    Tx_Init();

    while(1)
    {
        xQueuePeek(xQueue, &q_buf, 10);
    taskENTER_CRITICAL();
        ctim10ms = newValue - cal_ctim10ms;
        cal_ctim10ms = 0;
    taskEXIT_CRITICAL();
        GPIO_ToggleBits(GPIOB, GPIO_Pin_5);//пин контроля работы программы
        xQueueReceive(xQueue, &q_buf, 0);
    }
}

Если кто объяснит почему так нельзя приведя реальный пример как нужно - респект!
Go to the top of the page
 
+Quote Post
Forger
сообщение May 30 2018, 13:06
Сообщение #83


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(maxntf @ May 30 2018, 16:03) *
Если кто объяснит почему так нельзя приведя реальный пример как нужно - респект!

Очередь (Queue) в данном случае - как из пушки по воробьям.


Чтобы избежать таких детских граблей:
Код
if(xHigherPriorityTaskWoken & fGiveResult)

это следует писать хотя бы так:
Код
if( (xHigherPriorityTaskWoken != 0) && (fGiveResult != 0))

Вы вообще понимаете разницу между операторами & и && ?

Самый главный косяк, разрешать себе делать так: if(some) { ... }.
Это допустимо только для одного случая some есть bool, но в таких случаях эту some лучше называть иначе, чтобы было проще читать, например: bool isRxDone = что_то_что_возвращает true/false;
Тогда всякие условия читаются в разы проще: if (isRxDone) { ... }

Если же речь идет про все остальные типы, которые анализируются в блоке if {} else, то их сравнение следует указывать явно (number != 0), и обязательно брать в скобки, если в одном блоке if проверяются более одного значения.


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
maxntf
сообщение May 30 2018, 13:29
Сообщение #84


Частый гость
**

Группа: Участник
Сообщений: 107
Регистрация: 13-05-09
Пользователь №: 49 008



Цитата(Forger @ May 30 2018, 16:06) *
Очередь (Queue) в данном случае - как из пушки по воробьям.

Я спроси конкретный пример! А то все пишете плохо да плохо.

Цитата(Forger @ May 30 2018, 16:06) *
Вы вообще понимаете разницу между операторами & и && ?
Самый главный косяк, разрешать себе делать так: if(some) { ... }.

Отлично понимаю и вообще косяка не вижу. Поразрядное И с однотипными данными в условии, что тут такого!
Go to the top of the page
 
+Quote Post
Forger
сообщение May 30 2018, 13:33
Сообщение #85


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(maxntf @ May 30 2018, 16:29) *
Я спроси конкретный пример!

Конкретные примеры скачивайте с сайта freeRTOS.

Цитата
А то все пишете плохо да плохо.
Все просто - так оно и есть wink.gif

Цитата
Отлично понимаю и вообще косяка не вижу. Поразрядное И с однотипными данными в условии, что тут такого!
Вот с этого бреда и нужно было начинать тему. Дальше можно не продолжать, все ясно.

Напоследок. Вот так будет работать правильно:
Код
if ( (xHigherPriorityTaskWoken != pdFALSE) && (fGiveResult != pdFALSE) )


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
maxntf
сообщение May 30 2018, 13:50
Сообщение #86


Частый гость
**

Группа: Участник
Сообщений: 107
Регистрация: 13-05-09
Пользователь №: 49 008



Цитата(Forger @ May 30 2018, 16:33) *
Напоследок. Вот так будет работать правильно:
Код
if ( (xHigherPriorityTaskWoken != pdFALSE) && (fGiveResult != pdFALSE) )


#define pdFALSE ( ( BaseType_t ) 0 )
#define pdTRUE ( ( BaseType_t ) 1 )
typedef long BaseType_t;

xHigherPriorityTaskWoken и fGiveResult могут быть только 0x00000000 или 0x00000001

(xHigherPriorityTaskWoken & fGiveResult) в результате даст либо 0 либо 1
if(0) нет
if(1) да

P.S.
Ваш вариант с точки зрения читабельности, верный.
Фактически в данном случае мой вариант рабочий и перед тем чтоб такое написать я проверил что там за типы данных и какие значения принимают. Так пишу потому что последнее время писал только под pic с очень малым flash и приходилось очень много вот так подтачивать чтоб все влезло. Ваш код займет больше места, особенно если таких сравнений будет много.

Сообщение отредактировал maxntf - May 30 2018, 13:57
Go to the top of the page
 
+Quote Post
Forger
сообщение May 30 2018, 14:14
Сообщение #87


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(maxntf @ May 30 2018, 16:50) *
xHigherPriorityTaskWoken и fGiveResult могут быть только 0x00000000 или 0x00000001
Ну-ну ...
Мануалы читать - не Ваше.
Вот: https://www.freertos.org/xQueueSendToBackFromISR.html
Цитирую строчку для особе упертых: "pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL"

Цитата
Ваш код займет больше места, особенно если таких сравнений будет много.

Мля, что за идиотская привычка пошла у начинающих программеров экономить на спичках, плодя потенциальны места для будущих багов!!! cranky.gif
Забудьте про PIC и начинайте уже писать код так, как это делают остальные, без такой адской самодеятельности и оптимизаций!


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
maxntf
сообщение May 30 2018, 14:30
Сообщение #88


Частый гость
**

Группа: Участник
Сообщений: 107
Регистрация: 13-05-09
Пользователь №: 49 008



Не тот пример был.

Сообщение отредактировал maxntf - May 30 2018, 14:40
Go to the top of the page
 
+Quote Post
esaulenka
сообщение May 30 2018, 15:30
Сообщение #89


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(Forger @ May 30 2018, 16:06) *
Очередь (Queue) в данном случае - как из пушки по воробьям.

Расскажите пожалуйста, чем отличается очередь и семафор.
Напомню (и это важно!) мы по прежнему про FreeRTOS, а не о сферическом коне, как тут принято.


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
Forger
сообщение May 30 2018, 15:34
Сообщение #90


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(esaulenka @ May 30 2018, 18:30) *
Расскажите пожалуйста, чем отличается очередь и семафор.
Напомню (и это важно!) мы по прежнему про FreeRTOS, а не о сферическом коне, как тут принято.

RTFM


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post

9 страниц V  « < 4 5 6 7 8 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 17:11
Рейтинг@Mail.ru


Страница сгенерированна за 0.01513 секунд с 7
ELECTRONIX ©2004-2016