FreeRTOS

Working libraries, libraries being ported and related hardware
User avatar
mrburnette
Posts: 1762
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: FreeRTOS

Postby mrburnette » Thu May 21, 2015 11:47 pm

victor_pv wrote:<...>
Do you have any interesting example that could benefit from running in RTOS that would try?


@victor;

Just got RTC working today.

http://stm32duino.com/viewtopic.php?f=15&t=132#p1223

Might be interesting to know if RTC is "compatible" with freeRTOS ... I can see this being an interesting "basic" configuration and tHen add a worker thread for sensor/solenoid, etc.

Ray

victor_pv
Posts: 892
Joined: Mon Apr 27, 2015 12:12 pm

Re: FreeRTOS

Postby victor_pv » Fri May 22, 2015 1:48 am

Does RTC uses systick? if so, does it uses the systick callback function?

FreeRTOS uses systick with 1khz interrupts, and set the systick callback function to call an RTOS function that does the scheduling.

I believe RTC uses a different clock source, but if it uses systick, we could have 2 solutions:
-Change the callback from systick to RTC, and RTC calls the freeRTOS scheduler.
-Let RTOS have the callback from systick, but then RTOS calls the RTC.

Besides systick, and 2 functions in assembler that save the stack and restore the stack each time a task is switched, RTOS does not interfere with anything else.
I have successfully used DMA and the DMA ISR without any modification whatsoever, it doesn't care. As the cortex has a NVIC I guess that takes cares of priorities and serving any interrupt that triggers while another is being served, so they don't block each other.

In my most complex example to the moment, I have 2 functions drawing to the screen, with another function doing sqrt calculations in the background, pretty intense math. The sqrt performance goes down like 30% 40% compare as running by itself, but it has the lowest priorities, so at the same time the drawing ones are working at almost full speed.

If I used an mcu with 64KB, and reserved 32KB for frame buffer for a 128x128 full color TFT, I could the screen refresh completely on DMA at whatever frequency I wanted using just a few CPU cycles.
It's something I want to test, but I need to rewrite the ILI9163 driver to do all the drawing to a frame buffer.
Sadly, that would not work on in the nicer bigger 9341, cause the 1 full frame would take 144KB :(
I believe using the frame buffer could provide a huge performance impact, as writing a pixel would imply just writing 2 bytes to RAM, rather than having to send control data to the display, then the address of the pixel, then the pixel data itself, and wait for all those SPI transactions to complete...
Still the need for speed in such a small lcd display is doubtful...
Last edited by victor_pv on Fri May 22, 2015 1:55 am, edited 1 time in total.

User avatar
martinayotte
Posts: 1132
Joined: Mon Apr 27, 2015 1:45 pm

Re: FreeRTOS

Postby martinayotte » Fri May 22, 2015 1:51 am

mrburnette wrote:http://feilipu.me/2011/09/22/freertos-and-libraries-for-avr-atmega/

For the old 8-bit Arduino units, the revised library freeRTOS library above (updated 4/2015) looks promising, too. As I was discussing in another thread, the very cheap 328P 16MHz mini boards under $2 may become useful in future projects to manage sensors and pre-digest some of the data before sending over to the STM32 (master/hub).

Ray


It looks interesting. I will look more seriously when the "time" ingredient will be back in stock ... ;)

User avatar
ahull
Posts: 1376
Joined: Mon Apr 27, 2015 11:04 pm
Location: Sunny Scotland
Contact:

Re: FreeRTOS

Postby ahull » Fri May 22, 2015 10:44 am

victor_pv wrote:Does RTC uses systick? if so, does it uses the systick callback function?

FreeRTOS uses systick with 1khz interrupts, and set the systick callback function to call an RTOS function that does the scheduling.

I believe RTC uses a different clock source, but if it uses systick, we could have 2 solutions:
-Change the callback from systick to RTC, and RTC calls the freeRTOS scheduler.
-Let RTOS have the callback from systick, but then RTOS calls the RTC.

Besides systick, and 2 functions in assembler that save the stack and restore the stack each time a task is switched, RTOS does not interfere with anything else.
I have successfully used DMA and the DMA ISR without any modification whatsoever, it doesn't care. As the cortex has a NVIC I guess that takes cares of priorities and serving any interrupt that triggers while another is being served, so they don't block each other.

In my most complex example to the moment, I have 2 functions drawing to the screen, with another function doing sqrt calculations in the background, pretty intense math. The sqrt performance goes down like 30% 40% compare as running by itself, but it has the lowest priorities, so at the same time the drawing ones are working at almost full speed.

