Modelo Relatorio 001059836
Modelo Relatorio 001059836
Modelo Relatorio 001059836
ESCOLA DE ENGENHARIA
TRABALHO DE CONCLUSÃO EM ENGENHARIA DE CONTROLE
E AUTOMAÇÃO
I m p l e m e nta ç ã o d e u m
S i ste m a O p e ra c i o n a l
S i m p l i f i c a d o d e Te m p o Re a l
e m S i m u l i n k c o m G e ra ç ã o
A u to m á t i c a d e C ó d i go
E m b a rc a d o
Sumário
Sumário ii
Agradecimentos iii
Resumo iv
Abstract v
Lista de Figuras vi
Lista de Tabelas vii
1 Introdução 1
1.1 Objetivos 2
1.2 Estrutura do trabalho 3
2 Revisão Bibliográfica 4
2.1 Sistemas embarcados 4
2.1.1 Arduino 4
2.2 Sistemas operacionais 5
3 Materiais e Métodos 7
3.1 Programação através do Simulink 7
3.1.1 Function-Call Subsystem 7
3.1.2 Stateflow Chart 7
3.1.3 Simulink Coder 7
3.1.4 Simulink Support Package for Arduino Hardware 8
3.1.5 Custom C/C++ Target – Arduino 8
3.2 A Placa de desenvolvimento utilizada 9
4 Desenvolvimento do Trabalho 10
4.1 A Estrutura do Sistema Operacional 10
4.1.1 Implementação de tarefas 11
4.1.2 Escalonador (Scheduler) 12
4.1.3 Expedidor (Dispatcher) 17
4.2 Geração de código embarcado 19
5 Resultados 21
6 Conclusões e Trabalhos Futuros 28
7 Referências 30
8 Anexo A – Código original em C++ 32
Escola de Engenharia / UFRGS – Joel De Conto iii
________________________________________________________________________________________
Agradecimentos
Gostaria de agradecer a minha família, que me apoiou e incentivou desde o início de
meus estudos, ajudando assim no meu desenvolvimento pessoal e profissional.
Agradeço a minha namorada Jennifer, pelo amor, carinho e paciência, mesmos nos
momentos de dificuldade nestes últimos anos, além das convenientes instruções para
aprimorar a escrita deste trabalho.
Resumo
Considerando o crescente avanço de tecnologias utilizadas em hardwares
computacionais, a capacidade e poder de processamento de sistemas embarcados
também é aprimorado, demandando cada vez mais tempo e conhecimento para serem
programados. Algumas formas de facilitar e agilizar este processo são a implementação
de estruturas que gerenciem os recursos disponíveis e a utilização de linguagens de
programação de alto nível. Desta forma, este trabalho objetiva desenvolver um sistema
operacional simplificado no ambiente de diagrama de blocos do software Simulink, para
que possa ser utilizado na programação de sistemas embarcados. Para isso, será
analisado um sistema operacional escrito na linguagem C++ para a plataforma Arduino,
servindo como base para o desenvolvimento da lógica implementada no Simulink. Pelas
verificações realizadas, observa-se que o sistema operacional apresenta um
comportamento previsível e satisfatório, tanto na simulação quanto na implementação
em hardware, o que permite concluir que os objetivos deste trabalho foram alcançados,
disponibilizando uma estrutura de gerenciamento de tarefas que facilita o ciclo de
programação.
Palavras chaves
Abstract
Considering the increasing advance of technologies used in computer hardware, the
capacity and processing power of embedded systems is also developed, demanding more
time and knowledge to be programmed. Some ways to facilitate and speed up this
process are to implement structures that manage the available resources, and the use of
high-level programming languages. Therefore, this work aims to develop a simplified
operating system in the block diagram environment of the Simulink software, in order
that it can be used in the programming of embedded systems. For this purpose, an
operating system written in the C ++ language for the Arduino platform will be analyzed,
as a basis for the development of the logic implemented in Simulink. Through the
verification performed, it is observed that the operating system presents a predictable
and satisfactory behavior, both in simulation and hardware implementation, which allows
concluding that the objectives of this work were achieved, providing a task management
structure that facilitates the programming.
Keywords
Lista de Figuras
Figura 1 – Estrutura de um sistema embarcado genérico .................................................... 4
Figura 2 – Blocos disponíveis na biblioteca Custom C/C+ Target - Arduino .......................... 8
Figura 3 – Placa de desenvolvimento Arduino Uno .............................................................. 9
Figura 4 – Conexão principal do sistema operacional com as tarefas ................................ 10
Figura 5 – Estrutura dentro do bloco RTOS ......................................................................... 11
Figura 6 – Máscara do bloco RTOS ...................................................................................... 12
Figura 7 – Detalhamento da implementação em blocos do escalonador .......................... 13
Figura 8 – Subsistemas contidos no bloco de laço Do-While .............................................. 14
Figura 9 – Diagrama de blocos do subsistema Calcula delta_t ........................................... 15
Figura 10 – Diagrama de blocos do laço For - verifica tempo_decorrido ............................ 16
Figura 11 – Diagrama de blocos das condições if e else do teste contido no bloco verifica
tempo_decorrido ................................................................................................................. 16
Figura 12 – Stateflow Chart que implementa a função do expedidor ................................ 17
Figura 13 – Códigos executados nos estados do Stateflow Chart....................................... 18
Figura 14 – Janela de configuração dos parâmetros do Simulink Coder ............................. 19
Figura 15 – Tarefa de mudança do estado da saída ............................................................ 21
Figura 16 – Gráfico das saídas das tarefas gerado na simulação ........................................ 22
Figura 17 – Gráfico detalhado das saídas das tarefas na simulação no tempo a partir de
1800 milissegundos ............................................................................................................. 22
Figura 18 – Tarefa considerando um tempo computacional com a função delay .............. 23
Figura 19 – Estimativa de comportamento do conjunto escalonável de tarefas ............... 24
Figura 20 – Fotografias dos sinais medidos nas saídas do Arduino para o conjunto de
tarefas escalonável .............................................................................................................. 25
Figura 21 – Estimativa de comportamento do conjunto não-escalonável de tarefas ........ 26
Figura 22 – Fotos dos sinais medidos nas saídas do Arduino para o conjunto de tarefas
não-escalonável ................................................................................................................... 27
Escola de Engenharia / UFRGS – Joel De Conto vii
________________________________________________________________________________________
Lista de Tabelas
Tabela 1 – Conjunto de tarefas escalonável........................................................................ 24
Tabela 2 – Conjunto de tarefas não-escalonável ................................................................ 26
Escola de Engenharia / UFRGS – Joel De Conto 1
________________________________________________________________________________________
1 Introdução
Sistemas embarcados fazem parte do cotidiano. Mesmo passando despercebidos na
maioria das vezes, realizam funções importantes na vida moderna, atuando em uma vasta
gama de equipamentos, desde dispositivos simples, de uso pessoal, até complexos
sistemas industriais. Estima-se que mais de 98% dos processadores utilizados no mundo
estejam operando em sistemas embarcados e, embora possam não ser considerados
computadores por alguns, podem conter softwares bastante avançados (TAURION, 2005).
Uma maneira de facilitar este processo é utilizar uma linguagem de programação com
um nível mais alto de abstração, de forma que alguns processos sejam encobertos aos
olhos do programador e automaticamente executados ao compilar o código (HERNYÁK,
2012). Assim, o programador pode focar suas atenções no desenvolvimento do processo
em si, sem preocupar-se com a sintaxe de programação ou outros recursos que talvez não
sejam tão importantes no momento. Um exemplo disso é a plataforma Arduino, que
utiliza originalmente uma linguagem de programação baseada em C/C++ (ARDUINO
2017a), mas com simplificações que facilitam o aprendizado diminuem o tempo
necessário para a programação.
Embora seja vantajoso para o programador realizar tarefas com maior facilidade em
menos tempo, em algumas ocasiões, os métodos utilizados para estes fins acarretam no
desperdício do poder computacional do hardware, ou na perda de características
importantes para o processo, como a execução de tarefas periódicas em tempos
definidos. Os chamados sistemas de tempo real são os que possuem restrições de tempo
bastante precisas (BUTTAZZO, 2011), e muitas vezes a linguagem utilizada para a
programação não permite o controle necessário das tarefas para que o sistema consiga
executá-las de modo coerente e respeitando os requisitos temporais. Uma maneira de
contornar este problema é a utilização de um sistema operacional de tempo real, que irá
gerenciar os processos e recursos do processador de forma a aprimorar a eficiência da
execução de tarefas e garantir o cumprimento de requisitos temporais (TANENBAUM,
2010). Assim, é conveniente perguntar-se: é possível implementar uma estrutura de
2 Implementação de um Sistema Operacional Simplificado de Tempo Real em Simulink com
Geração Automática de Código Embarcado
________________________________________________________________________________________
Para validar este sistema serão propostos diferentes conjuntos de tarefas, de modo a
demonstrar a capacidade do sistema de executá-las de modo periódico e previsível.
1.1 Objetivos
O objetivo principal deste trabalho é realizar de maneira automatizada a programação
de um sistema operacional simplificado de tempo real em um sistema embarcado,
juntamente com as tarefas da aplicação, a partir do modelo do sistema em um nível
maior de abstração.
2 Revisão Bibliográfica
Neste capítulo será apresentada uma breve revisão sobre os principais conceitos
utilizados neste trabalho. Serão introduzidas as definições de sistemas embarcados e
sistemas operacionais, bem como os seus princípios de funcionamento.
2.1.1 Arduino
O Arduino é uma plataforma de prototipagem eletrônica de hardware e software
livres, composta por uma placa com um microcontrolador e um ambiente de
programação. O Arduino utiliza originalmente uma linguagem de programação baseada
Escola de Engenharia / UFRGS – Joel De Conto 5
________________________________________________________________________________________
Sistemas operacionais de tempo real são caracterizados por terem o tempo como um
parâmetro fundamental, onde os prazos para a execução de diferentes tarefas são
bastante rígidos. Assim, dois tipos de sistemas de tempo real podem ser identificados:
sistemas de tempo real crítico, os quais devem garantir a execução de determinadas
tarefas em tempos específicos; e sistemas de tempo real não críticos, nos quais embora
não seja desejável, o descumprimento de algum prazo não causará nenhum dano
permanente (TANENBAUM, 2010).
6 Implementação de um Sistema Operacional Simplificado de Tempo Real em Simulink com
Geração Automática de Código Embarcado
________________________________________________________________________________________
Uma das propriedades mais importantes que um sistema de tempo real deve
apresentar, segundo Buttazzo (2011), é a previsibilidade. O sistema deve poder prever a
evolução das tarefas e garantir que as restrições temporais sejam atendidas. Entretanto,
a confiabilidade desta previsão depende de diversos fatores, que envolvem desde a
arquitetura do hardware, até o algoritmo e a linguagem de programação utilizados.
3 Materiais e Métodos
Neste trabalho, utilizou-se principalmente o ambiente de programação do
Matlab/Simulink para realizar implementação do sistema operacional. Além disso,
também foi utilizada uma placa de desenvolvimento Arduino Uno para realizar a
implementação e validação experimental do sistema criado.
4 Desenvolvimento do Trabalho
O primeiro passo na realização deste projeto foi a análise do código disponibilizado
pelo professor Marcelo Götz, escrito na linguagem C/C++ para a plataforma Arduino, que
será utilizado como base para a construção do sistema operacional no ambiente do
Simulink.
A Figura 4 mostra a estrutura montada para a execução de três tarefas. O bloco RTOS
contém a lógica de funcionamento do sistema operacional de tempo real, gerando sinais
capazes de ativar a execução de um Function-Call Subsystem. Assim, cada saída do bloco
RTOS é conectada a um subsistema com essa configuração, dentro do qual está
construída a lógica para a tarefa. Neste caso, foram necessários três subsistemas, um
para cada tarefa.
bloco RTOS, ou seja, o primeiro período informado será para a saída t1, o segundo
período para a saída t2 e o terceiro para a saída t3, conforme visualizado na Figura 6.
automaticamente criado pela inserção dos valores, sendo que a ordem de inserção
corresponde a ordem em que estão dispostas as saídas no bloco RTOS.
execução do método, gerando assim uma diferença de tempo. O tempo atual é salvo na
variável que salva o tempo anterior para que possa ser utilizado na próxima iteração. A
diferença de tempo calculada é adicionada ao tempo decorrido desde a última chamada
de cada função. Em seguida, o tempo decorrido de cada tarefa é comparado com o
período que ela deve ser chamada, e caso seja maior, a tarefa é declarada como pronta
para a execução e o tempo decorrido é zerado. Desta forma, a finalidade do método Run
é verificar em cada instante de tempo quais tarefas devem ser executadas e declará-las
prontas para execução.
é realizado através de um bloco If, e caso o tempo atual seja maior ou igual ao tempo
anterior, a variável delta_t é calculada como a diferença entre os dois tempos, sendo
também adicionada à variável tempo_anterior para atualizar o valor para a próxima
iteração. Esta atualização é realizada dentro de um bloco do tipo MATLAB Function, no
qual é escrito um código na linguagem do Matlab que pode ser interpretado pelo
Simulink. A Figura 9 mostra a construção do subsistema descrito.
Dentro de cada estado foi implementada uma função do tipo MATLAB Function, que
permite adicionar um trecho de código a ser executado dentro do estado. A Figura 13
mostra os códigos adicionados nos dois estados.
18 Implementação de um Sistema Operacional Simplificado de Tempo Real em Simulink com
Geração Automática de Código Embarcado
________________________________________________________________________________________
Os eventos de saída do estado inicial testam o valor da variável i. Caso este valor seja
zero, o evento retorna ao início da execução do mesmo estado, fazendo com que o
programa execute novamente a lógica descrita anteriormente que identifica as tarefas
prontas. Caso o valor de i seja diferente de zero, a execução passa para o estado
AtivaTarefas, identificando que há uma tarefa selecionada para ser chamada
imediatamente.
uma saída do tipo function-call, indicando o nome e o número da porta de saída. Assim, a
geração do evento é realizada através da função send(), como pode ser visto na Figura 13,
as chamadas para as tarefas dentro da estrutura Switch-Case. Além das chamadas, esta
função também reinicializa o elemento do vetor tarefa_pronta correspondente à tarefa
que foi executada, para indicar que a chamada foi realizada e liberar as demais tarefas
para a execução.
5 Resultados
Neste capítulo serão apresentados e analisados os testes realizados para validar o
sistema construído e verificar seu correto funcionamento. Para isso, é necessário verificar
se as chamadas de tarefas estão acontecendo de maneira correta. Da maneira que o
sistema foi criado, espera-se que funcione em situações diferentes: na simulação do
Simulink e quando transferido para um microcontrolador através do Simulink Coder,
desde que o microcontrolador seja suportado pelo Embedded Coder e pela biblioteca
Custom C/C++ Target – Arduino (este último, caso seja utilizada a plataforma Arduino).
As saídas das tarefas foram ligadas a um bloco Scope, para visualizar as mudanças de
estado. A Figura 16 mostra os gráficos gerados pelas saídas. Pode-se perceber que as
mudanças de estado de cada uma das saídas ocorrem aproximadamente em tempos
múltiplos dos períodos inseridos. Assim, comprova-se que o sistema operacional realiza a
chamada das tarefas no tempo desejado.
Figura 17 – Gráfico detalhado das saídas das tarefas na simulação no tempo a partir de
1800 milissegundos
Fonte: autor
Escola de Engenharia / UFRGS – Joel De Conto 23
________________________________________________________________________________________
Embora este teste seja válido para mostrar as chamadas de tarefas nos períodos
estipulados, não é possível verificar o comportamento do sistema com atrasos, que
podem acontecer devido ao tempo de processamento de cada tarefa. Uma vez iniciadas,
as tarefas devem completar sua execução para liberar o uso do processador para o
sistema operacional identificar e chamar uma próxima tarefa. Assim, um conjunto de
tarefas com um custo computacional elevado pode não ser viável, pois o sistema não
conseguirá atender todas as condições temporais demandadas.
Para verificar o comportamento do sistema operacional com tarefas que exijam maior
tempo de processamento, foi construído o conjunto de blocos mostrado na Figura 18.
Nesta tarefa foi implementado um bloco do tipo S-function, que possibilita a inserção
de código C/C++ no ambiente do Simulink. Neste bloco foi escrita uma função que
executa um atraso através da função delay() do Arduino. Uma saída digital do Arduino foi
colocada em nível alto antes e em nível baixo após o delay, para que se possa visualizar o
tempo que o processador gastou para executar esta tarefa. Como a troca de nível lógico
da saída demanda um tempo de processamento bastante baixo, o tempo total da tarefa
pode ser considerado como o tempo inserido na função delay. Como a função delay não é
compreendida como um comando válido no Matlab, a tarefa mostrada na Figura 18 não
funciona de forma correta na simulação do Simulink. Entretanto, ela é compreendida pelo
Simulink Coder e pelo Arduino, quando transferida para o microcontrolador. Assim, o
funcionamento do sistema pode ser visualizado adquirindo os sinais das saídas digitais do
Arduino através de um osciloscópio.
Tarefa 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
T1 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
T2 1 2 3 4 5 6 7 1 2 3 4 5 6 7
T3 1 2 3 1 2 3 1 2 3
Tarefa 1
0
Início
Tarefa 2
Início
Tarefa 3
Figura 20 – Fotografias dos sinais medidos nas saídas do Arduino para o conjunto de
tarefas escalonável
Fonte: autor
Tarefa 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
T1 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
T2 1 2 3 4 5 6 7
T3 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
Tarefa 1
0
Início
Tarefa 2
Início
Tarefa 3
Figura 22 – Fotos dos sinais medidos nas saídas do Arduino para o conjunto de tarefas
não-escalonável
Fonte: autor
Embora não tenha sido precisamente quantificado, o tempo necessário para a troca
de contexto do sistema, ou seja, o período entre a execução de duas tarefas diferentes
em sequência, é em torno de 2 milissegundos. Desta forma, dependendo do tempo de
execução das tarefas, o período mínimo que pode ser utilizado fica em torno de 5
milissegundos.
28 Implementação de um Sistema Operacional Simplificado de Tempo Real em Simulink com
Geração Automática de Código Embarcado
________________________________________________________________________________________
7 Referências
BARR, Michael; MASSA, Anthony. Programming Embedded Systems With C and GNU
Development Tools. 2 ed. O'Reilly, 2009. 336 p.
HEATH, Steve. Embedded Systems Design. 2 ed. Oxford: Newnes, 2003. 430 p.
MATHWORKS. Matlab & Simulink: Simulink User's Guide. Edição. Natick, MA, 2017b.
4090 p.
MIT AEROASTRO. MIT and Navigating the Path to the Moon. Disponível em:
<http://web.mit.edu/aeroastro/news/magazine/aeroastro6/mit-apollo.html>. Acesso
em: 01 out. 2017.
OLIVEIRA, Rômulo S.; CARISSIMI, Alexandre S.; TOSCANI, Simão S. Sistemas Operacionais-
Vol. 11: Série Livros Didáticos Informática UFRGS. Bookman Editora, 2009
Sketch_sep23a.ino
1 #include "TaskClass.h"
2 #include "SchedulerClass.h"
3 #include "DispatcherClass.h"
4
5 #include "Tasks.h"
6
7 SchedulerClass Scheduler;
8
9 DispatcherClass Dispatcher;
10
11 TaskClass Task1(Task_1_code, 1000);
12 TaskClass Task2(Task_2_code, 1500);
13 TaskClass Task3(Task_3_code, 500);
14
15 void setup() {
16 // put your setup code here, to run once:
17
18 Scheduler.InsertTask (&Task1);
19 Scheduler.InsertTask (&Task2);
20 Scheduler.InsertTask (&Task3);
21
22 Scheduler.Sort();
23
24 Scheduler.Start();
25 }
26
27 void loop() {
28 // put your main code here, to run repeatedly:
29 TaskClass* f;
30
31 Scheduler.Run();
32
33 f = Scheduler.GetReadyTask();
34
35 if (f != NULL)
36 {
37 // Exist a task to run
38 Dispatcher.RunTask(f);
39 }
40 }
SchedulerClass.cpp
1 #include "SchedulerClass.h"
2
3 const unsigned long m_last_ = 0;
4 #define M_LAST (m_last_ - 1)
5
6 static inline unsigned long timing() { return millis(); }
7 //static inline unsigned long timing() { return micros(); }
8
9 // Constructor
Escola de Engenharia / UFRGS – Joel De Conto 33
________________________________________________________________________________________
10 SchedulerClass::SchedulerClass(void)
11 {
12 nTasks = 0;
13 }
14
15 unsigned char SchedulerClass :: getMaxNTasks(void)
16 {
17 return nTasks;
18 }
19
20 int SchedulerClass :: InsertTask (TaskClass *ptrTask)
21 {
22 //int ret;
23
24 // check if there is room free for inclusion
25 if (nTasks >= _MAX_N_TASKS)
26 {
27 return -1;
28 }
29
30 // if room free, insert and return number of tasks
31 ptrTaskList[nTasks] = ptrTask;
32 //ret = nTasks;
33 nTasks++;
34
35 return nTasks;
36 }
37
38 void SchedulerClass :: Start (void)
39 {
40 time_prev = timing();
41 }
42
43 boolean SchedulerClass :: Run (void)
44 {
45 unsigned long time_now;
46 unsigned long delta_time;
47 boolean ret;
48
49 int i;
50
51 time_now = timing();
52 ret = false;
53
54 if (time_now == time_prev)
55 return ret;
56
57 if (time_now > time_prev)
58 {
59 delta_time = (time_now > time_prev);
60 }
61 else // (time_now < time_prev) // will enter here not so often,
just in overflow cases.
62 {
63 delta_time = ((M_LAST - time_prev) + time_now);
64 }
65
66 time_prev = time_now;
67
68 // update all elapsed time now and check if it is ready;
69 for (i = 0; i < nTasks; i++)
70 {
71 if (ptrTaskList[i]->period != 0)
72 {
34 Implementação de um Sistema Operacional Simplificado de Tempo Real em Simulink com
Geração Automática de Código Embarcado
________________________________________________________________________________________
73 ptrTaskList[i]->elapsed_time += delta_time;
74 if (ptrTaskList[i]->elapsed_time >= ptrTaskList[i]-
>period)
75 {
76 ptrTaskList[i]->elapsed_time = 0;
77 ptrTaskList[i]->ready = true;
78 ret = true;
79 }
80 }
81 }
82
83 return ret;
84 }
85
86 TaskClass* SchedulerClass :: GetReadyTask(void)
87 {
88 TaskClass* f = NULL;
89 int i;
90
91 for (i = 0; i < nTasks; i++)
92 {
93 if (ptrTaskList[i]->ready)
94 {
95 f = ptrTaskList[i];
96 break;
97 }
98 }
99
100 return f;
101 }
102
103 // method to sort task list in decreasing priority.
104 void SchedulerClass :: Sort(void)
105 {
106 int i, j;
107 TaskClass* pTask;
108
109 for(i=0; i<(nTasks-1); i++)
110 {
111 for(j=0; j<(nTasks-(i+1)); j++)
112 {
113 if(ptrTaskList[j] > ptrTaskList[j+1])
114 {
115 pTask = ptrTaskList[j];
116 ptrTaskList[j] = ptrTaskList[j+1];
117 ptrTaskList[j+1] = pTask;
118 }
119 }
120 }
121 }
SchedulerClass.h
1 #ifndef SCHEDULERCLASS_H
2 #define SCHEDULERCLASS_H
3
4 #include <Arduino.h>
5
6 #include "TaskClass.h"
7
8 #ifndef _MAX_N_TASKS
Escola de Engenharia / UFRGS – Joel De Conto 35
________________________________________________________________________________________
DispatcherClass.cpp
1 #include "DispatcherClass.h"
2
3 // Constructor
4 DispatcherClass :: DispatcherClass()
5 {
6
7 }
8
9 void DispatcherClass :: RunTask (TaskClass* f)
10 {
11 if (f == NULL)
12 return;
13
14 f->task_function();
15 f->ready = false;
16 }
36 Implementação de um Sistema Operacional Simplificado de Tempo Real em Simulink com
Geração Automática de Código Embarcado
________________________________________________________________________________________
DispatcherClass.h
1 #ifndef DISPATCHERCLASS_H
2 #define DISPATCHERCLASS_H
3
4 #include <Arduino.h>
5
6 #include "TaskClass.h"
7
8 class DispatcherClass
9 {
10 public:
11 // constructor
12 DispatcherClass();
13
14 // execute task:
15 void RunTask(TaskClass* f);
16
17 private:
18
19 };
20 #endif
TaskClass.cpp
1 #include "TaskClass.h"
2
3 // Task Constructor
4 TaskClass :: TaskClass(ptr_task_function f, unsigned long p)
5 {
6 ready = false;
7
8 task_function = f;
9
10 elapsed_time = 0;
11
12 period = p;
13 }
TaskClass.h
1 #ifndef TASKCLASS_H
2 #define TASKCLASS_H
3
4 #include <Arduino.h>
5
6 //typedef std::function<void(void)> timer_callback;
7 typedef void(*ptr_task_function)(void);
8
9 class TaskClass
10 {
11 public:
12
13 // Constructor
14 TaskClass(ptr_task_function f, unsigned long p);
15
16 // indicates if task is ready to run
Escola de Engenharia / UFRGS – Joel De Conto 37
________________________________________________________________________________________
17 boolean ready;
18
19 // Task period. If 0 indicates an aperiodic task.
20 unsigned long period;
21
22 // Elapsed time unit since last execution.
23 unsigned long elapsed_time;
24
25 // Task to be executed in each period ou once.
26 ptr_task_function task_function;
27
28 private:
29
30 };
31
32 #endif
Tasks.cpp
1 #include "Tasks.h"
2
3 void Task_1_code (void)
4 {
5 char x;
6
7 x = 1;
8 }
9
10 void Task_2_code (void)
11 {
12 char x;
13
14 x = 1;
15 }
16
17 void Task_3_code (void)
18 {
19 char x;
20
21 x = 1;
22 }
Tasks.h
1 #ifndef TASKS_H
2 #define TASKS_H
3
4 void Task_1_code (void);
5
6 void Task_2_code (void);
7
8 void Task_3_code (void);
9
10 #endif