Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Обучение FreeRTOS
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
EmDMAl
Здравствуйте. Выбрал FreeRTOS для программирования МК AVR(в основном Atmega8,16,32..). В качестве рабочей среды использую AVR Studio 4.19 + AVR-TOOLCHAIN-3.3.0.710, а для обучения взял "FreeRTOS — операционная система для микроконтроллеров" Андрея Курница. И у меня естнственно возникают вопросы.
1. В первом примере (мигание 2мя светодиодами) используется задержка в задачах следующего типа:
Код
for( ul = 0; ul < 4000L; ul++ ) {}
. Но с этой формой задержки у меня работает только одна задача, та которая первая вызывается в главном теле (
Код
short main( void ) {....}
). Если использую одну из ф-ий задержек/сна vTaskDelay("Тик"), то работают обе ф-ии на ура. Так вот вообще такая запись как у Курница допускается или автор ее привел просто для понятия, но она никогда не будет работать? Ниже привожу код main.c и FreeRTOSConfig.h.
2. При компиляции этого кода у меня получился hex размером 11кб, на мой взгляд много. Делал все строго по инструкции автора, удалил все ненужное. Автор пишет, что размер ядра составляет 4-9кб, но это пик при использовании всех ф-ии. Так вот, почему же у меня при использовании 2х простых задач получилось уже 11кб? Можно ли как-нибудь программно отключить ненужные файлы.
3. Рассматривать FreeRTOS стал из-за ее популяризации(довольно много находил статей по ней). Может более опытные подскажут какая ОС более оптимальна в соотношении размера hex файла, возможностей и доступности документации?
Пишу сюда, потому, что в инете это единственное место на мой взгляд где можно получить ответы по FreeRTOS. Помгоите разобраться. С уважением Дмитрий.
main.c
Код
#include "FreeRTOS.h"
#include "task.h"

void vTask1( void *pvParameters )
{
  volatile unsigned long ul;
  for(;; )
  {
    PORTC ^= (1 << PC0);
    for( ul = 0; ul < 4000L; ul++ )
   {
   }
  }
  vTaskDelete( NULL );
}
void vTask2( void *pvParameters )
{
  volatile unsigned long ul;
  for(;; )
  {
    PORTC ^= (1 << PC1);
    for( ul = 0; ul < 8000L; ul++ )
   {
   }
  }
  vTaskDelete( NULL );
}
/*-----------------------------------------------------------*/
int main( void )
{
  DDRC |= (1 << DDC0) | (1 << DDC1);
  xTaskCreate( vTask1,  (signed char *) "Task1",  configMINIMAL_STACK_SIZE,   NULL,  1,   NULL );
  xTaskCreate( vTask2,  (signed char *) "Task2",  configMINIMAL_STACK_SIZE,  NULL, 1,   NULL );
  vTaskStartScheduler();
  return 0;
}

FreeRTOSConfig.h
Код
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#include <avr/io.h>

#define configUSE_PREEMPTION        1
#define configUSE_IDLE_HOOK        0//Отключаю vApplicationIdleHook()
#define configUSE_TICK_HOOK        0
#define configCPU_CLOCK_HZ        ( ( unsigned long ) 8000000 )
#define configTICK_RATE_HZ        ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES        ( ( unsigned portBASE_TYPE ) 4 )
#define configMINIMAL_STACK_SIZE    ( ( unsigned short ) 85 )
#define configTOTAL_HEAP_SIZE        ( (size_t ) ( 1500 ) )
#define configMAX_TASK_NAME_LEN    ( 8 )
#define configUSE_TRACE_FACILITY    0
#define configUSE_16_BIT_TICKS    1
#define configIDLE_SHOULD_YIELD    1
#define configQUEUE_REGISTRY_SIZE     0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES         1
#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        0
#define INCLUDE_uxTaskPriorityGet        0
#define INCLUDE_vTaskDelete            1
#define INCLUDE_vTaskCleanUpResources    0
#define INCLUDE_vTaskSuspend            0
#define INCLUDE_vTaskDelayUntil        1
#define INCLUDE_vTaskDelay            1