If I used an mcu with 64KB, and reserved 32KB for frame buffer for a 128x128 full color TFT, I could the screen refresh completely on DMA at whatever frequency I wanted using just a few CPU cycles.
It's something I want to test, but I need to rewrite the ILI9163 driver to do all the drawing to a frame buffer.
Sadly, that would not work on in the nicer bigger 9341, cause the 1 full frame would take 144KB :(
I believe using the frame buffer could provide a huge performance impact, as writing a pixel would imply just writing 2 bytes to RAM, rather than having to send control data to the display, then the address of the pixel, then the pixel data itself, and wait for all those SPI transactions to complete...
Still the need for speed in such a small lcd display is doubtful...


The frame buffer would only have to be large if it was full colour. If you limited yourself to a smaller number of bits for your frame buffer, then you could use less ram. A 1 bit frame buffer would take 240x320*1 bits or 9600 8 bit bytes 2 bits (4 colours) would take 19200 bytes. So if you only require to rapidly update a single colour, say to rapidly graph data or update text, then a frame buffer may be an option.
- Andy Hull -

victor_pv
Posts: 892
Joined: Mon Apr 27, 2015 12:12 pm

Re: FreeRTOS

Postby victor_pv » Fri May 22, 2015 3:44 pm

I think the problem would be that using a frame buffer like that would require CPU processing to translate the bits to the word in the screen. It's not like you can set a DMA transfer that will pick each bit and send the corresponding 16bit value to the SPI peripheral.
That would kill the main advantage I was thinking about, that was using a frame buffer so the whole screen is written at once by the DMA controller with no CPU cycles used.

I guess there could be one routine that translates from the binary frame buffer to 1 full scan line of color data, then have DMA send the scan line, then the routine translates the next line from binary to the 16bit color data, but this still would cost a lot of cpu cycles.

Where you thinking some other way to reduce cpu usage?

michael_l
Posts: 208
Joined: Mon Aug 24, 2015 6:11 pm

Re: FreeRTOS

Postby michael_l » Thu Aug 04, 2016 12:30 pm

victor, tried your example with ILI9341 (some small modifications) and it works great.

Image


Is #define USE_SEMAPHORE_DMA1 needed ?

Code: Select all

#define USE_SEMAPHORE_DMA1
#include <MapleFreeRTOS821.h>
#include <SPI.h>
#include <Adafruit_GFX_AS.h>    // Core graphics library, with extra fonts.
#include <Adafruit_ILI9341_STM.h> // 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.
}


User avatar
Pito
Posts: 561
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: FreeRTOS

Postby Pito » Thu Aug 04, 2016 5:03 pm

I've tried it as well, but - I've been using SPI2 for the display with

Code: Select all

#include <Adafruit_ILI9341_STM_SPI2.h>  // STM32 DMA Hardware-specific library

which works fine with my other sketch, but it locks everything with the cube demo above.
When I change it to

Code: Select all

#include <Adafruit_ILI9341_STM.h>  // STM32 DMA Hardware-specific library

the LED blinks 1Hz and the Serial prints out as it should, hopefully:

Code: Select all

Starting Sqrt calculations...
Sqrt calculations took (ms): 5971
Starting Sqrt calculations...
Sqrt calculations took (ms): 5960
Starting Sqrt calculations...

but the display shows nothing, of course.
1.6.10 and Maple Mini, btw.

michael_l
Posts: 208
Joined: Mon Aug 24, 2015 6:11 pm

Re: FreeRTOS

Postby michael_l » Thu Aug 04, 2016 5:52 pm

I had the same problem and wrote about it on the other thread. I was using wrong pins for Cs, dc and reset although I thought they were ok to use. Changing pins made the sketch work and display too.

You could first try to run the sketch without blink

User avatar
Pito
Posts: 561
Joined: Sat Mar 26, 2016 3:26 pm
Location: Rapa Nui

Re: FreeRTOS

Postby Pito » Thu Aug 04, 2016 6:22 pm

Did you use SPI2??

michael_l
Posts: 208
Joined: Mon Aug 24, 2015 6:11 pm

Re: FreeRTOS

Postby michael_l » Thu Aug 04, 2016 8:04 pm

Pito wrote:Did you use SPI2??


I used SPI. But I'll try SPI2 next time.


Return to “Libraries & Hardware”

Who is online

Users browsing this forum: No registered users and 1 guest