Jump to content

    

Обучение FreeRTOS

А кто может подсказать, чем FreeRTOS генерирует эти самые "тики"? Не таймером же - отнимать у юзера периферию не есть гуд...

Буду благодарен за объяснение.

Share this post


Link to post
Share on other sites
А кто может подсказать, чем FreeRTOS генерирует эти самые "тики"?

Таймером.

 

Не таймером же - отнимать у юзера периферию не есть гуд...

Добавление FreeRtos в проект == добавление ещё одного таймера прямо в МК.

 

 

Share this post


Link to post
Share on other sites
Добавление FreeRtos в проект == добавление ещё одного таймера прямо в МК.

А это как, не совсем понимаю. Еще один таймер откуда берется? Если к примеру у меня в проекте используются оба таймера в соих нуждах, то какой таймер использует RTOS?

Share this post


Link to post
Share on other sites
А кто может подсказать, чем FreeRTOS генерирует эти самые "тики"? Не таймером же - отнимать у юзера периферию не есть гуд...

Буду благодарен за объяснение.

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

Share this post


Link to post
Share on other sites
FreeRTOS хоть и забирает под свои нужды один аппаратный таймер, но взамен предоставляет программные таймеры, бери-нехочу...

 

А если мне нужно использовать 2 канала от разных аппаратных таймеров для генерации 2 независимых частот, ну что-то типа режима сброс таймера при совпадении и переключение (toggle) выхода, тогда как?

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

Edited by ATMExpert

Share this post


Link to post
Share on other sites
А если мне нужно использовать 2 канала от разных аппаратных таймеров для генерации 2 независимых частот, ну что-то типа режима сброс таймера при совпадении и переключение (toggle) выхода, тогда как?

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

Тогда, если у таймеров не один шим, можно на неиспользуемоё прерывание совпадения повесить Systick RTOS, если частота шима не меняется конечно.

Share this post


Link to post
Share on other sites
Тогда, если у таймеров не один шим, можно на неиспользуемоё прерывание совпадения повесить Systick RTOS, если частота шима не меняется конечно.

У таймеров обычно больше двух каналов ШИМ, но ШИМ здесь не используется, применяется режим изменения частоты генерируемой таймером, т.е. применительно для ШД - изменяется скорость step. Я обычно (на AVR) применял 2 отдельных таймера в режиме сброс по совпадению

Share this post


Link to post
Share on other sites
FreeRTOS хоть и забирает под свои нужды один аппаратный таймер, но взамен предоставляет программные таймеры, бери-нехочу...

FreeRTOS забирает под свои нужды 1 аппаратный таймер. его нужно освободить. Взамент ртос конечно предоставляет таймеры.... но не всегда аппаратный можно заменить программным. если тик == 1 мс, а нужно получить частоту 1 МГц, то ..... тут нужно тик делать 1 мкс. Это не совсем гуд для медленных процесоров (да и для быстрых тоже).

 

А если мне нужно использовать 2 канала от разных аппаратных таймеров для генерации 2 независимых частот,

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

Share this post


Link to post
Share on other sites

Привет знатокам! Начал разбираться с FreeRTOS V7.3.0 на Atmega128+AVRStudio 6. Несколько примеров заработали успешно (мигать светиком + кнопка с выводом события нажатия на LCD 1x16). После решил углубится в использование УАРТА, добавил 2 задачи + 1 прерывание по приему символа. При компиляции серьезных ошибок небыло, кроме 2-х одинаковых "вонингов" вида : Warning 1 cast from pointer to integer of different size [-Wpointer-to-int-cast] G:\......\tasks.c 523 44 AVRGCC1, что указывает на следующую строку кода

 

pxTopOfStack = ( portSTACK_TYPE * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) );

 

После запуска запуска в дебаге, программа виснет при получении семафора : xSemaphoreTake(xButtonSemaphore, (portTickType)0);

детальное изучения висячки привело меня в строку кода portRESTORE_CONTEXT();, после выполнения которой, на вкладке Processor - Registers, все регистры от 0 по 31 имеют значения 00. Т. е я так понимаю что контекст предыдущей задачи не востановился, но почему не могу понять. Этот участок кода работал нормально, пока не добавил ф-ции по работе с уартом. Сейчас полностью убрал эти ф-ции но ошибка осталась и побороть ее ника не могу, и вообще не могу понять в чем дело. Может проблема в "вонингах"? Прошу помощи.

 

Вот часть кода, которая глючит

 

void vButtonCheckTask( void *pvParameters )

{

portTickType xLastWakeTime;

const portTickType xFrequency = 20; //время, через которое проверяется кнопка, мс

xLastWakeTime=xTaskGetTickCount(); //Возвращает:Количество тиков начиная с вызова vTaskStartScheduler

 

xSemaphoreTake(xButtonSemaphore, (portTickType)0); //Макрос для получения семафора. <<<< --------глючит здесь во время/при выполнении

 

vButtonInit(); //initialization

for (;;)

{

if (xButtonGetStatus()==pdTRUE) //смотрим кнопку, если нажата

{

xSemaphoreGive(xButtonSemaphore); // Освобождаем семафор.

}

vTaskDelayUntil(&xLastWakeTime,xFrequency); //проверяем кнопку каждые 20 мс

}

}

 

portSHORT main(void)

{

 

vSemaphoreCreateBinary(xButtonSemaphore); // реализует семафор

if(xButtonSemaphore!=NULL) // если семафор создан удачно

{

xTaskCreate( vButtonCheckTask, ( signed char * ) "Button", configMINIMAL_STACK_SIZE, NULL, mainButton_TASK_PRIORITY, NULL ); //реакция на кнопку

}

 

xTaskCreate( vLEDFlashTask1, ( signed char * ) "LED", configMINIMAL_STACK_SIZE, NULL, mainLED_TASK_PRIORITY, NULL ); //мигание всетиком

 

while(1)

{

 

}

return 0;

}

Share this post


Link to post
Share on other sites

xx

Написал, не подумав, поскипал.

:laughing:

Share this post


Link to post
Share on other sites

Разобрался, дело было в ключевом слове "static", переменная семафора была static, что не позволяло ее модифицировать из другой ф-ции (задачи)

Share this post


Link to post
Share on other sites

Подскажите, как записать в такую очередь данные????

//определяю ст-ру, которая будет елементом очереди

typedef struct

{

unsigned portBASE_TYPE uint8_Command;

int32_t int32_Data_1;

int32_t int32_Data_2;

unsigned portBASE_TYPE uint8_Data_3;

}CmdData;

 

xQueueCMD = xQueueCreate ( 4, sizeof(CmdData)); //создаем очередь

Share this post


Link to post
Share on other sites

Как любые другие данные по указателю

xQueueSend(xQueueCMD, &CmdData, 100u / portTICK_RATE_MS); /* ждать 100мс в блокированном состоянии если свободного места нет */

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this