Перейти к содержанию
    

FreeRTOS - минимальное время тика?

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

 

Так вот...

Упростил как мог, все выкинул никаких тачлибов и всего остального, только 2 задачи.

xSemaphoreHandle xSem1ms;    
volatile uint32_t ctim100us;    
uint8_t FlagCreateTask;
void TIM10_IRQHandler(void)
{
    static portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    
    if(TIM_GetFlagStatus(TIM10, TIM_FLAG_Update) != RESET)
    {
        TIM_ClearFlag(TIM10, TIM_FLAG_Update);
        if(ctim100us) ctim100us--;
        else 
        {
            xSemaphoreGiveFromISR(xSem1ms, &xHigherPriorityTaskWoken);
            portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
        }
    }
}
int main(void)
{    
    xTaskCreate(Task2, "Task2-handler", configMINIMAL_STACK_SIZE, NULL, 1, NULL);    
    vTaskStartScheduler();
}
void Task2(void *pParams)
{

    FlagCreateTask = 0;
    vSemaphoreCreateBinary(xSem1ms);

    xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
    while(1)
    {
        if(FlagCreateTask != 0) continue;
        xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
    }
}
void Task1(void *pParams)
{
    uint16_t count = 3;

    xSemaphoreTake(xSem1ms, 0);
    FlagCreateTask = 1;

    ctim100us = count;
    Tx_Init();

    while(1)
    {
        if(xSemaphoreTake(xSem1ms, 10) != pdTRUE) continue;
        count++;
        if(count > 9) break;
    taskENTER_CRITICAL();
        ctim100us = count;
    taskEXIT_CRITICAL();
        GPIO_ToggleBits(GPIOB, GPIO_Pin_5);//пин контроля работы программы
    }
    TIM_DeInit(TIM10);
    FlagCreateTask = 0;
    vTaskDelete(NULL);
}

 

После выхода из обработчика прерывания TIM10 в случае выполнения portEND_SWITCHING_ISR(xHigherPriorityTaskWoken) программа попадает в Task2.

О Боже, за что?

Даже таймер настроен на 100мкс

Изменено пользователем maxntf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так вот...

Судя по всему, у обеих задач одинаковые приоритеты.

А Task2 вообще ВСЕГДА готова к выполнения.

Т.е. всегда что-то делает...

Более того, честно говоря, я чуть моск не сломал, пока попытался понять логику работы "флажка" FlagCreateTask :wacko:

Так нифига и не понял, что вы задумали (((

 

А вообще, прочитайте, наконец, нормальный мануал, как писать проекты под RTOS, посмотрите видео на ютубе, примеры из мануала и т. п.

Посмотрите примеры применения, конкретные рабочие примеры. Желательно это делать перед тем, как плодить франкешнейнов самодеятельность, и уж тем более тут это публиковать ;)

 

FreeRTOS запускается с полпинка и работает как и любая друга RTOS, но необходимы хотя бы базовые знания. Решите сначала этот вопрос!

Уверяю, ничего сверхсложного тут нет, все через это прошли ))

 

Немного упрощу задачу. Вот яркий пример откровенной самодеятельности:

    while(1)
    {
        if(FlagCreateTask != 0) continue;
        xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
    }

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Судя по всему, у обеих задач одинаковые приоритеты.

 

Судя по чему конкретно?

xTaskCreate(Task2, "Task2-handler", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL);

 

А вообще, прочитайте, наконец, нормальный мануал, как писать проекты под RTOS...

 

Какие проекты, я про конкретный случай спрашиваю.

Убрал то, что моск ломает.

void Task2(void *pParams)
{
    vSemaphoreCreateBinary(xSem1ms);
    xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
    while(1);
}
void Task1(void *pParams)
{
    xSemaphoreTake(xSem1ms, 0);
    ctim100us = 10;
    Tx_Init();
    xSemaphoreTake(xSem1ms, 10);    
    TIM_DeInit(TIM10);
    vTaskDelete(NULL);
}

 

Если задачи с одинаковым приоритетом, почему? Может где то настройки FreeRTOS?

Если Task2 всегда готова к выполнению, то когда срабатывает portEND_SWITCHING_ISR(xHigherPriorityTaskWoken) разве после выхода из прерывания контекст не должен переключится с Task2 на Task1?

Изменено пользователем maxntf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

xTaskCreate(Task2, "Task2-handler", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
xTaskCreate(Task1, "Task1-handler", configMINIMAL_STACK_SIZE, NULL, 2, NULL);

Исходя из мануала

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

 

Убрал то, что моск ломает.
Уже проще ;)

 