#endif /* FREERTOS_CONFIG_H */
iosifk
Цитата(EmDMAl @ May 13 2012, 21:24) *
..., а для обучения взял "FreeRTOS — операционная система для микроконтроллеров" Андрея Курница. И у меня естнственно возникают вопросы.
....
Пишу сюда, потому, что в инете это единственное место на мой взгляд где можно получить ответы по FreeRTOS. Помгоите разобраться.


А в статье для того и указан адрес автора, чтобы к нему любой читатель смог обратиться.
К Курницу для начала обратитесь, так проще будет...
Удачи!
Cosmojam
Цитата(EmDMAl @ May 13 2012, 20:24) *
2. При компиляции этого кода у меня получился hex размером 11кб, на мой взгляд много. Делал все строго по инструкции автора, удалил все ненужное. Автор пишет, что размер ядра составляет 4-9кб, но это пик при использовании всех ф-ии. Так вот, почему же у меня при использовании 2х простых задач получилось уже 11кб? Можно ли как-нибудь программно отключить ненужные файлы.

hex - это текстовый файл где каждый байт данных занимает 2 символа + адреса, тип записи и сумма. Он по определению больше чем прошивка займёт флеши. Смотреть надо на размер бинарного файла или вывод линкера (гуру по вашему тулчейну подскажут как это сделать)
Volldemar
Или применять утилиту hex2bin.exe для преобразования хекса в бин.
Terminator
Цитата(Volldemar @ May 14 2012, 11:49) *
Или применять утилиту hex2bin.exe для преобразования хекса в бин.

