Freertos

victor_pv
Пт, 8 мая 2015 г., 2:11
Я только что проверил библиотеку Freertos из «непроверенной» папки с простым мигающим наброском и, кажется, хорошо работает из коробки.

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

Luc_exe
Вторник 12 мая 2015 г., 21:23
Можете ли вы указать больше подробностей? MCU/Poard в Wich вы тестировали Freertos и инструменты, используемые для компиляции?

Выглядит интересно.

Я все еще пытаюсь найти хорошую IDE для тестирования подобных вещей (загрузчики, RTO и т. Д.) Используя Windows, но ни один из IDE, которые я мог бы использовать, не имеет возможности импортировать источники (Arduino IDE, Coocox Coide, Emide). Попробовал Eclipse и производные, и я могу получить код в импорт, но с этим у меня есть проблемы с инструментом. Надеюсь, я смогу найти решение, не имея в виду командную строку, все еще придется попробовать с Linux, работающим на VirtualBox.

victor_pv
Ср 13 мая 2015 г., 4:29
Luc я использовал Maple Mini в Arduino Ide.
Все файлы, которые я использовал в этом репозитории (https: // github.com/vicopropv/stm32f1_modified/)
Я держу это репо для экспериментов, и если что -то работает, я сообщаю об этом здесь. Мне нужно обновить мой основной до Мастера Роджерса, а затем я могу отправить ему запросы на то, чтобы облегчить обновления, мне не хватает, чтобы он попросил его вытащить файлы из одного репо, чтобы обновить другое, когда я мог бы просто сделать запрос на вытяжение.

Я не думаю, что я должен был что -то изменить в файлах Freertos, просто снял их с непрерывных библиотек папки. Я создал один пример из кода, который я нашел на форумах Leaflabs. Это просто мигающий. Я планирую провести больший тест с дисплеем ILI 9341 с использованием DMA Transfers.
Если это сработает, это будет здорово, потому что DMA может перенести сотни байтов, в то время как RTO могут назначить время какой -либо другой функции, пока не завершится DMA.
Если я возьму это работать, я опубликую пример этого.

victor_pv
Солнце 17 мая 2015 г., 2:46
Просто обновление на Freertos.

Я решил протестировать что -то более сложное, чем мигание, поэтому я взял пример куба из библиотеки ILI9163, немного настроив его, чтобы сделать его функцией, которую я могу позвонить несколько раз, чтобы иметь несколько кубиков на экране, и добавил 2 вращающихся кубика в качестве дополнительных потоков в пример куба.
Кажется, все работает действительно хорошо.
Я загружаю пример в свой репо, для всех, кто мог бы использовать в качестве примера.
В настоящее время он выполняет 4 задачи параллельно:
-Мигает светодиод.
-Рисовать вращающийся куб в центре экрана.
-Рисовать еще один вращающийся куб в углу.
-Расчеты SQRT с самым низким приоритетом.

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

Он делает все это, используя серийный порт, чтобы распечатать время, необходимое для расчетов квадратного корня, и используя SPI с DMA для дисплея.
И библиотека ILI не оптимизирована для Freertos, в противном случае, если она выпустила процессор каждый раз, когда он ожидает завершения DMA, она может освободить гораздо больше циклов ЦП.


Я хочу проверить Freertos 8.2, мне очень нравится, как легко легко запланировать кучу разных задач с разными приоритетами.

Mrburnette
Солнце 17 мая 2015 г. 15:24
victor_pv написал: ...
Я хочу проверить Freertos 8.2, мне очень нравится, как легко легко запланировать кучу разных задач с разными приоритетами.

victor_pv
Солнце 17 мая 2015 г. 15:48
Позвольте мне сравнить пример сбора вращающихся кубиков с RTO и без них.
Я полагаю, что он будет использовать больше ОЗУ из -за того, как RTOS оставляет за собой место для головы напрямую, а не позволить Malloc () управлять им, но я не знаю точно.

Есть ли у вас какой -либо интересный пример, который мог бы выиграть от работы в RTO, который попробовал бы? Я использовал только кубики, чтобы подтвердить периферический доступ и DMA работать хорошо, но у меня нет ничего больше, чем это, чтобы проверить прямо сейчас.

РЕДАКТИРОВАТЬ: Просто быстро протестировано.
Можно настроить пространство кучи Freertos, так как в моих тестах было установлено 8 КБ.
Я могу проверить карту памяти, что 8 КБ зарезервировано для XHEAP, поэтому из общей памяти, используемой эскизом во время компиляции, мы должны сдать эти 8 КБ. Для теста я прокомментировал задачу светодиодного мигания и задачу SQRT из примера Freertos, поэтому у нее есть только 2 ротатиновых кубика, точно так же, как эскиз без Freertos.
Это цифры: FreeRTOS: Sketch uses 26,444 bytes (21%) of program storage space. Maximum is 122,880 bytes. Global variables use 11,672 bytes of dynamic memory. No RTOS: Sketch uses 22,980 bytes (18%) of program storage space. Maximum is 122,880 bytes. Global variables use 3,168 bytes of dynamic memory.

Mrburnette
Солнце 17 мая 2015 г. 16:34
victor_pv написал:Позвольте мне сравнить пример сбора вращающихся кубиков с RTO и без них.
Я полагаю, что он будет использовать больше ОЗУ из -за того, как RTOS оставляет за собой место для головы напрямую, а не позволить Malloc () управлять им, но я не знаю точно.

Есть ли у вас какой -либо интересный пример, который мог бы выиграть от работы в RTO, который попробовал бы? Я использовал только кубики, чтобы подтвердить периферический доступ и DMA работать хорошо, но у меня нет ничего больше, чем это, чтобы проверить прямо сейчас.
<...>
Убирая 8 КБ зарезервированной кучи, различия:
Freertos использует 312 байта оперативной памяти и 3464 байт вспышки.
Я думаю, что эти цифры довольно хороши для того, что он делает.

РЕДАКТИРОВАТЬ: только что протестировал Freertos 8.2.1. Я взял их порт Cortexm3, затем сделал 3 изменения, которые я нашел, были сделаны с кленовым портом 7.0.1, и с этими 3 изменениями оба моих примера компилируют и работают нормально. Я не проверял каждую функциональность, поэтому могут быть вещи, которые не работают.
С 8.2.1 Есть 5 вариантов для управления кучей. С самым основным он приводит к еще 80 байтам, используемым из вспышки, но на 40 меньше используемых байтов ОЗУ.

victor_pv
Солнце 17 мая 2015 г. 16:53
Я был серьезно впечатлен. Я никогда раньше не использовал RTO в микроконтроллере, я ожидал, что он будет съесть ресурсы, такие как сумасшедшие, но, похоже, не делает это, и я считаю, что использование DMA для периферийных устройств может быть гораздо больше с RTOS чем если бы нам приходилось тщательно пройти время, чтобы использовать эти циклы с чем -то другим.
На этом этапе ЖК -библиотека даже не оптимизирована для RTOS. Я уверен, что с некоторыми небольшими изменениями, поэтому он выпускает процессор в RTO, когда происходит достаточно длинный DMA, значительно повысит производительность. Вероятно, не для небольших переводов, которые занимают несколько циклов, но все за несколько сотен циклов должно занять больше времени, чем переключение задач в RTOS. Я могу попробовать позже.

Rogerclark
Пн 18 мая 2015 г., 21:53
Виктор,

Я перемещаю Freertos из непроверенных в нормальную часть папки библиотек

Когда у Рэя была возможность подтвердить, что он работает для него, и, возможно, когда у нас есть некоторые примеры, которые люди могут попробовать, мы можем опубликовать объявление, так как я уверен, что многие люди будут очень заинтересованы

Спасибо

Роджер

Mrburnette
Вторник 19 мая 2015 г., 14:50
http: // feilipu.ME/2011/22/22/Freertos-A ... vr-atmega/

Для старых 8-битных подразделений Arduino, пересмотренная библиотека библиотеки Freertos выше (обновленная 4/2015) тоже выглядит многообещающе. Как я обсуждал в другой ветке, очень дешевые мини-доски 328 п. 16 МГц до 2 долларов могут стать полезными в будущих проектах по управлению датчиками и предварительным условием некоторых данных перед отправкой в ​​STM32 (Master/Hub).

Луча

Mrburnette
Чт 21 мая 2015 г., 23:47
victor_pv написал:<...>
Есть ли у вас какой -либо интересный пример, который мог бы выиграть от работы в RTO, который попробовал бы?

victor_pv
Пт 22 мая 2015 г. 1:48
Использует ли RTC Systick? Если это так, использует ли он функцию обратного вызова Systick?

Freertos использует Systick с прерываниями 1 кГц и установите функцию обратного вызова Systick, чтобы вызвать функцию RTOS, которая выполняет планирование.

Я считаю, что RTC использует другой источник часов, но если он использует Systick, у нас может быть 2 решения:
-Измените обратный вызов от Systick на RTC, и RTC вызывает планировщик Freertos.
-Пусть RTO имеет обратный вызов от Systick, но затем RTOS вызывает RTC.

Помимо Systick, и 2 функций в ассемблере, которые сохраняют стек и восстанавливают стек каждый раз, когда задача переключается, RTOS не мешает ничего другим.
Я успешно использовал DMA и DMA ISR без каких -либо изменений, это не заботится. Поскольку у коры есть NVIC, я думаю, это требует забот о приоритетах и ​​служит любому прерыванию, которое триггеры, в то время как другое обслуживается, так что они не блокируют друг друга.

В моем самом сложном примере на данный момент у меня есть 2 функции, рисующие на экране, а другая функция выполняет расчеты SQRT на заднем плане, довольно интенсивная математика. Производительность SQRT снижается, примерно на 30% 40% сравнивается как работает само по себе, но имеет самые низкие приоритеты, поэтому в то же время рисование работают почти на полной скорости.

Если бы я использовал MCU с 64 КБ и зарезервировал 32 КБ для кадровую буфер для полного цвета 128x128.
Это то, что я хочу проверить, но мне нужно переписать драйвер ILI9163, чтобы сделать весь рисунок в кадрский буфер.
К сожалению, это не сработает в более высоком большем 9341, потому что 1 полный кадр займет 144 КБ :(
Я полагаю, что использование кадрового буфера может оказать огромное влияние на производительность, так как написание пикселя подразумевает просто написание 2 байта на ОЗУ, а не отправлять управляющие данные на дисплей, затем адрес пикселя, затем сами данные пикселя, сами и подождите, пока все эти транзакции SPI завершат...
Все же необходимость скорости в таком маленьком ЖК -дисплеи сомнительна...

Martinayotte
Пт 22 мая 2015 г. 1:51
Mrburnette написал:http: // feilipu.ME/2011/22/22/Freertos-A ... vr-atmega/

Для старых 8-битных подразделений Arduino, пересмотренная библиотека библиотеки Freertos выше (обновленная 4/2015) тоже выглядит многообещающе. Как я обсуждал в другой ветке, очень дешевые мини-доски 328 п. 16 МГц до 2 долларов могут стать полезными в будущих проектах по управлению датчиками и предварительным условием некоторых данных перед отправкой в ​​STM32 (Master/Hub).

Луча

Ахулл
Пт 22 мая 2015 г., 10:44
victor_pv написал:Использует ли RTC Systick? Если это так, использует ли он функцию обратного вызова Systick?

Freertos использует Systick с прерываниями 1 кГц и установите функцию обратного вызова Systick, чтобы вызвать функцию RTOS, которая выполняет планирование.

Я считаю, что RTC использует другой источник часов, но если он использует Systick, у нас может быть 2 решения:
-Измените обратный вызов от Systick на RTC, и RTC вызывает планировщик Freertos.
-Пусть RTO имеет обратный вызов от Systick, но затем RTOS вызывает RTC.

Помимо Systick, и 2 функций в ассемблере, которые сохраняют стек и восстанавливают стек каждый раз, когда задача переключается, RTOS не мешает ничего другим.
Я успешно использовал DMA и DMA ISR без каких -либо изменений, это не заботится. Поскольку у коры есть NVIC, я думаю, это требует забот о приоритетах и ​​служит любому прерыванию, которое триггеры, в то время как другое обслуживается, так что они не блокируют друг друга.

В моем самом сложном примере на данный момент у меня есть 2 функции, рисующие на экране, а другая функция выполняет расчеты SQRT на заднем плане, довольно интенсивная математика. Производительность SQRT снижается, примерно на 30% 40% сравнивается как работает само по себе, но имеет самые низкие приоритеты, поэтому в то же время рисование работают почти на полной скорости.

Если бы я использовал MCU с 64 КБ и зарезервировал 32 КБ для кадровую буфер для полного цвета 128x128.
Это то, что я хочу проверить, но мне нужно переписать драйвер ILI9163, чтобы сделать весь рисунок в кадрский буфер.
К сожалению, это не сработает в более высоком большем 9341, потому что 1 полный кадр займет 144 КБ :(
Я полагаю, что использование кадрового буфера может оказать огромное влияние на производительность, так как написание пикселя подразумевает просто написание 2 байта на ОЗУ, а не отправлять управляющие данные на дисплей, затем адрес пикселя, затем сами данные пикселя, сами и подождите, пока все эти транзакции SPI завершат...
Все же необходимость скорости в таком маленьком ЖК -дисплеи сомнительна...

victor_pv
Пт 22 мая 2015 г. 15:44
Я думаю, что проблема заключается в том, что использование такого буфера кадров потребует обработки процессора для перевода битов на слово на экране. Не то чтобы вы могли установить передачу DMA, которая выберет каждый бит и отправит соответствующее 16 -битное значение на периферийное устройство SPI.
Это убило бы основное преимущество, о котором я думал, который использовал кадрский буфер, поэтому весь экран написан сразу же контроллером DMA без использования циклов ЦП.

Я предполагаю, что может быть одна подпрограмма, которая переводится из бинарного кадрского буфера в 1 полную линию цветовых данных, а затем направить DMA отправить линию сканирования, а затем подпрограмма переводит следующую строку от двоичной на 16 -битные цветные данные, но это все еще будет стоят много циклов процессора.

Где вы думаете о каком -то другом способе уменьшить использование процессора?

michael_l
Чт, 04 августа 2016 г., 12:30
Виктор, попробовал ваш пример с ILI9341 (некоторые небольшие модификации), и он отлично работает.

Изображение


Является #define use_semaphore_dma1 нужный ?
#define USE_SEMAPHORE_DMA1 #include #include #include // Core graphics library, with extra fonts. #include // STM32 DMA Hardware-specific library // For the Adafruit shield, these are the default. #define TFT_CS PC13 #define TFT_DC PC15 #define TFT_RST PC14 Adafruit_ILI9341_STM tft = Adafruit_ILI9341_STM(TFT_CS, TFT_DC, TFT_RST); // Use hardware SPI xSemaphoreHandle xDisplayFree; #define BOARD_LED_PIN PA5 const float sin_d[] = { 0, 0.17, 0.34, 0.5, 0.64, 0.77, 0.87, 0.94, 0.98, 1, 0.98, 0.94, 0.87, 0.77, 0.64, 0.5, 0.34, 0.17, 0, -0.17, -0.34, -0.5, -0.64, -0.77, -0.87, -0.94, -0.98, -1, -0.98, -0.94, -0.87, -0.77, -0.64, -0.5, -0.34, -0.17 }; const float cos_d[] = { 1, 0.98, 0.94, 0.87, 0.77, 0.64, 0.5, 0.34, 0.17, 0, -0.17, -0.34, -0.5, -0.64, -0.77, -0.87, -0.94, -0.98, -1, -0.98, -0.94, -0.87, -0.77, -0.64, -0.5, -0.34, -0.17, 0, 0.17, 0.34, 0.5, 0.64, 0.77, 0.87, 0.94, 0.98 }; const float d = 5; float cube1_px[] = { -d, d, d, -d, -d, d, d, -d }; float cube1_py[] = { -d, -d, d, d, -d, -d, d, d }; float cube1_pz[] = { -d, -d, -d, -d, d, d, d, d }; float cube1_p2x[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; float cube1_p2y[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int cube1_r[] = { 0, 0, 0 }; const float d2 = 10; float cube2_px[] = { -d2, d2, d2, -d2, -d2, d2, d2, -d2 }; float cube2_py[] = { -d2, -d2, d2, d2, -d2, -d2, d2, d2 }; float cube2_pz[] = { -d2, -d2, -d2, -d2, d2, d2, d2, d2 }; float cube2_p2x[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; float cube2_p2y[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int cube2_r[] = { 0, 0, 0 }; uint16 cube1_x, cube1_y, cube2_x, cube2_y, cube1_color, cube2_color; static void vLEDFlashTask(void *pvParameters) { for (;;) { vTaskDelay(1000); digitalWrite(BOARD_LED_PIN, HIGH); vTaskDelay(50); digitalWrite(BOARD_LED_PIN, LOW); } } static void vCube1LoopTask(void *pvParameters) { while (1) { if ( xSemaphoreTake( xDisplayFree, ( portTickType ) 10 ) == pdTRUE ) { cube(cube1_px, cube1_py, cube1_pz, cube1_p2x, cube1_p2y, cube1_r, &cube1_x, &cube1_y, &cube1_color); xSemaphoreGive( xDisplayFree ); vTaskDelay(15); } } } static void vCube2LoopTask(void *pvParameters) { while (1) { if ( xSemaphoreTake( xDisplayFree, ( portTickType ) 10 ) == pdTRUE ) { cube(cube2_px, cube2_py, cube2_pz, cube2_p2x, cube2_p2y, cube2_r, &cube2_x, &cube2_y, &cube2_color); xSemaphoreGive( xDisplayFree ); vTaskDelay(40); } } } void cube(float *px, float *py, float *pz, float *p2x, float *p2y, int *r, uint16 *x, uint16 *y, uint16 *color) { for (int i = 0; i < 3; i++) { tft.drawLine(p2x[i], p2y[i], p2x[i + 1], p2y[i + 1], ILI9341_WHITE); tft.drawLine(p2x[i + 4], p2y[i + 4], p2x[i + 5], p2y[i + 5], ILI9341_WHITE); tft.drawLine(p2x[i], p2y[i], p2x[i + 4], p2y[i + 4], ILI9341_WHITE); } tft.drawLine(p2x[3], p2y[3], p2x[0], p2y[0], ILI9341_WHITE); tft.drawLine(p2x[7], p2y[7], p2x[4], p2y[4], ILI9341_WHITE); tft.drawLine(p2x[3], p2y[3], p2x[7], p2y[7], ILI9341_WHITE); r[0] = r[0] + 1; r[1] = r[1] + 1; if (r[0] == 36) r[0] = 0; if (r[1] == 36) r[1] = 0; if (r[2] == 36) r[2] = 0; for (int i = 0; i < 8; i++) { float px2 = px[i]; float py2 = cos_d[r[0]] * py[i] - sin_d[r[0]] * pz[i]; float pz2 = sin_d[r[0]] * py[i] + cos_d[r[0]] * pz[i]; float px3 = cos_d[r[1]] * px2 + sin_d[r[1]] * pz2; float py3 = py2; float pz3 = -sin_d[r[1]] * px2 + cos_d[r[1]] * pz2; float ax = cos_d[r[2]] * px3 - sin_d[r[2]] * py3; float ay = sin_d[r[2]] * px3 + cos_d[r[2]] * py3; float az = pz3 - 190; p2x[i] = *x + ax * 500 / az; p2y[i] = *y + ay * 500 / az; } for (int i = 0; i < 3; i++) { tft.drawLine(p2x[i], p2y[i], p2x[i + 1], p2y[i + 1], *color); tft.drawLine(p2x[i + 4], p2y[i + 4], p2x[i + 5], p2y[i + 5], *color); tft.drawLine(p2x[i], p2y[i], p2x[i + 4], p2y[i + 4], *color); } tft.drawLine(p2x[3], p2y[3], p2x[0], p2y[0], *color); tft.drawLine(p2x[7], p2y[7], p2x[4], p2y[4], *color); tft.drawLine(p2x[3], p2y[3], p2x[7], p2y[7], *color); } static void vSqrtTask(void *pvParameters) { while (1){ Serial.println ("Starting Sqrt calculations..."); uint16 x = 0; uint16 ixx[1001]; // Library Sqrt uint32_t t0 = millis(); for (uint32_t n = 247583650 ; n > 247400000 ; n--) { x = sqrt (n); } uint32_t t1 = millis() - t0; Serial.print ("Sqrt calculations took (ms): "); Serial.println (t1); delay (5000); } } void setup() { // initialize the digital pin as an output: Serial.begin(9600); delay (5000); Serial.println ("Running..."); pinMode(BOARD_LED_PIN, OUTPUT); tft.begin(); tft.fillScreen(ILI9341_WHITE); cube1_x = ((tft.width()) / 4); cube1_y = ((tft.height()) / 4); cube2_x = ((tft.width()) / 2); cube2_y = ((tft.height()) / 2); cube1_color = ILI9341_BLACK; cube2_color = ILI9341_RED; vSemaphoreCreateBinary(xDisplayFree); xTaskCreate(vLEDFlashTask, "Task1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); xTaskCreate(vCube1LoopTask, "Cube1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL); xTaskCreate(vCube2LoopTask, "Cube2", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+1, NULL); xTaskCreate(vSqrtTask, "Sqrt", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL); vTaskStartScheduler(); } void loop() { // Do not write any code here, it would not execute. }

Пито
Чт, 04 августа 2016 г., 17:03
Я тоже пробовал, но - я использовал SPI2 для дисплея с #include // STM32 DMA Hardware-specific library

michael_l
Чт, 04 августа 2016 г., 17:52
У меня была та же проблема, и я написал об этом в другой ветке. Я использовал неправильные булавки для CS, DC и RESET, хотя я думал, что они в порядке использовать. Изменение булавок заставило эскиз работать и отображать тоже.

Вы можете сначала попытаться запустить эскиз без мигания

Пито
Чт, 04 августа 2016 г., 18:22
Вы использовали SPI2??

michael_l
Чт, 04 августа 2016 г., 8:04 вечера
Пито написал:Вы использовали SPI2??

Пито
Чт, 04 августа 2016 г., 21:34
Он рисует небольшой отдельный куб иногда после сброса, но впоследствии останавливается.. Таким образом, SPI2 работает как -то, но, вероятно, должна быть проблема с DMA (SPI2 использует DMA IMHO) против. Freertos.
ОК, с большим cube_stack_sizes (т.е. 512bytes, по умолчанию configminimal_stack_size - это 120 шорт). Теперь он работает и с SPI2: .. xTaskCreate(vCube1LoopTask, "Cube1", 512, NULL, tskIDLE_PRIORITY + 2, NULL); xTaskCreate(vCube2LoopTask, "Cube2", 512, NULL, tskIDLE_PRIORITY + 1, NULL); ..

Пито
Пт 5 августа 2016 г., 9:46 утра
И Maple Mini Version (вкл. Некоторые моды) с дисплеем на SPI2: // Cube FreeRtos Demo // for Maple Mini and SPI2 display // uses "SPI2" ILI9341 library // uses UART at 115k2 // ide 1.6.10 // mods 8/2016 by Pito #include #include #include // Core graphics library, with extra fonts. #include // SPI2 DMA Hardware-specific library // Maple Mini with SPI2 #define TFT_CS PA8 #define TFT_DC PA13 Adafruit_ILI9341_STM tft = Adafruit_ILI9341_STM(TFT_CS, TFT_DC); // Use hardware SPI xSemaphoreHandle xDisplayFree; #define BOARD_LED_PIN PB1 const float sin_d[] = { 0, 0.17, 0.34, 0.5, 0.64, 0.77, 0.87, 0.94, 0.98, 1, 0.98, 0.94, 0.87, 0.77, 0.64, 0.5, 0.34, 0.17, 0, -0.17, -0.34, -0.5, -0.64, -0.77, -0.87, -0.94, -0.98, -1, -0.98, -0.94, -0.87, -0.77, -0.64, -0.5, -0.34, -0.17 }; const float cos_d[] = { 1, 0.98, 0.94, 0.87, 0.77, 0.64, 0.5, 0.34, 0.17, 0, -0.17, -0.34, -0.5, -0.64, -0.77, -0.87, -0.94, -0.98, -1, -0.98, -0.94, -0.87, -0.77, -0.64, -0.5, -0.34, -0.17, 0, 0.17, 0.34, 0.5, 0.64, 0.77, 0.87, 0.94, 0.98 }; const float d = 5; float cube1_px[] = { -d, d, d, -d, -d, d, d, -d }; float cube1_py[] = { -d, -d, d, d, -d, -d, d, d }; float cube1_pz[] = { -d, -d, -d, -d, d, d, d, d }; float cube1_p2x[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; float cube1_p2y[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int cube1_r[] = { 0, 0, 0 }; const float d2 = 10; float cube2_px[] = { -d2, d2, d2, -d2, -d2, d2, d2, -d2 }; float cube2_py[] = { -d2, -d2, d2, d2, -d2, -d2, d2, d2 }; float cube2_pz[] = { -d2, -d2, -d2, -d2, d2, d2, d2, d2 }; float cube2_p2x[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; float cube2_p2y[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int cube2_r[] = { 0, 0, 0 }; uint16 cube1_x, cube1_y, cube2_x, cube2_y, cube1_color, cube2_color; // Perform an LED blink every 1000msecs static void vLEDFlashTask( void * pvParameters ) { portTickType xLastWakeTime; const portTickType xPeriod = 1000; // =1second with 1ms Tick // Initialise the xLastWakeTime variable with the current time. xLastWakeTime = xTaskGetTickCount(); for( ;; ) { // Wait for the next blink cycle. vTaskDelayUntil( &xLastWakeTime, xPeriod ); // Perform the LED blink digitalWrite(BOARD_LED_PIN, HIGH); vTaskDelay(50); // 50msec blink digitalWrite(BOARD_LED_PIN, LOW); } } static void vCube1LoopTask(void *pvParameters) { while (1) { if ( xSemaphoreTake( xDisplayFree, ( portTickType ) 10 ) == pdTRUE ) { cube(cube1_px, cube1_py, cube1_pz, cube1_p2x, cube1_p2y, cube1_r, &cube1_x, &cube1_y, &cube1_color); xSemaphoreGive( xDisplayFree ); vTaskDelay(50); } } } static void vCube2LoopTask(void *pvParameters) { while (1) { if ( xSemaphoreTake( xDisplayFree, ( portTickType ) 10 ) == pdTRUE ) { cube(cube2_px, cube2_py, cube2_pz, cube2_p2x, cube2_p2y, cube2_r, &cube2_x, &cube2_y, &cube2_color); xSemaphoreGive( xDisplayFree ); vTaskDelay(40); } } } void cube(float *px, float *py, float *pz, float *p2x, float *p2y, int *r, uint16 *x, uint16 *y, uint16 *color) { for (int i = 0; i < 3; i++) { tft.drawLine(p2x[i], p2y[i], p2x[i + 1], p2y[i + 1], ILI9341_WHITE); tft.drawLine(p2x[i + 4], p2y[i + 4], p2x[i + 5], p2y[i + 5], ILI9341_WHITE); tft.drawLine(p2x[i], p2y[i], p2x[i + 4], p2y[i + 4], ILI9341_WHITE); } tft.drawLine(p2x[3], p2y[3], p2x[0], p2y[0], ILI9341_WHITE); tft.drawLine(p2x[7], p2y[7], p2x[4], p2y[4], ILI9341_WHITE); tft.drawLine(p2x[3], p2y[3], p2x[7], p2y[7], ILI9341_WHITE); r[0] = r[0] + 1; r[1] = r[1] + 1; if (r[0] == 36) r[0] = 0; if (r[1] == 36) r[1] = 0; if (r[2] == 36) r[2] = 0; for (int i = 0; i < 8; i++) { float px2 = px[i]; float py2 = cos_d[r[0]] * py[i] - sin_d[r[0]] * pz[i]; float pz2 = sin_d[r[0]] * py[i] + cos_d[r[0]] * pz[i]; float px3 = cos_d[r[1]] * px2 + sin_d[r[1]] * pz2; float py3 = py2; float pz3 = -sin_d[r[1]] * px2 + cos_d[r[1]] * pz2; float ax = cos_d[r[2]] * px3 - sin_d[r[2]] * py3; float ay = sin_d[r[2]] * px3 + cos_d[r[2]] * py3; float az = pz3 - 190; p2x[i] = *x + ax * 500 / az; p2y[i] = *y + ay * 500 / az; } for (int i = 0; i < 3; i++) { tft.drawLine(p2x[i], p2y[i], p2x[i + 1], p2y[i + 1], *color); tft.drawLine(p2x[i + 4], p2y[i + 4], p2x[i + 5], p2y[i + 5], *color); tft.drawLine(p2x[i], p2y[i], p2x[i + 4], p2y[i + 4], *color); } tft.drawLine(p2x[3], p2y[3], p2x[0], p2y[0], *color); tft.drawLine(p2x[7], p2y[7], p2x[4], p2y[4], *color); tft.drawLine(p2x[3], p2y[3], p2x[7], p2y[7], *color); } static void vSqrtTask(void *pvParameters) { while (1){ Serial1.println (F("Starting Sqrt calculations...")); uint32 x = 0; uint32 Ns = 100000; // number of sqrt calcs // Library Sqrt uint32_t t0 = millis(); for (uint32_t n = 1 ; n < Ns ; n++) { x = sqrt (247400000 + n); } uint32_t t1 = millis() - t0; Serial1.print (F("100k Sqrt calculations took (ms): ")); Serial1.println (t1); vTaskDelay (70); } } void setup() { // initialize the digital pin as an output: Serial1.begin(115200); delay (1000); Serial1.println (F("Running...")); pinMode(BOARD_LED_PIN, OUTPUT); tft.begin(); tft.fillScreen(ILI9341_WHITE); cube1_x = ((tft.width()) / 4); cube1_y = ((tft.height()) / 4); cube2_x = ((tft.width()) / 2); cube2_y = ((tft.height()) / 2); cube1_color = ILI9341_BLACK; cube2_color = ILI9341_RED; vSemaphoreCreateBinary(xDisplayFree); xTaskCreate(vLEDFlashTask, "Task1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 3, NULL); xTaskCreate(vCube1LoopTask, "Cube1", configMINIMAL_STACK_SIZE + 200, NULL, tskIDLE_PRIORITY + 2, NULL); xTaskCreate(vCube2LoopTask, "Cube2", configMINIMAL_STACK_SIZE + 200, NULL, tskIDLE_PRIORITY + 1, NULL); xTaskCreate(vSqrtTask, "Sqrt", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL); vTaskStartScheduler(); Serial.println(F("Insufficient RAM")); while(1); } void loop() { // Do not write any code here, it would not execute. }

priyank_bolia
Ср 12 октября 2016 г., 17:23
У кого -то успешно использовал таймеры в Freertos на STM32Duino. Я пытался скомпилировать, скомпилировано, но ничего не сделал. Функция таймера никогда не была вызвана. У кого -нибудь есть рабочий пример таймеров.

michael_l
Ср. 02 ноября 2016 г., 10:42
Priyank_bolia написал:У кого -то успешно использовал таймеры в Freertos на STM32Duino. Я пытался скомпилировать, скомпилировано, но ничего не сделал. Функция таймера никогда не была вызвана. У кого -нибудь есть рабочий пример таймеров.

michael_l
Ср. 02 ноября 2016 г., 10:45
Это должно звучать как простой вопрос, но использует сериал.println 'и т.д. Функции нуждаются в охране с помощью мутекс в этом фриттосе, созданном для Maple и Bluepill в STM32Duino ?

Пито
Ср. 02 ноября 2016 г., 17:31
Я бы порекомендовал использовать Mutexes для любых ресурсов, которые можно было бы вызвать/запросить из нескольких задач.
Сериал обычно обращается к одному устройству (терминалу), поэтому не использование мутекса вокруг последовательного не обязательно не обязательно сбой кода (но ввод/вывод), однако такие ресурсы, как SPI и I2C, когда их вызывают из различных задач и решают различные задачи. Связанные устройства могут потерпеть крах, поэтому здесь требуется мутекс, AFAIK.

Олли
Ср. 02 ноября 2016 г. 18:29
Для SPI и I2C я использовал модель очередей, где один или несколько потоков/задач могут опубликовать запрос без какого -либо блокировки. Эти запросы хранятся в FIFO и обрабатываются один раз в то время. Когда доступен ответ от удаленного устройства, механизм обратного вызовов используется для связи с исходным потоком/задачей.

В этой модели не требуется мутекс.

Ура, Олли

michael_l
Чт, 3 ноября 2016 г., 8:34 утра
Спасибо, Пито и Олли. Я тестировал с несколькими задачами, написанными в сериале, и в какой -то момент он был запутан, но не разбился. Приятно знать. Я использую SPI1 и SPI2 с библиотекой ADAFRUT_ILI9143_STM, и я должен использовать Mutexes.

Какой -то другой вопрос, связанный с обработкой памяти. Я запрограммировал в многопоточных средах в течение многих лет, но в основном с ПК. Встроенные вещи настолько разные, как мы все знаем.

Я обнаружил, что Freertos имеет собственную модель памяти, где вы определяете в файле конфигурации, сколько памяти (куча) она может использовать. Где это определено? Из журнала сборки я вижу, что 8 КБ выделено, так что я предполагаю, что 8 КБ - это определено сумма. Также куча 8 КБ, доступная во всем мире для использования во всех задачах ?

Второй вопрос:

В одной из моих задач я добавил немного своего кода, и когда я запускаю его, он висит. Есть ли какие -либо методы в Freertos, доступные для отслеживания, если, например, Stack вышел из памяти, могу ли я получить некоторую функцию обратного вызова или тому подобное ? Если есть ошибка на уровне процессора, можно это проследить или найти также ?

Спасибо.

Пито
Чт, 3 ноября 2016 г., 9:57
..\ hareware \ arduino_stm32 \ stm32f1 \ libraries \ freertos821 \ utility \ memmang \ heap_1.в
Там есть несколько моделей..

Может быть:
http: // www.Freertos.org/uxtaskgetstackh ... rmark.HTML

michael_l
Чт, 3 ноября 2016 г., 18:41
Спасибо. А вот и один из способов проверить:

http: // www.Freertos.org/stacks и stac ... кокринг.HTML

victor_pv
Сб 24 декабря 2016 г. 12:51
Просто хотел добавить некоторые вещи в эту ветку.
Мне нужно убедиться, что я нашел правильную версию эскиза, а затем опубликую его, но у меня были следующие вместе, работающие вместе под Freertos 8.2.1 как включено в ядро:
ILI9163 дисплей в SPI2
SDCARD в SPI1
Траймеры аппаратного обеспечения, воспроизводимый файл WAV с прочтением из SDCARD.
DMA переносится как для SDCARD SPI, так и для дисплея.

Я использовал Mutexes, чтобы убедиться, что порты SPI не будут использоваться одновременно, потому что я использовал SPI.функция SetModule. Поскольку эти функции выбирают тот или другой порт, который будет использоваться с функциями SPI, мне нужен был мутекс, чтобы убедиться, что только один будет использоваться за раз.

В прошлом я перезаряил библиотеку ILI9163 для использования SPI2, закодированной в библиотеке, не используя SPI.SetModule, и это тоже работало нормально, но я думаю, что я все еще использовал Mutex, чтобы не иметь двух функций. Используйте порты SPI одновременно. Возможно, не было необходимо.

Я могу сказать, что в тот момент я подтолкнул процедуры SPI DMA к репо, оба SPI 1 & 2 порта можно использовать с DMA в том же эскизе, если использовались мутекс. Я не знаю всех изменений, которые были перемещены в репо с тех пор, что -то могло что -то сломать.
Кроме того, я не помню, могут ли функции SPI DMA поделиться некоторой переменной между обоими портами, они могут, в этом случае, если вы попытаетесь использовать один порт, в то время как предыдущая передача не завершена для другого порта, он может испортить некоторую переменную и причинять проблемы.

П.С. Исправление, у меня все вышеперечисленное работало над COOS. Я не помню, если бы я проверил то же самое в Freertos, но у меня нет причин полагать, что это не сработало бы.

USBERIAL и SERIAL TERMINAL