4.5 Implementa¸c˜ ao do Sistema de Comunica¸c˜ ao e Controlo
4.5.2 Modelo de Camadas
O Modelo OSI ´e uma referˆencia muito importante na cria¸c˜ao de protocolos de co-
munica¸c˜ao. O sistema desenvolvido nesta disserta¸c˜ao n˜ao ´e exce¸c˜ao. Foi criado um
protocolo de comunica¸c˜ao baseado em camadas, no qual se definiram 3 camadas:
Liga¸c˜ao, Rede, Aplica¸c˜ao. A Figura 4.13representa o modelo desenhado, bem como algumas carater´ısticas e funcionalidades de cada camada.
Figura 4.13 – Modelo de camadas implementado no sistema de comunica¸c˜ao e controlo
As camadas criadas s˜ao independentes umas das outras, o que permite modificar
uma camada sem alterar as outras. No entanto ´e importante respeitar as regras de
4.5. IMPLEMENTAC¸ ˜AO DO SISTEMA DE COMUNICAC¸ ˜AO E CONTROLO 85
gens. uma estrutura de mensagem CAN, presente na camada de Liga¸c˜ao, e outra
estrutura para as mensagens de aplica¸c˜ao. A camada de Rede, que est´a no meio das
outras duas, utiliza as suas fun¸c˜oes para criar mensagens baseadas nas estruturas
definidas.
No software desenvolvido em Java, utilizado para diagn´osticos, est˜ao presentes os
ficheiro com o nome app, network e can message protocol, que representam as
camadas de aplica¸c˜ao, rede e Acesso `a Rede, respetivamente. No software criado em
C para o microcontrolador, foram criados os mesmos ficheiros com as mesmas fun¸c˜oes
e propriedades de c´odigo, mas foi criado ainda o ficheiro can s18 que juntamente
com o can message protocol criam a camada de Acesso `a Rede. O c´odigo presente
neste ficheiro permite ao PIC ler e colocar dados no barramento, realizando fun¸c˜oes
de baixo n´ıvel.
Camada de Acesso `a Rede
Para ser poss´ıvel criar a mensagem CAN, de forma definida, criou-se uma estrutura
de dados. Esta estrutura ´e respons´avel por guardar toda a informa¸c˜ao necess´aria
para a constru¸c˜ao da frame a enviar. Deste modo a estrutura permite introduzir
valores relativos ao ID, RTR, DLC e DATA (dados), sendo que os trˆes primeiros s˜ao
do tipo inteiro sem sinal e o ´ultimo ´e um vetor de inteiros sem sinal. A estrutura
pode ser analisada no c´odigo 4.1 e foi-lhe atribu´ıdo o nome CAN MSG.
typedef struct {
unsigned int ID;
86 CAP´ITULO 4. CAP´ITULO DE COMUNICAC¸ ˜AO E CONTROLO
unsigned int DATA[8]; } CAN_MSG;
C´odigo 4.1: Estrutura das mensagens CAN
O microcontrolador estar´a muitas vezes a trocar uma grande quantidade de mensa-
gens. Enviar ou receber mensagens pode consumir alguma da capacidade de pro-
cessamento e, juntamente com as outras fun¸c˜oes que o PIC est´a a realizar, pode
levar a que este n˜ao tenha capacidade de resposta suficiente para “atender” todos
os pedidos de mensagens que lhe chegam. Sentiu-se ent˜ao a necessidade de poder
armazenar as mensagens CAN temporariamente, enquanto estas n˜ao s˜ao enviadas
ou processadas. A estrutura desenvolvida para guardar a mensagem CAN pode ser
analisada no c´odigo 4.2.
typedef struct {
unsigned int rp;
unsigned int wp;
CAN_MSG CAN_FIFO[CAN_FIFO_MAX];
unsigned int counter; } CAN_FIFO;
C´odigo 4.2: Estrutura criada para armazenar mensagens CAN
Quando o microcontrolador precisa de enviar uma mensagem para o barramento
CAN, cria a mensagem e adiciona-a `a fila de mensagens a enviar. A mensagem
n˜ao ´e imediatamente enviada. Fica guardada at´e que a sua vez chegue. A estrutura
CAN FIFO, como o pr´oprio nome indica, ´e uma fila do tipo FIFO (First In First Out),
isto ´e, o primeiro elemento a entrar na fila ´e o primeiro a sair, mantendo a ordem
4.5. IMPLEMENTAC¸ ˜AO DO SISTEMA DE COMUNICAC¸ ˜AO E CONTROLO 87
esta FIFO um vetor de mensagens, ´e necess´ario definir o tamanho m´aximo do mesmo.
Foi-lhe atribu´ıdo o valor 8 (#define CAN FIFO MAX 8), sendo assim armazenar um
n´umero m´aximo de 8 mensagens. A vari´avel counter indica o n´umero de mensagens
por processar (enviar), e sempre que este ´e igual a 8 o PIC n˜ao guarda as mensagens
que se seguem, descartando-as.
Figura 4.14 – Esquema ilustrativo da FIFO de mensagens CAN
As vari´aveis rp e wp indicam a posi¸c˜ao de leitura e de escrita, respetivamente. Com
base nos valores que estes possuem ´e poss´ıvel saber qual a pr´oxima mensagem a ler,
para proceder ao envio, e a posi¸c˜ao onde o microcontrolador deve escrever a pr´oxima
mensagem a enviar posteriormente. `A medida que as mensagens s˜ao adicionadas `a
FIFO, o valor de wp ´e incrementado. O mesmo acontece com rp sempre que as
mensagens s˜ao lidas. fazendo com que o ponteiro de leitura v´a “perseguindo” o
ponteiro de escrita.
Sempre que os ponteiros chegam `a posi¸c˜ao 7 do vetor de mensagens, isto ´e, est˜ao no
´
ultimo espa¸co de leitura/escrita, ´e poss´ıvel que estes possam voltar `a posi¸c˜ao 0. Isto
torna a fila FIFO numa lista circular. No entanto apenas ´e poss´ıvel avan¸car com
os apontadores apenas se o n´umero de mensagens guardado na vari´avel counter for
88 CAP´ITULO 4. CAP´ITULO DE COMUNICAC¸ ˜AO E CONTROLO
Figura 4.15 – Adi¸c˜ao e leitura de mensagens na FIFO
A Figura 4.15 ilustra as fun¸c˜oes de adi¸c˜ao (ADD) e leitura (READ) de mensagens na FIFO. Inicialmente, a FIFO tem mensagens por processar nas posi¸c˜oes 5, 6, 7, 0 e
1, sendo que os valores de rp e wp s˜ao 5 e 2, respetivamente. Quando ´e feito um
pedido para adicionar uma nova mensagem `a FIFO, o sistema verifica o n´umero
de mensagens por processar (counter). Como este ´e igual a 5, logo ´e inferior ao
valor m´aximo poss´ıvel, a mensagem ´e gravada na posi¸c˜ao indicada pelo ponteiro de
escrita, wp0 →2. Depois de a mensagem ser gravada na posi¸c˜ao 2, o ponteiro passa a indicar a posi¸c˜ao 3 (wp1 →3). Se for necess´ario ler uma mensagem o programa realiza opera¸c˜oes semelhantes. Come¸ca por verificar se o valor de counter ´e maior
que 0. Como o contador passou a ser igual a 6, o sistema vˆe o valor para o qual o
ponteiro de leitura est´a a apontar, rp0 →5. A mensagem lida ´e depois processada e o ponteiro de leitura passa a ter o valor 6 (rp0 →6). O valor de counter ´e atualizado para 5.
4.5. IMPLEMENTAC¸ ˜AO DO SISTEMA DE COMUNICAC¸ ˜AO E CONTROLO 89
Um aspeto importante ´e a posi¸c˜ao de cada um dos ponteiros. O ponteiro wp est´a
quase sempre `a frente do ponteiro rp, podendo apenas estar na mesma posi¸c˜ao nos
casos em que a FIFO est´a vazia, sem mensagens para ler. Como se guarda o n´umero
de mensagens da FIFO na vari´avel counter ´e poss´ıvel impedir que a posi¸c˜ao de
escrita se sobreponha `a de leitura, impedindo que as mensagens sejam perdidas.
Todos estes aspetos e propriedades que foram descritos aplicam-se n˜ao s´o ao envio de
mensagens mas tamb´em `a leitura de mensagens do barramento CAN. Sempre que o
PIC lˆe uma mensagem do barramento CAN, verifica se esta lhe ´e destinada. Se for,
guarda-a na FIFO de entrada para que esta possa depois ser lida e processada. O
sistema vai lendo as mensagens pela mesma ordem com que chegaram, e sempre que
chega uma nova mensagem e exista espa¸co para a guardar (counter<8), escreve-a
na pr´oxima posi¸c˜ao dispon´ıvel, indicada por rp.
Depois de colocar a mensagem CAN na FIFO de entrada (FIFO IN) a mensagem ´e
processada, quando chegar a sua vez. A camada superior pode ler essa mensagem
ou colocar uma na FIFO de sa´ıda (FIFO OUT), respeitando sempre o formato da
mensagem CAN.
Camada de Rede
Esta camada, embora se chame camada de Rede, n˜ao cont´em todas as funcionali-
dades da camada de Rede do Modelo OSI. Apenas foram implementadas algumas
funcionalidades, tais como controlo de IDs (endere¸camento) e encapsulamento e de-
90 CAP´ITULO 4. CAP´ITULO DE COMUNICAC¸ ˜AO E CONTROLO
entre a camada de Acesso `a Rede e a camada de Aplica¸c˜ao.
A camada de Rede ´e respons´avel por ler a FIFO de entrada ou colocar mensagens
da camada de aplica¸c˜ao na FIFO de sa´ıda. Para o poder realizar estas tarefas, a
camada de rede utiliza as fun¸c˜oes de leitura e adi¸c˜ao da camada de Acesso `a Rede
e usa os seus m´etodos de codifica¸c˜ao e descodifica¸c˜ao. Outra fun¸c˜oes ´e lidar com o
endere¸camento dos v´arios n´os da rede.
Esta camada est´a constantemente a ler a FIFO de entrada, de forma a verificar
se existem mensagens para processar. As mensagens da FIFO de entrada podem
ser destinadas `a camada de rede ou `a camada de aplica¸c˜ao. Para saber que destino
atribuir a cada mensagem, a camada de rede desencapsula a mensagem e descodifica-
a.
Quando a mensagem CAN lida n˜ao tem como destino a camada de rede, ´e enviada
para a camada de aplica¸c˜ao. Mas antes de se poder enviar a mensagem para a
camada superior ´e necess´ario descodificar os dados e convertˆe-los no formato definido
para as mensagens de aplica¸c˜ao.
Figura 4.16 – Convers˜oes entre frames: descodifica¸c˜ao e codifica¸c˜ao
4.5. IMPLEMENTAC¸ ˜AO DO SISTEMA DE COMUNICAC¸ ˜AO E CONTROLO 91
tem converter mensagens de aplica¸c˜ao em mensagens CAN e vice-versa, respeti-
vamente. O sistema utiliza os m´etodos App Msg decode(CAN MSG msg) e CAN MSG
encode(App Msg msg). O primeiro permite ler uma mensagem CAN, processa a
mesma, converte a informa¸c˜ao para o formato da mensagem de aplica¸c˜ao e no final
retorna a mensagem do tipo APP MSG.
O mesmo acontece quando a camada de aplica¸c˜ao necessita de enviar uma mensa-
gem. A mensagem APP MSG ´e enviada para a camada de Rede e esta codifica a mensa-
gem no formato da CAN. Depois de convertida o m´etodo CAN MSG encode(App Msg
msg) devolve a mensagem CAN e esta ´e colocada na FIFO de sa´ıda da camada de
Acesso `a Rede. Esta camada fica encarregue de ler a FIFO e enviar a mensagem
assim que poss´ıvel.
Quando a mensagem ´e destinada `a camada de Rede significa que ´e um pedido ou
resposta de Ping ou de ID. Caso seja a primeira op¸c˜ao, Ping, se for um pedido, o
sistema lˆe a mensagem e verifica o ID do n´o que enviou a mensagem, colocando-o no
campo de ID de destino. O c´odigo de mensagem ´e alterado de “Ping” para “Pong”
e coloca nos dados o seu pr´oprio ID. Se a mensagem se relacionar com a gest˜ao de
IDs na rede, o processamento ´e diferente. ´E necess´ario saber que elementos existem
na rede e que IDs est˜ao dispon´ıveis.
A capacidade de controlo e gest˜ao de IDs apenas foi implementada em Java, uma vez
que s´o o SBC (Single Board Computer) pode realizar estas tarefas. Para lidar com
o controlo e gest˜ao de IDs foi necess´ario encontrar uma forma de mapear os IDs dos
92 CAP´ITULO 4. CAP´ITULO DE COMUNICAC¸ ˜AO E CONTROLO
3 op¸c˜oes (Oracle, map):
1. Hashtable (Oracle,hashtable) - Converte a chave noutro valor, com base numa
fun¸c˜ao de hashing. Qualquer objeto n˜ao-nulo pode ser utilizado como chave
ou valor. Para que o armazenar e readquirir dados seja vi´avel, os objetos uados
como chave devem implementar o mesmo m´etodo de hashCode. A performance
na sua utiliza¸c˜ao depende essencialmente de 2 fatores: do tamanho inicial
e o fator de carga (load factor ) (default = 75%). O tamanho inicial n˜ao
deve ser muito pequeno pois assim que o n´umero de elementos seja superior a
75% desse valor, o tamanho da tabale aumenta e ´e feito um novo rehashing.
Esta tarefa pode consumir algum tempo e capacidade de processamento, tanto
maior quanto maior o tamanho da tabela e o n´umero de vezes que ´e realizado.
O custo das opera¸c˜oes de inser¸c˜ao e remo¸c˜ao ´e O(1). O custo de itera¸c˜ao ´e
O(1).
2. LinkedHashMap (Oracle, linkedhashmap) - Os elementos da lista conhecem
tanto o elemento que lhe segue como o que lhe precede. A ordem com que
as chaves ficam na lista ´e a ordem pela qual s˜ao inseridos. Permite elemen-
tos nulos, como a classe HashMap. O seu desempenho pode ser influenciado
pela capacidade inicial e o fator de carga, mas com um menor peso que na
Hashtable. Assim como a Hashtable, o custo das opera¸c˜oes de inser¸c˜ao e
remo¸c˜ao ´e O(1) e o de itera¸c˜ao ´e O(n).
3. TreeMap (Oracle, treemap) - ´E uma ´arvore Red-Black. A ordena¸c˜ao dos ele-
4.5. IMPLEMENTAC¸ ˜AO DO SISTEMA DE COMUNICAC¸ ˜AO E CONTROLO 93
mesmos. Este tipo de implementa¸c˜ao garante um custo de O(log(n)) para os
m´etodos de pesquisa de chaves, inser¸c˜ao, remo¸c˜ao e obten¸c˜ao (containsKey,
put, remove e get). ´E poss´ıvel alterar o m´etodo de compara¸c˜ao, por forma a
alterar ordem de inser¸c˜ao dos elementos no mapa.
Decidiu-se basear o armazenamento dos IDs numa TreeMap, como a Figura 4.17
representa, devido ao custo de pesquisa log(n) e ao facto de os MACs ficarem
ordenados pela ordem natural.
Figura 4.17 – Mapeamento dos IDs com base nos MACs de cada n´o com TreeMap
Um pormenor importante na implementa¸c˜ao do controlo de IDs ´e o facto de n˜ao se
poder atribuir o mesmo ID a dois n´os diferentes. Uma forma de evitar elementos
repetidos ´e utilizar Sets. Assim criando um conjunto de elementos num Set e
consultando este conjunto, elimina-se a possibilidade de dar o mesmo ID a dois
MACs diferentes. Tiveram-se em conta os 3 tipos de Sets (Oracle, set):
1. HashSet (Oracle, hashset) - Esta classe implementa a interface Set apoiada
94 CAP´ITULO 4. CAP´ITULO DE COMUNICAC¸ ˜AO E CONTROLO
garante consistˆencia da ordem ao longo do tempo. Permite elementos nulos. As
a¸c˜oes de adi¸c˜ao, remo¸c˜ao e pesquisa tˆem um custo constante, O(1), assumindo
que a fun¸c˜ao de hash distribui os elementos de forma correta. O custo de
itera¸c˜ao ´e O(1), pelo que n˜ao se deve atribuir um tamanho inicial ou um fator
de carga muito elevado inicialmente.
2. LinkedHashSet (Oracle,linkedhashset) - Nesta classe a ordem de inser¸c˜ao dos
elementos ´e mantida. A ordem dos elementos no conjunto ´e igual `a ordem
pela qual foram adicionados. ´E uma lista duplamente ligada, uma vez que os
elementos da lista sabem que elemento est´a antes e depois. Da mesma forma
que o HashSet, o custo dos m´etodos de adi¸c˜ao, remo¸c˜ao e pesquisa tˆem um
custo O(1), sendo o custo de itera¸c˜ao O(n).
3. TreeSet (Oracle,treeset) - Consiste numa implementa¸c˜ao da interface NavigableSet
com base na classe TreeMap. Os elementos est˜ao ordenados pela sua ordem
natural, ou de outra forma se utilizar outra fun¸c˜ao de compara¸c˜ao. A sua es-
trutura permite custos de O(log(n)) para as opera¸c˜oes base: adi¸c˜ao, remo¸c˜ao
e pesquisa.
Implementou-se o conjunto do tipo TreeSet. Isto permitiu criar uma ´arvore que
cont´em todos os IDs livres, como se pode verificar na Figura4.18. Como se utilizou uma ´arvore, a implementa¸c˜ao desta parte do projeto tornou-se um pouco mais r´apida
uma vez que j´a se tinha trabalhado com a classe TreeMap, que tem uma utiliza¸c˜ao
semelhante.
4.5. IMPLEMENTAC¸ ˜AO DO SISTEMA DE COMUNICAC¸ ˜AO E CONTROLO 95
Figura 4.18 – TreeSet criado para guardar os IDs livres
´
e removido. Deste modo, o sistema, quando inicia o seu funcionamento, cria uma
´
arvore com os IDs 1, 2, 3, 4, ..., at´e ao ID 31. Este passo permite criar todos os Ids
poss´ıveis no sistema desenvolvido.
Sempre que chega um pedido de ID, a camada de Rede identifica o c´odigo da men-
sagem, verifica que ela lhe ´e destinada e processa-a. Na mensagem de pedido de ID
encontram-se os dois dados necess´arios `a atribui¸c˜ao de endere¸co na rede: o MAC do
n´o e o ID que esse n´o deseja ter. O c´odigo4.3 mostra de que forma a atribui¸c˜ao de ID funciona.
private final int ID_MAX = 31;
private TreeMap<Integer, Integer> ID_TreeMap = new
TreeMap<Integer, Integer>();
private TreeSet<Integer> ID_TreeSet = new TreeSet<Integer>();
private int giveID(int board_MAC, int board_ID) {
int newID = -1; if (board_ID > ID_MAX) { } else if (ID_TreeMap.containsKey(board_MAC)) { newID = ID_TreeMap.get(board_MAC); } else { while (!ID_TreeSet.contains(board_ID)) { board_ID++; if (board_ID > ID_MAX) { break; }
96 CAP´ITULO 4. CAP´ITULO DE COMUNICAC¸ ˜AO E CONTROLO } if (board_ID <= ID_MAX) { ID_TreeMap.put(board_MAC, board_ID); ID_TreeSet.remove(board_ID); } newID = board_ID; } return newID; }
C´odigo 4.3: M´etodo de atribui¸c˜ao de ID desenvolvido
Primeiro ´e verificado se o ID pedido ´e superior ao m´aximo. Se for verdade o m´etodo
devolve -1. De seguida, verifica-se se o n´o j´a tem um ID atribu´ıdo. Se o MAC do n´o
existir na ´arvore de mapeamento, o m´etodo devolve o ID correspondente ao MAC
fornecido como chave.
Caso o ID pedido seja v´alido e o MAC ainda n˜ao tenha um ID relacionado, procede-
se `a atribui¸c˜ao do ID de rede. Nesta parte, o objetivo ´e dar ao n´o o ID pedido,
mas caso j´a esteja ocupado, tenta-se dar o pr´oximo ID livre, de valor superior. O
ciclo while verifica se o ID proposto est´a livre, verificando se este est´a presente
no objeto ID TreeSet. Se estiver livre o ciclo p´ara e o ID ´e removido do objeto
do tipo TreeSet, adiciona-se um novo elemento ao objeto ID TreeMap, com chave
‘board MAC’ e valor ‘board ID’, e o valor newID ´e devolvido pelo m´etodo.
Enquanto o ID proposto n˜ao est´a livre, ou seja, n˜ao est´a presente na ´arvore TreeSet,
o valor de ID desejado vai incrementando. Caso o valor de board ID proposto
ultrapasse o valor m´aximo de ID, o ciclo p´ara e n˜ao ´e atribu´ıdo nenhum endere¸co
4.5. IMPLEMENTAC¸ ˜AO DO SISTEMA DE COMUNICAC¸ ˜AO E CONTROLO 97
Camada de Aplica¸c˜ao
A camada de Aplica¸c˜ao recebe as mensagens que a camada de Rede descodifica ou
cria mensagens para a camada de Acesso `a Rede, que s˜ao codificadas pela camada
de Rede. Esta camada superior tem um formato de mensagem definido, chamada
de APP MSG, com a estrutura que se pode ver no extrato de c´odigo 4.4.
typedef struct {
unsigned int CODE;
unsigned int ID;
unsigned int REQUEST;
int DATA[]; } APP_MSG;
C´odigo 4.4: Estrutura da mensagem da camada de Aplica¸c˜ao
A estrutura APP MSG ´e constitu´ıda por 4 partes:
• CODE - indica a fun¸c˜ao a executar, sendo representada por um valor de 5 bits. • ID - indica o n´o que enviou a mensagem ou para a qual a mensagem ´e destinada.
´
E tamb´em representado por 5 bits.
• REQUEST - indica se a mensagem ´e um pedido ou uma resposta. Apenas ´e constitu´ıdo por um bit.
• DATA[] - ´e o vetor onde ser˜ao inseridos/lidos os dados da mensagem.
Esta camada n˜ao foi completamente implementada. Apenas se projetou o formato
98 CAP´ITULO 4. CAP´ITULO DE COMUNICAC¸ ˜AO E CONTROLO
deve implementar esta camada, construindo os seus m´etodos os fun¸c˜oes de forma
a poder dar funcionalidades ao seu projeto. As fun¸c˜oes podem variar dependendo
do tipo de ve´ıculo ou sistema a controlar. Para este trabalho apenas foi criado um
m´etodo que permite verificar o c´odigo da mensagem de aplica¸c˜ao que a camada de
rede descodificou. Este m´etodo ap´os analisar o c´odigo da mensagem, invoca uma
fun¸c˜ao como por exemplo rodar um motor, ler a temperatura ou ligar o sistema de
ilumina¸c˜ao.