Если ошибиться с линкером, то можно получить результирующий bin размером многие Мб sm.gif
juvf
1. две задачи с равным приоритетом при вытесняющей многозадачности - задачи должны выполяться по 1 тику по очереди.
2. в данном примере не используются апипаузы, поэтому удалить их из конфигаe]
vTaskDelete( NULL ); - азачам она нужна? удалить ей из кода и из конфигурации. Созадачи не используются - к терапевту
Код
#define configUSE_PREEMPTION        1
#define configUSE_IDLE_HOOK        0//Отключаю vApplicationIdleHook()
#define configUSE_TICK_HOOK        0
#define configCPU_CLOCK_HZ        ( ( unsigned long ) 8000000 )
#define configTICK_RATE_HZ        ( ( portTickType ) 1000 )
#define configMAX_PRIORITIES        ( ( unsigned portBASE_TYPE ) 4 )
#define configMINIMAL_STACK_SIZE    ( ( unsigned short ) 85 )
#define configTOTAL_HEAP_SIZE        ( (size_t ) ( 1500 ) )
#define configMAX_TASK_NAME_LEN    ( 8 )
#define configUSE_TRACE_FACILITY    0
#define configUSE_16_BIT_TICKS    1
#define configIDLE_SHOULD_YIELD    0 //*******************
#define configQUEUE_REGISTRY_SIZE     0
/* 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        0
#define INCLUDE_uxTaskPriorityGet        0
#define INCLUDE_vTaskDelete            0 //*******************
#define INCLUDE_vTaskCleanUpResources    0
#define INCLUDE_vTaskSuspend            0
#define INCLUDE_vTaskDelayUntil        0 //*******************
#define INCLUDE_vTaskDelay            0//*******************

3. по ресурсам мне больше нравиться uOS, но возможно придётся повозиться с её освоением.
EmDMAl
1.
Оказывется в Proteus 7.7. sp3 этот код работает некорректно, на железе все работает на ура. Значит очередной баг в Proteus. Просто тестирую я программы в нем.
Цитата(iosifk @ May 13 2012, 21:48) *
А в статье для того и указан адрес автора, чтобы к нему любой читатель смог обратиться.
К Курницу для начала обратитесь, так проще будет...
Удачи!

Написал 2 письма автору, но ответа нету, да теперь и не нужно, оказывается код работает правильно.
2.
Цитата(Cosmojam @ May 13 2012, 23:08) *
hex - это текстовый файл где каждый байт данных занимает 2 символа + адреса, тип записи и сумма. Он по определению больше чем прошивка займёт флеши. Смотреть надо на размер бинарного файла или вывод линкера (гуру по вашему тулчейну подскажут как это сделать)

Как я понял при компиляции в AVR Studio выдает
Program: X bytes (Y% Full). Х это и есть размер чистого бинарного файла, который преобразуется в hex. Только вот вопрос: в конроллере hex займет flash память или бинарный?
В makefile лесть не стал для запроса bin файла.
3.
Цитата(juvf @ May 15 2012, 06:48) *
... по ресурсам мне больше нравиться uOS, но возможно придётся повозиться с её освоением.

uOS - довольно толковая документация, все разжевано. Но работаю я на компе ,6Гц, а там мин 2Гц, неизвестно будет нормально работать. И еще не подскажите как ее прикрутить к AVR Studio? В инете данный вопрос я не нашел.

juvf
Цитата(EmDMAl @ May 15 2012, 11:03) *
uOS - довольно толковая документация, все разжевано. Но работаю я на компе ,6Гц, а там мин 2Гц, неизвестно будет нормально работать. И еще не подскажите как ее прикрутить к AVR Studio? В инете данный вопрос я не нашел.

ну может на сами апи функции всё толково, а вот на ос не очень. На сколько я понял uOS это встраиваемая ос в код, какая же как uC/OS или FreeRTOS. Т.е. есть папка с исходными файлами ОС и в своем коде нужно подключить нужные инклуде и задать нужные дефайны. А потом компилировать в любой иде, хоть в эклипсе, хоть в ире, хоть в студии... хоть вообще в шеле. И сборка может происходить в любой ос (линукс, виндоус, ...). Из исходников ос и из исходников моего проекта собирается elf (или hex, или bin) для нужной, для конкретной АТМеги128 (или т.п.).
Мне кажется, получив исходники юОС для конкретной платформы можно их прикрутить к любой ИДЕ. Единственное, в студии не будет контроля за ОС, как например есть в эклипсе контроль за ФрииРТОС.

ps обратись за помощью к автору юОС. На сайте ос есть форум по оси, автор вроде отвечает на вопросы.

EmDMAl
Цитата(EmDMAl @ May 15 2012, 09:03) *
Написал 2 письма автору, но ответа нету, да теперь и не нужно, оказывается код работает правильно.

Пришел ответ от автора, может кому-нибудь пригодится на заметку, на будующее:
В этой программе происходит доступ к разделяемому ресурсу PORTC без использования механизма взаимного исключения. Скорее всего ваша программа не работает именно из-за этого. Попробуйте один из следующих
вариантов:
1. Увеличить задержку в циклах на несколько порядков:
Код
for( ul = 0; ul < 80000L; ul++ )
for( uq = 0; uq < 40000L; uq++ )

2. Использовать критическую секцию для организации взаимного исключения:
Код
taskENTER_CRITICAL();
PORTC ^= (1 << PC0);
taskEXIT_CRITICAL();
...
taskENTER_CRITICAL();
PORTC ^= (1 << PC1);
taskEXIT_CRITICAL();
Volldemar
У меня вот такой main работал без проблем:
Код
#include <avr/io.h>
#include <avr/iom128.h>

#ifdef GCC_MEGA_AVR
    /* EEPROM routines used only with the WinAVR compiler. */
    #include <avr/eeprom.h>
#endif

/* Scheduler include files. */
#include "FreeRTOS.h"
#include "task.h"

/* Priority definitions for most of the tasks in the demo application.  Some
tasks just use the idle priority. */

#define TASK1_PRIORITY            ( tskIDLE_PRIORITY + 1 )
#define TASK2_PRIORITY            ( tskIDLE_PRIORITY + 1 )

/* ---------------------------------------------------------------------- */
void vTask1( void *pvParameters );
void vTask2( void *pvParameters );
/* ---------------------------------------------------------------------- */

/* ---------------------------------------------------------------------- */
/* Функция задачи 1 */
void vTask1(void *pvParameters)
{
( void ) pvParameters;
volatile unsigned long ul;
for(;;)
    {

    PORTB^=(1<<PB0);
    for(ul=0; ul<4000L; ul++)
        {
        }
    }
vTaskDelete(NULL);
}
/* ---------------------------------------------------------------------- */
/* Функция задачи 2 */

void vTask2(void *pvParameters)
{
( void ) pvParameters;
volatile unsigned long ul;
for(;;)
{
    PORTB^=(1<<PB1);
    for(ul=0; ul<8000L; ul++)
    {
    }
}
vTaskDelete(NULL);
}
/* ---------------------------------------------------------------------- */

