el68e prog concorrente - dainf.ct.utfpr.edu.brdainf.ct.utfpr.edu.br/~douglas/el68e prog concorrente...
Post on 19-Jul-2018
230 Views
Preview:
TRANSCRIPT
Programação Concorrente1 – Infra-estrutura
• Prog. Sequencial x Prog Concorrente• Pessoa x Equipe
• Processadores Virtuais
• Regiões de Memória de Prog. Sequencial
• Regiões de Memória de Prog. Concorrente• Multi-processo / MMU / mem. Virtual
• Multi-threaded
Problema da Exclusão Mútua –Soluções em SW
1. Porta
2. Porta 1 e Porta 21. Duas ordens de acesso possíveis
3. Vez
4. Porta 1, Porta 2 e Vez
SemáforosDefinição
Tipos: binário, contador, mutex
Conceito de propriedade – só a tarefa “dona” do semáforo pode liberá-lo
Suporte em HW
Ciclos RMW
Solução no Cortex – instruções de LD/ST exclusivo
Comunicação Assíncrona
Tarefa 1
Executando
Receive
Bloqueado em receive
Tarefa 2
Executando
Pronto
Pronto
Put
Comunicação Síncrona com Resp
Bloqueado em receive
Tarefa 1
Executando
Receive
Tarefa 2
Executando
Pronto
Pronto
Send
Bloqueado em send
Executando
Reply
Problema realSistema embarcado com:
3 portas seriais 115kbps = 1 char / 100u
USB = 1 pacote de 1K a cada 125us
IHM – touch
IHM – LCD
5 atividades:
A1: 2 ms leitura touch
A2: 7 ms processamento numérico dados USB
A3: 500 us protocolo USB
A4: 100 ms – sistema de menus
A5: …
Como seria o fluxo de controle num algoritmo
único para tratar de todas estas atividades ?
Douglas Renaux – ESC 2014
Multithreading(múltiplas linhas de execução)
PV1 PV2 … PVn
RTOS
HW Proc.
Mem.
Perif
Proc 1
Memória Compartilhada
Periféricos Compartilhados
Proc n…
Douglas Renaux – ESC 2014
Mas afinal, qual a mágica por trás do RTOS ?Cria processadores virtuais idênticos
Cada qual com seus registradores e sua pilha
Soma da capacidade de processamento de todos eles é igual ao do MCU
Multicore Muito mais proc. Virtuais do que cores
Douglas Renaux – ESC 2014
Regiões de Memória
Flash
CODE(.text)
(.const)
RAMHEAP
STACK
DATA(.data)(.bss)
CPU
Registradores
Douglas Renaux – ESC 2014
para um programa sequencial:
FlashCODE(.text)
(.const)
RAM
HEAP
DATA(.data)(.bss)
CPURegistradores
RAM
Multithreading(múltiplas linhas de execução)
STACK 1
Regs 1
RAM
STACK n
Regs n…
Douglas Renaux – ESC 2014
Olhando no tempo:granularidade grossa
Douglas Renaux – ESC 2014
Thread 1
Thread 2
Thread 3
Thread 4
t0 t0 +1s t0 +2s t0 +3s
RTOSA área de Engenharia de Sistemas Embarcados
já descobriu há décadas a importância de se usar um RTOS (70s)
Nestes 40 anos, inúmeros RTOS surgiram no mercado Comerciais
FOSS (Free and Open Source SW)
Silicon vendor
Douglas Renaux – ESC 2014
• v 1.0 (2008)– Drivers API
• v 2.0– DSP Lib
• v 3.0 (2012)– API RTOS– DAP (Debug)
• V 4.0 (2014)– CMSIS-Driver– CMSIS-Pack
• V 5.0 (2016)
CMSIS (Cortex Microcontroller Software Interface Standard)
Douglas Renaux – ESC 2014
Task Management
Timing (delay, timers)
Signals
Semaphore / Mutex
Memory Pool
Message Queue
Mail Queue
CMSIS-RTOS Funcionalidades
Douglas Renaux – ESC 2014
CMSIS-RTOS - Prioridades
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0049a/gs_ma_rtos.htm
enum osPriority {osPriorityIdle = -3,osPriorityLow = -2,osPriorityBelowNormal = -1,osPriorityNormal = 0,osPriorityAboveNormal = +1,osPriorityHigh = +2,osPriorityRealtime = +3,osPriorityError = 0x84
}
CMSIS-RTOS: Overview 1/4Kernel Information and Control
• osKernelInitialize : Initialize the RTOS kernel.• osKernelStart : Start the RTOS kernel.• osKernelRunning : Query if the RTOS kernel is running.• osKernelSysTick $ : Get RTOS kernel system timer counter.• osKernelSysTickFrequency $ : RTOS kernel system timer frequency in Hz.• osKernelSysTickMicroSec $ : Convert microseconds value to RTOS kernel
system timer value.
Thread Management• osThreadCreate : Start execution of a thread function.• osThreadTerminate : Stop execution of a thread function.• osThreadYield : Pass execution to next ready thread function.• osThreadGetId : Get the thread identifier to reference this thread.• osThreadSetPriority : Change the execution priority of a thread function.• osThreadGetPriority : Obtain the current execution priority of a thread
function.
Douglas Renaux – ESC 2014
CMSIS-RTOS: Overview 2/4Generic Wait Functions
• osDelay : Wait for a specified time.• osWait $ : Wait for any event of the type Signal, Message, or Mail.
Timer Management $• osTimerCreate : Define attributes of the timer callback function.• osTimerStart : Start or restart the timer with a time value.• osTimerStop : Stop the timer.• osTimerDelete : Delete a timer.
Douglas Renaux – ESC 2014
CMSIS-RTOS: Overview 3/4Signal Management
• osSignalSet : Set signal flags of a thread.• osSignalClear : Reset signal flags of a thread.• osSignalWait : Suspend execution until specific signal flags are set.
Mutex Management $• osMutexCreate : Define and initialize a mutex.• osMutexWait : Obtain a mutex or Wait until it becomes available.• osMutexRelease : Release a mutex.• osMutexDelete : Delete a mutex.
Semaphore Management $• osSemaphoreCreate : Define and initialize a semaphore.• osSemaphoreWait : Obtain a semaphore token or Wait until it becomes available.• osSemaphoreRelease : Release a semaphore token.• osSemaphoreDelete : Delete a semaphore.
Douglas Renaux – ESC 2014
CMSIS-RTOS: Overview 4/4
Douglas Renaux – ESC 2014
• Memory Pool Management $• osPoolCreate : Define and initialize a fix-size memory pool.• osPoolAlloc : Allocate a memory block.• osPoolCAlloc : Allocate a memory block and zero-set this block.• osPoolFree : Return a memory block to the memory pool.
• Message Queue Management $• osMessageCreate : Define and initialize a message queue.• osMessagePut : Put a message into a message queue.• osMessageGet : Get a message or suspend thread execution until message
arrives.• Mail Queue Management $
• osMailCreate : Define and initialize a mail queue with fix-size memory blocks.• osMailAlloc : Allocate a memory block.• osMailCAlloc : Allocate a memory block and zero-set this block.• osMailPut : Put a memory block into a mail queue.• osMailGet : Get a mail or suspend thread execution until mail arrives.• osMailFree : Return a memory block to the mail queue.
•
1. Definição de estruturas de dadoscomo acessar ?
2. Inicialização destas estruturas
3. OperaçãoYieldGetIdSetPriority
4. Término (opcional)
Ciclo de Vida dos Elementos do Kernel – exemplo: Thread
Douglas Renaux – ESC 2014
1. Definição de estruturas de dadoscomo acessar ?
2. Inicialização destas estruturas
3. OperaçãoYieldGetIdSetPriority
4. Término (opcional)
osThreadDef(job1, osPriorityAboveNormal, 1, 0);
macro
Cria uma struct com:
-nome da função principal desta thread
-prioridade
-número máximo de instâncias
-tamanho da pilha (em bytes) obs: 0 = tamanho default
osThread(job1):
uma macro que é substituida por um ponteiro para a estrutura acima
Ciclo de Vida dos Elementos do Kernel – exemplo: Thread
Douglas Renaux – ESC 2014
1. Definição de estruturas de dadoscomo acessar ?
2. Inicialização destas estruturas
3. OperaçãoYieldGetIdSetPriority
4. Término (opcional)
osThreadCreate(osThread(job1),NULL);
- Ponteiro para a struct com configuração da tarefa
- Ponteiro para argumento da função job1
Ciclo de Vida dos Elementos do Kernel – exemplo: Thread
Douglas Renaux – ESC 2014
1. Definição de estruturas de dadoscomo acessar ?
2. Inicialização destas estruturas
3. OperaçãoYieldGetIdSetPriority
4. Término (opcional)
Ciclo de Vida dos Elementos do Kernel – exemplo: Thread
Douglas Renaux – ESC 2014
osThreadYield( );
- Libera o processador para a próxima tarefa
osThreadGetId( );
- Retorna o identificador desta tarefa (ThreadId)
osThreadSetPriority( id, priority);
- Altera o nível de prioridade de uma tarefa
1. Definição de estruturas de dadoscomo acessar ?
2. Inicialização destas estruturas
3. OperaçãoYieldGetIdSetPriority
4. Término (opcional)
Ciclo de Vida dos Elementos do Kernel – exemplo: Thread
Douglas Renaux – ESC 2014
osThreadTerminate( id );
- Destrói o TCB eliminando esta tarefa do sistema
Ciclo de Vida dos Elementos do Kernel
Douglas Renaux – ESC 2014
Thread Timer Mutex Semaphore MemoryPool
MessageQueue
MailQueue
Tipos (*) osThreadIdos_pthread
osTimerIdos_ptimer
osMutexId osSemaphoreId osPoolId osMessageQId osMailQId
Definição osThreadDef osTimerDef osMutexDef osSemaphoreDef osPoolDef osMessageQDef osMailQDef
Acesso osThread osTimer osMutex osSemaphore osPool osMessageQ osMailQ
Inicializ. osThreadCreate osTimerCreate osMutexCreate osSemaphoreCreate osPoolCreate osMessageCreate osMailQCreate
Operação osThreadYieldosThreadGetId
osTimerStartosTimerStop
osMutexWaitosMutexRelease
osSemaphoreWaitosSemaphoreRelease
osPoolAllocosPoolFree
osMessagePutosMessageGet
osMailAllocosMailFreeosMailPutosMailGet
Término osThreadTerminate osTimerDelete osMutexDelete osSemaphoreDelete
(*) os Id são ponteiros para structs
Exercício 1• Familiarização com o exemplo de CMSIS-
RTOS
• Apresente um diagrama de classes com as tarefas deste exemplo
#include "cmsis_os.h" // CMSIS RTOS header file
void job1 (void const *argument) { // thread function 'job1'
while (1) {
: // execute some codeosDelay (10); // delay execution for 10 milliseconds
}
}osThreadDef(job1, osPriorityAboveNormal, 1, 0); // define job1 as thread function
void job2 (void const *argument) { // thread function 'job2'
while (1) {
: // execute some code
}
}
osThreadDef(job2, osPriorityNormal, 1, 0); // define job2 as thread function
int main (void) { // program execution starts here
osKernelInitialize (); // initialize RTOS kernel
: // setup and initialize peripherals
osThreadCreate (osThread(job1),NULL); // higher priority
osThreadCreate (osThread(job2),NULL);
osKernelStart (); // start kernel with job1 execution
}
Duas tarefas independentes
Douglas Renaux – ESC 2014
Exercício 2• Implementar um programa utilizando o CMSIS-
RTOS RTX que acione as 3 cores do LED RGB da placa base em intervalos de tempo ligeiramente diferentes.
– tR = 500ms, tG = 550ms, tB = 600ms
1. Utilizar osDelay em cada tarefa.
2. Utilizar 3 tarefas independentes, uma para cada cor do LED RGB.
Duas tarefas que compartilham um recurso
Douglas Renaux – ESC 2014
#include "cmsis_os.h" // CMSIS RTOS header file
osMutexDef (mutLCD);
void job1 (void const *argument) { // thread function 'job1'
while (1) {
osMutexWait (mutLCDid,osWaitForever);
: // resource usage
osMutexRelease (mutLCDid);
}
}
osThreadDef(job1, osPriorityNormal, 1, 0); // define job1 as thread function
void job2 (void const *argument) { // thread function 'job2'
}
osThreadDef(job2, osPriorityNormal, 1, 0); // define job2 as thread function
int main (void) { // main thread
: // setup and initialize peripherals
osMutexId mutLCDid = osMutexCreate (osMutex(mutLCD));
osThreadCreate (osThread(job1),NULL);
osThreadCreate (osThread(job2),NULL);
}
Comunicação ISR -> Tarefa
Douglas Renaux – ESC 2014
#include "cmsis_os.h" // CMSIS RTOS header file
enum JoystickMovement {Up, Down, Left, Right, Center, Last = 0x12345678};
osMessageQDef (MsgBox, 2, JoystickMovement ); // Define message queue
osMessageQId MsgBox;
void JoySt_ISR(void)
{
JoystickMovement JS_value = ReadJoyStick( );
osMessagePut(MsgBox, &JS_value, 0);
}
void PacMan (void const *argument) {
osEvent evt; // osEventMessage,valor, id da MsgBox
:
evt = osMessageGet(MsgBox, 5); // timeout 5 ms
if (evt == ...) {
:
}
osThreadDef(PacMan, osPriorityNormal,1,0); //define PacMan as thread function
int main (void) { // main thread
: // setup and initialize peripherals
MsgBox = osMessageCreate(osMessageQ(MsgBox), NULL);
osThreadCreate (osThread(PacMan));
}
Alocação de MemóriaMesmo papel de malloc e free
A biblioteca padrão do C não foi concebida para tolerar chaveamento de contexto, ou seja, não é thread-safe.
Douglas Renaux – ESC 2014
Alocação de Memória
Douglas Renaux – ESC 2014
void th_alloc_ex (void const *argument) {
uint32_t *address;
osStatus status; // códigos de retorno
osPoolId MemPool_Id; // ponteiro para o Pool
osPoolDef(MemPool,8,uint32_t); // Pool para 8 inteiros
MemPool_Id = osPoolCreate(osPool (MemPool)); // NULL = erro
address = (uint32_t *) osPoolAlloc(MemPool_Id); //aloca 1
*address = 0xffaabbcc; // acesso escrita
status = osPoolFree(MemPool_Id, address); // libera
// osOK, osErrorValue, osErrorParameter
osThreadTerminate(osThreadGetId());
}
CMSIS-RTOS - Temporizadores
www.arm.com
Macro de definição de temporizador: osTimerDef
Macro para acesso ao temporizador: osTimer
Tipos de dados: os_timer_type, osTimerId, osStatus
Funções: osTimerCreate, osTimerStart, osTimerStop, osTimerDelete
Função de Callback
Exercício 3 - repetir com temporizadores• Implementar um programa utilizando o CMSIS-
RTOS RTX que acione as 3 cores do LED RGB da placa base em intervalos de tempo ligeiramente diferentes.
– tR = 500ms, tG = 550ms, tB = 600ms
1. Utilizar timers do CMSIS-RTOS em cada tarefa.
2. Utilizar 3 tarefas independentes, uma para cada cor do LED RGB.
CMSIS-RTOS - EventosEventos são de 3 tipos:
Sinais – um flag (setado ou resetado)
Mensagens – um int de 32 bits / ponteiro
Mail – um bloco de memória
osEvent status osStatus(osEventSignal / osEventMessage / osEventMail)
value int / ptr / grupo flags
def id (do mail ou da msg)
CMSIS-RTOS - Eventosvoid Thread_2 (void const *arg);
osThreadDef (Thread_2, osPriorityHigh, 1, 0);
static void EX_Signal_1 (void) {
int32_t signals;
uint32_t exec;osThreadId thread_id;
thread_id = osThreadCreate (osThread(Thread_2), NULL);
if (thread_id == NULL) {
// Failed to create a thread.
} else {
signals = osSignalSet (thread_id, 0x00000005); // Send signals to the created thread
}
}
void Thread_3 (void const *arg);
osThreadDef (Thread_3, osPriorityHigh, 1, 0);
static void EX_Signal_1 (void) {osThreadId thread_id;osEvent evt;
thread_id = osThreadCreate (osThread(Thread_2), NULL);
if (thread_id == NULL) {
// Failed to create a thread.
} else {
// wait for a signal
evt = osSignalWait (0x01, 100); // espera pelo sinal 0x1 por até 100 ms
if (evt.status == osEventSignal) {
// handle event status
}
}
}
ver RTX_Conf_CM.C pela def do número max de sinais
CMSIS-RTOS - Semáforos• osSemaphore - para sincronização entre
tarefas e/ou tarefa/ISR
• osMutex - para exclusão Mútua. Apenas a tarefa que fez osMutexWait pode fazer osMutexRelease
Mutex// 1 – definição da estrutura de dados do Mutex (em geral é uma variável global)
osMutexDef(mut_GLCD);
// 2 – definição de um ponteiro para o Mutex (também costuma ser uma var global)
osMutexId mut_lcd;
// 3 – Inicialização do Mutex (em geral na função main)
mut_lcd = osMutexCreate(osMutex(mut_GLCD));
// 4 – Uso do Mutex sem timeout (a partir de uma thread)
osMutexWait(mut_lcd, osWaitForever);
...
osMutexRelease(mut_lcd);
obs:osMutex(mut_GLCD) é umachamada de MACROesta chamada retorna o endereço
da estrutura
Projeto – Arquitetura da SoluçãoElementos que compõem a arquitetura da solução:
• objetos/classes passivas
• Tarefas (threads) – objetos/classes ativas
• Tarefas Periódicas
• Message Queue – envia
• Event Queue – envia
• Temporizador – objeto passive + callback
• Semáforos (binário, contador e mutex)
• ISR – objeto/classe ativa
top related