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

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


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

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



Никакой конкретики. Отлично.
Ещё раз. Пожалуйста, расскажите своё видение отличий очереди и семафора.
Что вижу я: макрос vSemaphoreCreateBinary вызывает xQueueGenericCreate, макрос xSemaphoreGive вызывает функцию xQueueGenericSend.
Т.е. внутри что семафор, что очередь из одного элемента отличаются минимально.

А теперь расскажите, почему эту очередь maxntf ни в коем случае использовать не должен.


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


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

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



Цитата(esaulenka @ May 30 2018, 20:15) *
...

"Разжевать и положить в рот"? Нет, я пас. Извините, но мы не в ясельной группе!
Если вы сами до сих пор еще не разобрались, где какой сервис RTOS нужно использовать, а где какой будет избыточен, то я ни как Вам не смогу помочь.
В качестве "домашнего задания": подумайте, зачем в RTOS существует такое разноообразие сервисов?


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


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

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



Цитата(esaulenka @ May 30 2018, 20:15) *
Никакой конкретики. Отлично.
Ещё раз. Пожалуйста, расскажите своё видение отличий очереди и семафора...
А теперь расскажите, почему эту очередь maxntf ни в коем случае использовать не должен.

Опыта с freertos мало, точнее нет. Работал только с кооперативной ОС OSA, под pic_и, там все проще. По этому не смог сделать нужное мне на семафорах, в частности мне нужно было задачу разблокировать , а семафор забрать уже так, чтоб посреди этой функции снова не влететь в прерывание. А вот с очередями получилось, так как там можно прочитать сообщение не забирая его тем самым разблокировать задачу, а потом забрать когда задача будет к этому готова.

Цитата(Forger @ May 30 2018, 20:31) *
В качестве "домашнего задания": подумайте, зачем в RTOS существует такое разноообразие сервисов?

Чтоб народ с ума сводить sm.gif. Чем дальше углубляюсь, тем больше вижу, что там куча всего через дефайны дублируется.

Сообщение отредактировал maxntf - May 30 2018, 17:59
Go to the top of the page
 
+Quote Post
Forger
сообщение May 30 2018, 18:27
Сообщение #94


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

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



Цитата(maxntf @ May 30 2018, 20:58) *
Чтоб народ с ума сводить sm.gif. Чем дальше углубляюсь, тем больше вижу, что там куча всего через дефайны дублируется.

Это во FreeRTOS они все сделаны можно сказать "через одну щель", потому и не славится эта RTOS особой производительностью и малым размером. Но зато под нее существует порт практически под любой проц.
Увы, такова плата за универсальность и поддержку немереного числа платформ.

В самом начале пути можно делать как угодно: и через зад лечить зубы и через нос зашивать пятку.
Но потом все равно придется делать как надо ))


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


Местный
***

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



Взял отладку на STM32F429, повторил код автора топика.
Код
int main(void)
{
    HW_MCUInit();
    
    SampleSemaphoreHandle = xSemaphoreCreateBinary();
    
    xTaskCreate(&SampleHandlingTask, "SampleHandlingTask", 512, NULL, SAMPLE_HANLING_TASK_PRIORITY, &SampleHandlingTaskHandle);
    
    vTaskStartScheduler();
    
    return 0;
}

Код
void SampleHandlingTask(void *Parameters)
{
    HW_TIMER_START();
    
    while(1)
    {
        xSemaphoreTake(SampleSemaphoreHandle, 10);
        
        unsigned int ReshedulingTime = DWT_CYCCNT - CYCCNT_ISR_Vale;

        ctim10ms = 10;
        
        GPIOG->ODR ^= GPIO_Pin_13;
    }
}

Код
volatile unsigned int ctim10ms = 10000;
volatile unsigned int CYCCNT_ISR_Vale = 0;