int main( void )
{
    DDRB|=(1<<DDB0)|(1<<DDB1);


    /* Создать задачу 1. */
    xTaskCreate( vTask1, ( signed char * ) "Task1", configMINIMAL_STACK_SIZE, NULL, TASK1_PRIORITY, NULL );

    /* Создать задачу 2. */
    xTaskCreate( vTask2, ( signed char * ) "Task2", configMINIMAL_STACK_SIZE, NULL, TASK2_PRIORITY, NULL );
    
    /* Запустить планировщик. Задачи начнут выполняться. */
    vTaskStartScheduler();

    return 0;
}
/*-----------------------------------------------------------*/
EmDMAl
1. Кто-нибудь, устанавливал компилятор Open Watcom используемый у Курницы? Все установлено по инструкции: Open Watcom в корень диска С, папка FreeRtos тоже в корень С. При компиляции целая куча ошибок разного рода. В принципе можно проекты под AVR Studio переделывать.
2. При попытки переделки под AVR Studio, возникает ошибки:
Код
D:\library\Pinboard\temp_Ci\FreeRTOSV7.1.1\Project\AVR_ATMega32_KURN_2\./FreeRTOSConfig.h:88:9: error: macro names must be identifiers
D:\library\Pinboard\temp_Ci\FreeRTOSV7.1.1\Project\AVR_ATMega32_KURN_2\..\..\Source\include/FreeRTOS.h:137:3: error: #error Missing definition: INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the
../AVR_ATMega32_KURN_2.c:22:10: error: 'string' undeclared (first use in this function)
../AVR_ATMega32_KURN_2.c:24:25: error: 'gt' undeclared (first use in this function)

Не подскажите кто разбирал его примеры, как вы справлялись с переделками или подскажите хороший источник для обучения FreeRtos.
Volldemar
Я компиляю в эклипсе+winavr
EmDMAl
Цитата(EmDMAl @ May 17 2012, 11:40) *
1. Кто-нибудь, устанавливал компилятор Open Watcom используемый у Курницы? Все установлено по инструкции: Open Watcom в корень диска С, папка FreeRtos тоже в корень С. При компиляции целая куча ошибок разного рода. В принципе можно проекты под AVR Studio переделывать.
2. При попытки переделки под AVR Studio, возникает ошибки:
Код
D:\library\Pinboard\temp_Ci\FreeRTOSV7.1.1\Project\AVR_ATMega32_KURN_2\./FreeRTOSConfig.h:88:9: error: macro names must be identifiers
#error Missing definition:  INCLUDE_vTaskDelay should be defined in FreeRTOSConfig.h as either 1 or 0.  See the Configuration section of the FreeRTOS API documentation for details.

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

EmDMAl
При повторной установки новой версии ошибки с поиском библиотек исчезли.
Теперь при компиляции выдает ошибку:
Код
Error! E2028: vTaskStartTrace_ is an undefined reference
Error! E2028: ulTaskEndTrace_ is an undefined reference
.
vTaskStartTrace - ф-ия трассировки данных и записи их в лог, при ее отключении exe компилируется, но ничего не отображается(dos-ий экран черный). Эта ф-ия используется в main.c и инициализируется в task.h, оба файла присоеденены к проекту. В FreeRTOSConfig.h configUSE_TRACE_FACILITY=1, правда #define configQUEUE_REGISTRY_SIZE=0, но менял значение для тестирования.
TaskEndTrace - останавливает трассировку.
Error! E2028: означает неопределенное значение, такое ощущение что компилятор не видит объявление этой ф-ии.
Куда двигаться я не знаю, в инете подобной проблемы ни у кого нету.
juvf
непонятно почему компилятор ищет vTaskStartTrace_, мой компилятор ищет vTaskStartTrace. Может символ '_' приписывается в выхлопе компилятора.
Нужно искать по всем файлам проекта, включая исходники ртос объявление и определение vTaskStartTrace. И нужно смотреть какими ифами обрамлено определение функции. У меня определение нашлось в task.c, определение обрамлено "#if ( configUSE_TRACE_FACILITY == 1 )". Может нету в вашем проекте task.c
ATMExpert
А кто может подсказать, чем FreeRTOS генерирует эти самые "тики"? Не таймером же - отнимать у юзера периферию не есть гуд...
Буду благодарен за объяснение.
_Артём_
Цитата(ATMExpert @ May 27 2012, 00:13) *
А кто может подсказать, чем FreeRTOS генерирует эти самые "тики"?

