Jump to content

    

Обучение FreeRTOS

Здравствуйте. Выбрал 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 */

Share this post


Link to post
Share on other sites
..., а для обучения взял "FreeRTOS — операционная система для микроконтроллеров" Андрея Курница. И у меня естнственно возникают вопросы.

....

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

 

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

К Курницу для начала обратитесь, так проще будет...

Удачи!

 

Share this post


Link to post
Share on other sites
2. При компиляции этого кода у меня получился hex размером 11кб, на мой взгляд много. Делал все строго по инструкции автора, удалил все ненужное. Автор пишет, что размер ядра составляет 4-9кб, но это пик при использовании всех ф-ии. Так вот, почему же у меня при использовании 2х простых задач получилось уже 11кб? Можно ли как-нибудь программно отключить ненужные файлы.

hex - это текстовый файл где каждый байт данных занимает 2 символа + адреса, тип записи и сумма. Он по определению больше чем прошивка займёт флеши. Смотреть надо на размер бинарного файла или вывод линкера (гуру по вашему тулчейну подскажут как это сделать)

Share this post


Link to post
Share on other sites

Или применять утилиту hex2bin.exe для преобразования хекса в бин.

Share this post


Link to post
Share on other sites
Или применять утилиту hex2bin.exe для преобразования хекса в бин.

Если ошибиться с линкером, то можно получить результирующий bin размером многие Мб :)

Edited by Terminator

Share this post


Link to post
Share on other sites

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, но возможно придётся повозиться с её освоением.

Edited by juvf

Share this post


Link to post
Share on other sites

1.

Оказывется в Proteus 7.7. sp3 этот код работает некорректно, на железе все работает на ура. Значит очередной баг в Proteus. Просто тестирую я программы в нем.

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

К Курницу для начала обратитесь, так проще будет...

Удачи!

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

2.

hex - это текстовый файл где каждый байт данных занимает 2 символа + адреса, тип записи и сумма. Он по определению больше чем прошивка займёт флеши. Смотреть надо на размер бинарного файла или вывод линкера (гуру по вашему тулчейну подскажут как это сделать)

Как я понял при компиляции в AVR Studio выдает

Program: X bytes (Y% Full). Х это и есть размер чистого бинарного файла, который преобразуется в hex. Только вот вопрос: в конроллере hex займет flash память или бинарный?

В makefile лесть не стал для запроса bin файла.

3.

... по ресурсам мне больше нравиться uOS, но возможно придётся повозиться с её освоением.

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

 

 

Share this post


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

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

Мне кажется, получив исходники юОС для конкретной платформы можно их прикрутить к любой ИДЕ. Единственное, в студии не будет контроля за ОС, как например есть в эклипсе контроль за ФрииРТОС.

 

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

 

 

Share this post


Link to post
Share on other sites
Написал 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();

Share this post


Link to post
Share on other sites

У меня вот такой 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;
}
/*-----------------------------------------------------------*/

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

Я компиляю в эклипсе+winavr

Share this post


Link to post
Share on other sites
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.

 

Share this post


Link to post
Share on other sites

При повторной установки новой версии ошибки с поиском библиотек исчезли.

Теперь при компиляции выдает ошибку:

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: означает неопределенное значение, такое ощущение что компилятор не видит объявление этой ф-ии.

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

Share this post


Link to post
Share on other sites

непонятно почему компилятор ищет vTaskStartTrace_, мой компилятор ищет vTaskStartTrace. Может символ '_' приписывается в выхлопе компилятора.

Нужно искать по всем файлам проекта, включая исходники ртос объявление и определение vTaskStartTrace. И нужно смотреть какими ифами обрамлено определение функции. У меня определение нашлось в task.c, определение обрамлено "#if ( configUSE_TRACE_FACILITY == 1 )". Может нету в вашем проекте task.c

post-49045-1337653177_thumb.png

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