void TIM1_UP_TIM10_IRQHandler(void)
{
    static BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    
    if(TIM1->SR & TIM_IT_Update)
    {
        if(ctim10ms)
            ctim10ms--;
        else
        {
            xSemaphoreGiveFromISR(SampleSemaphoreHandle, &xHigherPriorityTaskWoken);
            portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
            
            CYCCNT_ISR_Vale = DWT_CYCCNT;
        }
        TIM1->SR = (uint16_t)~TIM_IT_Update;
    }
}

Не работает (вернее работает через ж*пу - светодиод еле видно - но, видимо, переключается).
Ставлю таймер на 100мкс, все работает. Отлично - открываю отладчик, запускаю код в нем. Отключаю работу таймера при отладке, чтобы не поломалась система и результаты были честными.

В теле задачи ставлю точку останова на
Код
ctim10ms = 10;

и результат 256 тактов CPU тратит на работу переключателя контекста.

256/16000000Гц = 16мкс.

Далее точно также посчитаем, сколько выполняется тело цикла прерывания: 40 тактов в случае, если ctim10ms отличен от 0 и вызовов xSemaphoreGiveFromISR() не производится, и 356 тактов в случае, если ctim10ms достигло 0 и были вызваны сервисы RTOS выдачи семафора. Добавим ко всему этому по 12 тактов на вход/выход в прерывание (предполагаем, что tail-chaining и late-arriving не запускаются в связи с непериодичностью): итого 64 и 380 тактов соответственно. В микросекундах это 4 и 23.75 соответственно при синхронизации CPU от 16МГц. О какой нафиг тут периодичности прерываний 10мкс может идти речь - не пойму. У Вас за 23.75мкс сформируется еще 2 прерывания, которые Вы пропустите и обработаете как одно.

P.S. Поднял частоту работы системы - и теперь 10мкс прерывания работают отлично, что и требовалось доказать.
А Ваши старания с очередью... Ну не уверен я, что оно работает действительно так, как задумано.

Сообщение отредактировал Arlleex - May 30 2018, 19:42
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 30 2018, 20:05
Сообщение #96


Гуру
******

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



Цитата(Arlleex @ May 30 2018, 22:41) *
Взял отладку на STM32F429, повторил код автора топика.
...
О какой нафиг тут периодичности прерываний 10мкс может идти речь - не пойму. У Вас за 23.75мкс сформируется еще 2 прерывания, которые Вы пропустите и обработаете как одно.

Пролистайте тему выше. Ещё в 47-м, 49-м и 75-м сообщениях тут я писал об этом. Тут даже отладка не нужна - и так всё очевидно. Но "чукча не читатель, чукча писатель"...... laughing.gif
Go to the top of the page
 
+Quote Post
Arlleex
сообщение May 30 2018, 20:15
Сообщение #97


Местный
***

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



Цитата(jcxz @ May 30 2018, 23:05) *
Пролистайте тему выше. Ещё в 47-м, 49-м и 75-м сообщениях тут я писал об этом. Тут даже отладка не нужна - и так всё очевидно. Но "чукча не читатель, чукча писатель"...... laughing.gif

Мне просто было интересно поковырять, пока еда готовится biggrin.gif
Но где-то внутри тоже предполагал, что времени не хватает просто...
Go to the top of the page
 
+Quote Post
maxntf
сообщение May 31 2018, 13:15
Сообщение #98


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

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



Всем участникам спасибо за помощь и в некоторых случаях за "мат". Кое как вроде разобрался, что то может не до понял, в дальнейшем процессе освоения дойдет.
Остался один не решенный момент, а именно макрос
Код
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);


В начале я думал, что он работает следующим образом:
Task1 имеет более высокий приоритет чем Task2, но она заблокирована, а работает Task2.
Вдруг в каком то месте Task2 возникает прерывание, в котором происходит разблокировка Task1 (установили семафор например, который ждет Task1).
В макросе portYIELD() грубо говоря поменяли адрес (на задачу с большим приоритетом) куда нужно вернуться.
После выхода из функции обработки прерывания уже попадаем в Task1, а не возвращаемся в Task2.

