freertos eğitimi · İşletim sistemi temelleri [email protected] may 8, 2018 İşletim...

38
FreeRTOS Eğitimi FreeRTOS Eğitimi www.cmb-tech.com [email protected] May 8, 2018

Upload: others

Post on 28-May-2020

17 views

Category:

Documents


1 download

TRANSCRIPT

FreeRTOS EğitimiFreeRTOS Eğitimi

www.cmb-tech.com

[email protected] 8, 2018

İçerik

www.cmb-tech.com

● İşletim Sistemi Temelleri

● FreeRTOS

● Multitasking

● IPC/Resource management

● Framework Tasarımı

[email protected] 8, 2018

İşletim Sistemi Temelleri

www.cmb-tech.com

[email protected] 8, 2018

● İşletim Sistemi nedir?

● Donanımı kontrol eden yazılım

● Uygulama ile donanımı ayıran yazılım

● Her uygulamanın güvenli ve efektif şekilde yüklenmesini ve çalışmasını sağlayan yazılım

İşletim Sistemi, CPU, IO, bellek ve haberleşme sistemleri gibi kaynakların yöneticisidir.

İşletim Sistemi Temelleri

www.cmb-tech.com

[email protected] 8, 2018

● İşletim Sistemi olmadığında;

● Superloop

● Scheduler

● Cooperative mutitasking

İşletim sistemlerinin sağladıkları:

● Çoklu Görev (multitasking)

● Scheduling

● Görevler arası etkileşim/haberleşme (IPC)

● Bellek yönetimi (Memory management)

● IO Yönetimi

İşletim Sistemi Temelleri

www.cmb-tech.com

[email protected] 8, 2018

Superloop:

void func1(void){ //Do smth}

void func2(void){ //Do some other thing}//...void funcN(void){ //Do very different things}

int main(void){ //Initialization code

while(1) { func1(); func2(); //... funcN(); }}

Scheduler:typedef struct{ void (*taskFunc)(void);}Task;

void func1(void){ //Do smth}

void func2(void){ //Do some other thing}//...void funcN(void){ //Do very different things}

Task taskList[]={ func1, func2, //... funcN};

int main(void){ //Initialization code

while(1) { int i; for( i=0; i<sizeof(taskList)/sizeof(Task); i++ ){ taskList[i].taskFunc(); } }}

İşletim Sistemi Temelleri

www.cmb-tech.com

[email protected] 8, 2018

Cooperative Preemptive

İşletim Sistemi Temelleri

www.cmb-tech.com

[email protected] 8, 2018

Context Switch

1.Save Context

2.Select next task

3.Load Context

to currentTask stack

Scheduler → currrentTask = nextTask;

from currentTask stack

FreeRTOS

www.cmb-tech.com

[email protected] 8, 2018

Free - RT – OS

● Free: Bedava, ticari uygulamalarda da kullanılabilir.

● RT: RealTime - deterministic

● OS: Operating System

FreeRTOS

www.cmb-tech.com

● Multitasking / Task Management● Periodic/cont./event driven● Priority

● IPC / Synchronisation

● Soft timers

● Modularity

● Concurrent Programming

[email protected] 8, 2018

● Sürücüleri içermez

● Network veya Dosya sistemine erişim sağlamaz

● Hata ayıklama daha zorlaşır

FreeRTOS

www.cmb-tech.com

[email protected] 8, 2018

● Small footprint (5-10KBytes)

● Portable (farklı donanım mimarileri üzerinde çalışabilir)

● C ve çok az assembly ile yazılmıştır.

● Multitasking

● Preemptive

FreeRTOS – Source structure

www.cmb-tech.com

[email protected] 8, 2018

● https://freertos.org adresinden indirilebilir

● Klasör Yapısı:

FreeRTOS - Configuration

www.cmb-tech.com

[email protected] 8, 2018

● Konfigürasyon

FreeRTOSConfig.h

#define configMAX_TASK_COUNT 10#define configUSE_PREEMPTION 1#define configUSE_IDLE_HOOK 0#define configUSE_TICK_HOOK 0#define configCPU_CLOCK_HZ ( SystemCoreClock )#define configTICK_RATE_HZ ( ( portTickType ) 1000 )#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 12 )#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 256 )#define configMAX_STACK_SIZE ( ( unsigned short ) 2048 )#define configTOTAL_HEAP_SIZE ( ( size_t ) ( configMAX_TASK_COUNT * configMAX_STACK_SIZE ) )#define configMAX_TASK_NAME_LEN ( 32 )#define configUSE_TRACE_FACILITY 0#define configUSE_16_BIT_TICKS 0#define configIDLE_SHOULD_YIELD 1#define configUSE_MUTEXES 1#define configQUEUE_REGISTRY_SIZE 8#define configCHECK_FOR_STACK_OVERFLOW 0#define configUSE_RECURSIVE_MUTEXES 1#define configUSE_MALLOC_FAILED_HOOK 0#define configUSE_APPLICATION_TASK_TAG 0#define configUSE_COUNTING_SEMAPHORES 1#define configGENERATE_RUN_TIME_STATS 0

/* Co-routine definitions. */#define configUSE_CO_ROUTINES 0#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

/* Software timer definitions. */#define configUSE_TIMERS 1#define configTIMER_TASK_PRIORITY ( 2 )#define configTIMER_QUEUE_LENGTH 10#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )

/* Set the following definitions to 1 to include the API function, or zeroto exclude the API function. */#define INCLUDE_vTaskPrioritySet 1#define INCLUDE_uxTaskPriorityGet 1#define INCLUDE_vTaskDelete 1#define INCLUDE_vTaskCleanUpResources 1#define INCLUDE_vTaskSuspend 1#define INCLUDE_vTaskDelayUntil 1#define INCLUDE_vTaskDelay 1

FreeRTOS – Memory Management

www.cmb-tech.com

[email protected] 8, 2018

● Dynamic Memory Allocation

● Static Memory Allocation

#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 26 * 1024 ) )

#define configSUPPORT_STATIC_ALLOCATION 0

TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,const char * const pcName,const uint32_t ulStackDepth,void * const pvParameters,UBaseType_t uxPriority,StackType_t * const puxStackBuffer,StaticTask_t * const pxTaskBuffer )

BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,const char * const pcName,const configSTACK_DEPTH_TYPE usStackDepth,void * const pvParameters,UBaseType_t uxPriority,TaskHandle_t * const pxCreatedTask )

#ifndef configSUPPORT_DYNAMIC_ALLOCATION/* Defaults to 1 for backward compatibility. */#define configSUPPORT_DYNAMIC_ALLOCATION 1

#endif

FreeRTOS - Tasks

www.cmb-tech.com

[email protected] 8, 2018

● Process/Thread/Task

● Maksimum task sayısı donanım ile sınırlı

● xTaskCreate() ile yaratılıyor

xTaskCreate( taskFunc, (signed char *)"taskname", configMINIMAL_STACK_SIZE, (void*)&param, tskIDLE_PRIORITY, NULL );

void taskFunc( void* param ){

//do initializationwhile(1){

//do smth

//thenvTaskDelay( 1000 );

}}

vTaskStartScheduler();

FreeRTOS - Tasks

www.cmb-tech.com

[email protected] 8, 2018

● Task States

FreeRTOS - Priorities

www.cmb-tech.com

[email protected] 8, 2018

● HW Priorities

● Düşük sayı yüksek öncelik (-15, -14… 0 1 2 3)

● Task Priorities

● Düşük sayı düşük öncelik (idleTask=0)

xTaskCreate( func1, (signed char *)"test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );

FreeRTOS - Scheduling

www.cmb-tech.com

[email protected] 8, 2018

● Scheduling

FreeRTOS – Task parameters

www.cmb-tech.com

[email protected] 8, 2018

● Task Parameters

● Task variables

● Static variables

xTaskCreate( func1, (signed char *)"test", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );

FreeRTOS – Critical Section

www.cmb-tech.com

[email protected] 8, 2018

taskENTER_CRITICAL();

taskEXIT_CRITICAL();

//Do some critical work

void vPortEnterCritical( void ){

portDISABLE_INTERRUPTS();uxCriticalNesting++;

/* This is not the interrupt safe version of the enter critical function soassert() if it is being called from an interrupt context. Only APIfunctions that end in "FromISR" can be used in an interrupt. Only assert ifthe critical nesting count is 1 to protect against recursive calls if theassert function also uses a critical section. */if( uxCriticalNesting == 1 ){

configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );}

}/*-----------------------------------------------------------*/

void vPortExitCritical( void ){

configASSERT( uxCriticalNesting );uxCriticalNesting--;if( uxCriticalNesting == 0 ){

portENABLE_INTERRUPTS();}

}

Multitasking

www.cmb-tech.com

[email protected] 8, 2018

Inter-process Communications

www.cmb-tech.com

● Semaphore ve Mutex kavramları

[email protected] 8, 2018

● Semaphore - dataAvailable

● Binary semaphore (Flag)

● Counting Semaphore

https://cs.nyu.edu/~yap/classes/os/resources/origin_of_PV.html

Inter-process Communications

www.cmb-tech.com

[email protected] 8, 2018

#include "FreeRTOS.h"#include "task.h"#include "semphr.h"

xSemaphoreHandle semaphore1;

void func1( void* param ){ while( 1 ) { //Do smth if( pdPASS == xSemaphoreTake( semaphore1, 1000 ) ){ GPIOD->ODR |= (0x00000001<<12); vTaskDelay( 100 ); GPIOD->ODR &= ~(0x00000001<<12); vTaskDelay( 900 ); } }}

void func2( void* param ){ RCC->AHB1ENR |= 0x00000001;

while( 1 ) { if(GPIOA->IDR & 0x0001){ xSemaphoreGive( semaphore1 ); } vTaskDelay( 100 ); }}

vSemaphoreCreateBinary( semaphore1 );

semaphore1 = xSemaphoreCreateCounting( 20, 0 );

Inter-process Communications

www.cmb-tech.com

● Mutex - inUse

● Binary semaphore ile benzer● Aynı task tarafından alınıp geri

verilmelidir.

● Deadlock?

[email protected] 8, 2018

Inter-process Communications

www.cmb-tech.com

[email protected] 8, 2018

xSemaphoreHandle mutex1;

void func1( void* param ){ while( 1 ) { //Do smth if( pdPASS == xSemaphoreTake( mutex1, 10 ) ){ GPIOD->ODR |= (0x00000001<<12); vTaskDelay( 100 );

xSemaphoreGive( mutex1 );

GPIOD->ODR &= ~(0x00000001<<12); vTaskDelay( 900 );

} }}

void func2( void* param ){ RCC->AHB1ENR |= 0x00000001;

while( 1 ) { if(GPIOA->IDR & 0x0001){ if( pdPASS == xSemaphoreTake( mutex1, 10 ) ){ while((GPIOA->IDR & 0x0001)){ vTaskDelay( 1 ); } xSemaphoreGive( mutex1 ); } } vTaskDelay( 100 ); }}

mutex1 = xSemaphoreCreateMutex();

● Mutex, ISR içerisinde kullanılmaz

Inter-process Communications

www.cmb-tech.com

[email protected] 8, 2018

● Deadlock

Inter-process Communications

www.cmb-tech.com

● Queue - FIFO

[email protected] 8, 2018

xQueueHandle queue1;

void func1( void* param ){ while( 1 ) { int pinState; //Do smth if( pdPASS == xQueueReceive(queue1, ( void * ) &pinState, 10 ) )

{ if(pinState){ GPIOD->ODR |= (0x00000001<<12); } else { GPIOD->ODR &= ~(0x00000001<<12); }

} }}

void func2( void* param ){ RCC->AHB1ENR |= 0x00000001;

while( 1 ) { int pinState;

if(GPIOA->IDR & 0x0001){

pinState = 1; if( xQueueSend( queue1, ( void * ) &pinState, 10 ) != pdPASS ) { // Failed to post the message, even after 10 ticks. }

while(GPIOA->IDR & 0x0001){ vTaskDelay( 1 ); }

pinState = 0; if( xQueueSend( queue1, ( void * ) &pinState, 10 ) != pdPASS ) { // Failed to post the message, even after 10 ticks. }

}else{ vTaskDelay( 10 ); } }}

Inter-process Communications

www.cmb-tech.com

● Queue

[email protected] 8, 2018

xQueueHandle queue1;//....//....queue1 = xQueueCreate( 10, sizeof(int) ); if(!queue1){ //handle error}

xQueueSend( queue1, ( void * ) &pinState, 10 )

xQueueSendToBack( queue1, ( void * ) &pinState, 10 )

xQueueSendToFront( queue1, ( void * ) &pinState, 10 )

xQueueReceive(queue1, ( void * ) &pinState, 10 )

Inter-process Communications

www.cmb-tech.com

● StreamBuffer

● Point to Point Communication !!!

[email protected] 8, 2018

StreamBufferHandle_t stream1;

stream1 = xStreamBufferCreate( 100, 10 );

if( stream1 == NULL ){ //error handling}

pinState = 1;if( sizeof(pinState) != xStreamBufferSend( stream1, ( void * )&pinState, sizeof( pinState ), 10 ) ){ // Failed to post the message, even after 10 ticks.}

void func1( void* param ){ while( 1 ) { int pinState; //Do smth if( sizeof(pinState) == xStreamBufferReceive( stream1,( void * ) &pinState, sizeof( pinState ), 10 ) ){ if(pinState){ GPIOD->ODR |= (0x00000001<<12); } else { GPIOD->ODR &= ~(0x00000001<<12); } } }}

Inter-process Communications

www.cmb-tech.com

● MessageBuffer

● Point to Point Communication !!!

[email protected] 8, 2018

void func1( void* param ){ while( 1 ) { int pinState; //Do smth if( sizeof(pinState) == xMessageBufferReceive( messageBuffer1,( void * ) &pinState, sizeof( pinState ), 10000 ) ){ if(pinState){ GPIOD->ODR |= (0x00000001<<12); } else { GPIOD->ODR &= ~(0x00000001<<12); } } }}

MessageBufferHandle_t messageBuffer1;

pinState = 1;

if( sizeof(pinState) != xMessageBufferSend( messageBuffer1, ( void * )&pinState, sizeof( pinState ), 10 ) ){ // Failed to post the message, even after 10 ticks.}

messageBuffer1 = xMessageBufferCreate( 100 );

Inter-process Communications

www.cmb-tech.com

● Interrupts

[email protected] 8, 2018

xMessageBufferSend( messageBuffer1, ( void * )&pinState, sizeof( pinState ), 10 )

Block in ISR?

xStreamBufferSend xStreamBufferSendFromISR

xStreamBufferReceive xStreamBufferReceiveFromISR

xMessageBufferSend xMessageBufferSendFromISR

xMessageBufferReceive xMessageBufferReceiveFromISR

xQueueSend

xQueueReceive

xQueueSendFromISR

xQueueReceiveFromISR

xSemaphoreTake

xSemaphoreGive xSemaphoreGiveFromISR

xSemaphoreTakeFromISR

Soft-Timers

www.cmb-tech.com

● One-shot

● Auto-reload (Periodic)

[email protected] 8, 2018

timer1 = xTimerCreate( "Timer", 1000, pdTRUE, ( void * )0, timerCallback );

if( timer1 == NULL ){ // The timer was not created.}else{ if( xTimerStart( timer1, 0 ) != pdPASS ) { // The timer could not be set into the Active state. }}

void timerCallback( TimerHandle_t xTimer ){ //Do smth if(GPIOD->IDR & (0x00000001<<14) ){ GPIOD->ODR &= ~(0x00000001<<14); }else{ GPIOD->ODR |= (0x00000001<<14); }}

TimerHandle_t timer1;

Development Support

www.cmb-tech.com

[email protected] 8, 2018

#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

void vAssertCalled( const char *pcFile, uint32_t ulLine ){ RecordErrorInformationHere(pcFile, ulLine ); taskDISABLE_INTERRUPTS(); for( ;; );}

extern void vAssertCalled( const char *pcFile, uint32_t ulLine );#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )

#define configUSE_MALLOC_FAILED_HOOK 1

void vApplicationMallocFailedHook( void ){ //malloc failed}

#define configCHECK_FOR_STACK_OVERFLOW 1

void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ){ //stack overflow}

Framework Tasarımı

www.cmb-tech.com

● Moduler Tasarım

● Donanımdan soyutlama

● Sürücüler

● Diagnostic ve Debug arayüzü

[email protected] 8, 2018

Framework Tasarımı - Sürücüler

www.cmb-tech.com

● Interrupt Service Routine (ISR)

[email protected] 8, 2018

void Some_IRQHandler(void) { //check smth //Read data processData( data ); //return from ISR}

void Some_IRQHandler(void) { //check smth //Read data xQueueSendFromISR( hwDataQueue, ( void * ) &data, pdFALSE ); //return from ISR}

void highPrioTask( void* param ){ for(;;){ char data; if( pdPASS == xQueueReceive( hwDataQueue, ( void * ) &data, 10 ) ) { processData( data ); } }}

Use ● Queue● Stream● Message● Semaphore

Framework Tasarımı – Diagnostic/Debug

www.cmb-tech.com

● Debug Interface

[email protected] 8, 2018

#ifdef DEBUG_LOG_LEVEL_ERROR#define LOG_ERROR(x) DEBUG_LOG("ERROR: ",x)#define LOG_WARNING(x)#define LOG_INFO(x)

#elif defined DEBUG_LOG_LEVEL_WARNING#define LOG_WARNING(x) DEBUG_LOG("WARNING: ",x)#define LOG_ERROR(x) DEBUG_LOG("ERROR: ",x)#define LOG_INFO(x)

#elif defined DEBUG_LOG_LEVEL_INFO#define LOG_INFO(x) DEBUG_LOG("INFO: ",x)#define LOG_ERROR(x) DEBUG_LOG("ERROR: ",x)#define LOG_WARNING(x) DEBUG_LOG("WARNING: ",x)

#else#define LOG_INFO(x)#define LOG_ERROR(x)#define LOG_WARNING(x)

#endif

#ifdef DEBUG_LOG_ACTIVE#define DEBUG_LOG(level,x) {DC_Write(level);DC_Write(x);DC_Write("\n");}#define BREAK()

#elif defined DEBUG_BREAK_ACTIVE#define DEBUG_LOG(x)#define BREAK() { DISABLE_INT();for(;;);}

#else#define DEBUG_LOG(x)#define BREAK()

#endif

LOG_INFO("Someting not important");

LOG_ERROR("Someting very important");

Framework Tasarımı – Diagnostic/Debug

www.cmb-tech.com

● Diagnostic Interface

[email protected] 8, 2018

Firmware

USB2UARTFTDI

UART

DiagnosticInterface

Application

Run/Pause/StopApplication

Read/WriteVariable

Framework Tasarımı – Diagnostic/Debug

www.cmb-tech.com

● Map file

[email protected] 8, 2018

int globalVariable;

COMMON 0x200069f0 0x20 ..\obj\main.o 0x200069f0 messageBuffer1 0x200069f4 globalVariable 0x200069f8 stream1

0x200069fc semaphore1 0x20006a00 queue1 0x20006a04 hwDataQueue 0x20006a08 timer1 0x20006a0c mutex1

www.cmb-tech.com

[email protected] 8, 2018

TeşekkürlerEğitim dökümanına

https://www.cmb-tech.com/trainingDocuments.php

adresinden ulaşabilirsiniz.