Таймером.

Цитата(ATMExpert @ May 27 2012, 00:13) *
Не таймером же - отнимать у юзера периферию не есть гуд...

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

ATMExpert
Цитата(_Артём_ @ May 27 2012, 01:51) *
Добавление FreeRtos в проект == добавление ещё одного таймера прямо в МК.

А это как, не совсем понимаю. Еще один таймер откуда берется? Если к примеру у меня в проекте используются оба таймера в соих нуждах, то какой таймер использует RTOS?
Volldemar
Цитата(ATMExpert @ May 27 2012, 00:13) *
А кто может подсказать, чем FreeRTOS генерирует эти самые "тики"? Не таймером же - отнимать у юзера периферию не есть гуд...
Буду благодарен за объяснение.

FreeRTOS хоть и забирает под свои нужды один аппаратный таймер, но взамен предоставляет программные таймеры, бери-нехочу...
ATMExpert
Цитата(Volldemar @ May 27 2012, 11:06) *
FreeRTOS хоть и забирает под свои нужды один аппаратный таймер, но взамен предоставляет программные таймеры, бери-нехочу...


А если мне нужно использовать 2 канала от разных аппаратных таймеров для генерации 2 независимых частот, ну что-то типа режима сброс таймера при совпадении и переключение (toggle) выхода, тогда как?
Например, 2 шаговых двигателя, по каждому каналу своя скорость, причем и разгон и торможение нужно использовать.
_Артём_
Цитата(ATMExpert @ May 27 2012, 10:25) *
А если мне нужно использовать 2 канала от разных аппаратных таймеров для генерации 2 независимых частот, ну что-то типа режима сброс таймера при совпадении и переключение (toggle) выхода, тогда как?
Например, 2 шаговых двигателя, по каждому каналу своя скорость, причем и разгон и торможение нужно использовать.

Тогда, если у таймеров не один шим, можно на неиспользуемоё прерывание совпадения повесить Systick RTOS, если частота шима не меняется конечно.
ATMExpert
Цитата(_Артём_ @ May 27 2012, 11:32) *
Тогда, если у таймеров не один шим, можно на неиспользуемоё прерывание совпадения повесить Systick RTOS, если частота шима не меняется конечно.

У таймеров обычно больше двух каналов ШИМ, но ШИМ здесь не используется, применяется режим изменения частоты генерируемой таймером, т.е. применительно для ШД - изменяется скорость step. Я обычно (на AVR) применял 2 отдельных таймера в режиме сброс по совпадению
juvf
Цитата(Volldemar @ May 27 2012, 13:06) *
FreeRTOS хоть и забирает под свои нужды один аппаратный таймер, но взамен предоставляет программные таймеры, бери-нехочу...

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

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

если частоты невысокие, то можно программным таймером решить проблему, а если высокие, то тут извращатся придётся.... либо как-то аппаратно настраивать совпадения и обработку этих совпадений.... либо запускать аппаратный таймер на какую-то высокую частоту, а в обработчике прерыванию считать тики в две переменные - вот вам две частоты и руками в прерывании дёргать пины.
wellcom
Привет знатокам! Начал разбираться с 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;
}
MrYuran
xx
Написал, не подумав, поскипал.
laughing.gif
wellcom
Цитата(MrYuran @ Dec 11 2012, 12:47) *
xx

и как это перевести/применить?


вот весь проект http://kazus.ru/forums/showpost.php?p=5790...mp;postcount=50
wellcom
Разобрался, дело было в ключевом слове "static", переменная семафора была static, что не позволяло ее модифицировать из другой ф-ции (задачи)
wellcom
Подскажите, как записать в такую очередь данные????
//определяю ст-ру, которая будет елементом очереди
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)); //создаем очередь
Cosmojam
Как любые другие данные по указателю
Код
xQueueSend(xQueueCMD, &CmdData, 100u / portTICK_RATE_MS); /* ждать 100мс в блокированном состоянии если свободного места нет */
wellcom
...перед этим нужно заполнить структуру данными что бы ее передать в очередь. Я думал, возможно есть вариант что бы записать значени в переменную структуры прямо в очереди. В любом случае спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.