Но судя по отладке это не так.
Кто может без нервов разжевать, как оно работает?
Go to the top of the page
 
+Quote Post
Arlleex
сообщение May 31 2018, 13:44
Сообщение #99


Местный
***

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



Цитата(maxntf @ May 31 2018, 17:15) *
В начале я думал, что он работает следующим образом.

Вы все правильно думаете. Прерывания - это асинхронные события, и всегда нужно стараться сократить время реакции системы на них.
Ваши домыслы, очевидно, верны.
Ну а при отладке Вы что-то делаете не так...
Еще раз прошу, скиньте файл FreeRTOSConfig.h, там много интересных настроек, и без включения некоторых из них действительно можно наблюдать чудеса.
Go to the top of the page
 
+Quote Post
maxntf
сообщение May 31 2018, 13:46
Сообщение #100


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

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



Цитата(Arlleex @ May 31 2018, 16:44) *
Еще раз прошу, скиньте файл FreeRTOSConfig.h

Вот пожалуйста.
Код
#define configTICK_RATE_HZ                        ( ( TickType_t ) 1000 )
#define configCPU_CLOCK_HZ                        ( SystemCoreClock )
#define configUSE_PREEMPTION                    1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION    1
#define configUSE_IDLE_HOOK                        1
#define configUSE_TICK_HOOK                        1
#define configMAX_PRIORITIES                    ( 5 )
#define configMINIMAL_STACK_SIZE                ( ( unsigned short ) 170 )
#define configTOTAL_HEAP_SIZE                    ( ( size_t ) ( 14 * 1024 ) )
#define configMAX_TASK_NAME_LEN                    ( 16 )
#define configUSE_TRACE_FACILITY                1
#define configUSE_16_BIT_TICKS                    0
#define configIDLE_SHOULD_YIELD                    1
#define configUSE_MUTEXES                        1
#define configQUEUE_REGISTRY_SIZE                5
#define configCHECK_FOR_STACK_OVERFLOW            2
#define configUSE_RECURSIVE_MUTEXES                1
#define configUSE_MALLOC_FAILED_HOOK            1
#define configUSE_APPLICATION_TASK_TAG            0
#define configUSE_COUNTING_SEMAPHORES            1

/* Software timer related definitions. */
#define configUSE_TIMERS                        1
#define configTIMER_TASK_PRIORITY                ( configMAX_PRIORITIES - 1 )
#define configTIMER_QUEUE_LENGTH                10
#define configTIMER_TASK_STACK_DEPTH            configMINIMAL_STACK_SIZE

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES             0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */

#define INCLUDE_vTaskPrioritySet        1
#define INCLUDE_uxTaskPriorityGet        1
#define INCLUDE_vTaskDelete                1
#define INCLUDE_vTaskCleanUpResources    0
#define INCLUDE_vTaskSuspend            1
#define INCLUDE_vTaskDelayUntil            1
#define INCLUDE_vTaskDelay                1

/* Standard assert semantics. */
//#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for(;; ); }    

/* Use the system definition, if there is one */
#ifdef __NVIC_PRIO_BITS
    #define configPRIO_BITS       __NVIC_PRIO_BITS
#else
    #define configPRIO_BITS       4        /* 15 priority levels */
#endif

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY            15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5

/* The lowest priority. */
#define configKERNEL_INTERRUPT_PRIORITY     ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Priority 5, or 95 as only the top four bits are implemented. */
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY     ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

/* Run time stats related macros. */
#define configGENERATE_RUN_TIME_STATS    0

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
Go to the top of the page
 
+Quote Post
Arlleex
сообщение May 31 2018, 14:05
Сообщение #101


Местный
***

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



Ну вроде в порядке все, только определены ли у Вас функции-ловушки всех установленных опций? Я про IdleHook, TickHook и т.д.
Как проверяете, что RTOS не переключается на задачу с самым высоким приоритетом?
Go to the top of the page
 