Может где то настройки FreeRTOS?
Еще раз на всякий случай приведите настройки (в теге CODEBOX).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще раз на всякий случай приведите настройки (в теге CODEBOX).

Для проверки работы приоритетов поменял приоритеты задач - программа в Task1 вообще не попадает, значит приоритеты работают.


#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 ) 120 )
#define configTOTAL_HEAP_SIZE					( ( size_t ) ( 12 * 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

#endif /* FREERTOS_CONFIG_H */

Изменено пользователем maxntf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Создайте сразу две задачи (можно с разными приоритетами),

воткните в бесконечный цикл каждой задачи что-нибудь для постановки ее в очередь ожидания, например sleep(1) (или что там используется у freertos).

 

Поставьте по одному бряку внутри задач 1 и 2 и см. как идет процесс переключения задач.

 

Они должны переключаться по очереди.

 

Далее добавляйте свой код по чуть-чуть и смотрите, что сыпется от него.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Похоже отладчик всему беда.

Вывел сигнал с прерывания таймера на осциллограф, по количеству тактов определил что все работает нормально.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что же за отладчик такой, если не секрет?

Тот что в Keil.

Причем только в пошаговом режиме кнопками Step или Step Over при выходе из обработчика прерываний.

А если поставить брекпоинты в задачах, и выйти из прерывания Step Out или Run тогда попадаем куда нужно, то есть в Task2.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тот что в Keil.

Причем только в пошаговом режиме кнопками Step или Step Over при выходе из обработчика прерываний.

А если поставить брекпоинты в задачах, и выйти из прерывания Step Out или Run тогда попадаем куда нужно, то есть в Task2.

Оптимизацию отключите, хотя бы для debug сборки. При пошаговой отладке она только вредит.

Или как вариант - ходить не по C/C++ исходникам, а в по командам в окне disasm.

 

И вообще, изучайте инструмент, а то вон 8 страниц наплодили по сути на пустом месте :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Оптимизацию отключите, хотя бы для debug сборки. При пошаговой отладке она только вредит.

Или как вариант - ходить не по C/C++ исходникам, а в по командам в окне disasm.

Оптимизация стоит Level 0, и сделал я это сразу после установки кейла. Никогда оптимизацию не использую.

Да хоть по Cи, хоть по disasm. Был бы disbasic :) думаю так же работал.

 

Эта реплика к чему?

И вообще, изучайте инструмент, а то вон 8 страниц наплодили по сути на пустом месте :)

Где про это сказано?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Оптимизация стоит Level 0, и сделал я это сразу после установки кейла. Никогда оптимизацию не использую.

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

Если это так, то это в корне неправильно, нужно разбираться, почему так в Вас работает.

Я с таким "багом" столкнулся в старой TNKernel, что, кстати, заставило ее поменять на другую ртос - как раз на freeRTOS

В ней такого "бага" нет. Это я сразу проверил, как только освоил. В ней все работает как надо. Но с настройками повозился, к слову, отключил нафик динамическую память (у freeRTOS есть свой типа диспетчер дин. памяти)

 

Если весь код состоит из макросов (define), то старый компилятор кейла (v5) не умеет ходить по макросам. Новый v6 умеет.

Возможно, тут есть проблемы.

 

К проекту подключены исходники freeRTOS или заранее собранная библиотека (lib)?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Нет.

Поставил 3 брекпоинта. Task1, Task2 и в xPortSysTickHandler.

Сразу попадаем в Task1.

 

P.S.

Возможно я ошибаюсь, но что то мне подсказывает, что по функции Step и Step Over отладчик не может попасть в прерывание, а собственно это и должно произойти после выход из обработчика прерывания TIM10, программа должна попасть в PendSV Handler.

Изменено пользователем maxntf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет.

Поставил 3 брекпоинта. Task1, Task2 и в xPortSysTickHandler.

Сразу попадаем в Task2.

 

P.S.

Возможно я ошибаюсь, но что то мне подсказывает, что по функции Step и Step Over отладчик не может попасть в прерывание, а собственно это и должно произойти после выход из обработчика прерывания TIM10.

Ну значит задача просто закончила свою работу и сама вызвала диспетчер. Никакой мистики.

Так все операционки устроены

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет.

Поставил 3 брекпоинта. Task1, Task2 и в xPortSysTickHandler.

Сразу попадаем в Task2.

Пройдите под отладчиком по окну дизасма, анализирую содержимое стека. В частности при выходе из прерывания.

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

 

И приведите код этого "проекта" (в теге CODEBOX)

 

Ну значит задача просто закончила свою работу и сама вызвала диспетчер. Никакой мистики. Так все операционки устроены

© "Слышу звон, да не знаю, где он" :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...