+Quote Post
maxntf
сообщение May 31 2018, 14:13
Сообщение #102


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

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



Цитата(Arlleex @ May 31 2018, 17:05) *
Ну вроде в порядке все, только определены ли у Вас функции-ловушки всех установленных опций? Я про IdleHook, TickHook и т.д.

Код
void vApplicationIdleHook(void)
{
    //HOOK_PULSE;
}
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
{
    for(;;);
}
void vApplicationTickHook(void)
{
    
}
void vApplicationMallocFailedHook(void)
{
    for(;;);
}

#define HOOK_PULSE GPIO_ToggleBits(GPIOB, GPIO_Pin_5) - это вывод пина на осциллограф, когда нужно что то проверить. А так они IdleHook, TickHook пока у меня пустые.
Цитата(Arlleex @ May 31 2018, 17:05) *
Как проверяете, что RTOS не переключается на задачу с самым высоким приоритетом?

Шагаю по прерыванию, а после выхода из обработчика прерывания вываливаюсь в Task2 (точнее в тело функции которую она периодически вызывает) с низким приоритетом (приоритет 1) а Task1 который ждет семафор (только у меня событие из очереди) приоритет 2.

Сообщение отредактировал maxntf - May 31 2018, 14:42
Go to the top of the page
 
+Quote Post
Arlleex
сообщение May 31 2018, 15:05
Сообщение #103


Местный
***

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



Код
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);

А зачем два раза подряд вызывать ожидающие функции xQueuePeek() и xQueueReceive() причем подряд?
Как-то не корректно Вы с очередью работаете...
xQueuePeek() считает значение из очереди, но не удалит его оттуда.
xQueueReceive() тоже считает, но удалит (FIFO).
Почему просто не вызывать xQueueReceive()?

Сообщение отредактировал Arlleex - May 31 2018, 15:10
Go to the top of the page
 
+Quote Post
maxntf
сообщение Jun 1 2018, 09:18
Сообщение #104


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

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



Цитата(Arlleex @ May 31 2018, 18:05) *
А зачем два раза подряд вызывать ожидающие функции xQueuePeek() и xQueueReceive() причем подряд?
Как-то не корректно Вы с очередью работаете...
xQueuePeek() считает значение из очереди, но не удалит его оттуда.
xQueueReceive() тоже считает, но удалит (FIFO).
Почему просто не вызывать xQueueReceive()?

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

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

В частности сейчас у меня проблема, что не работает portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
Докопался portYIELD(), понял что он устанавливает флаг прерывания PendSV, в котором ОС выполняет переключение контекста.

А теперь о моих баранах. В Task2(с низким приоритетом) у меня вызывается функция F1() с той самой тачлиб что фигурировала в начале темы. Так вот после выхода из обработчика прерывания в котором вызывался portEND_SWITCHING_ISR(xHigherPriorityTaskWoken), программа попадает в место из картинки. Получается что флаг прерывания PendSV был установлен когда судя по записи __disable_irq() все прерывания били отключены.



Убрал нафиг эти __disable_irq() и __enable_irq(). Но все равно не работает.

Как бы в отладчике узнать включено ли прерывание для PendSV?

P.S.
Кстати у меня с калибровкой на 10мкс все работало четко, только потому, что не переключается контекст и время на это не тратится и все успевает. Вот так бывает sm.gif

Сообщение отредактировал maxntf - Jun 1 2018, 09:23
Go to the top of the page
 
+Quote Post
Forger
сообщение Jun 1 2018, 10:39
Сообщение #105


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

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



Цитата(maxntf @ Jun 1 2018, 12:18) *
По этому просьба больше не писать что я туплю и делаю не так.

Дык, тогда и не пишите тут то, что вызывает такую реакцию, кстати, вполне естественную реакцию laughing.gif

зы. "По этому" в данном случае пишется слитно biggrin.gif



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

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

 


RSS Текстовая версия Сейчас: 27th April 2024 - 14:52
Рейтинг@Mail.ru


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