Escolar Documentos
Profissional Documentos
Cultura Documentos
Visão geral
A PDU do Modbus é formada por um código de função seguido por um conjunto de dados
associado. As dimensões e o conteúdo desses dados são definidos pelo código de função, mas
toda a PDU (código de função e dados) não pode ultrapassar 253 bytes. Cada código de função
tem um comportamento específico, que os escravos têm flexibilidade para implementar com base
no comportamento desejado da aplicação. A especificação de PDU define os conceitos básicos
para o acesso e manipulação dos dados; entretanto, um escravo pode tratar os dados de uma
maneira não definida explicitamente na especificação.
Acesso aos dados no Modbus e o modelo de dados do Modbus
Os dados que podem ser acessados pelo Modbus são armazenados, de forma geral, em
um dos quatro bancos de dados, ou faixas de endereço: coils, entradas discretas, registradores
holding e registradores de entrada. Como ocorre com muitas partes da especificação, esses
nomes podem variar, dependendo da indústria ou aplicação. Por exemplo, os registradores
holding podem ser denominados registradores de saída, e os coils podem ser referidos como
saídas digitais ou discretas. Esses bancos de dados definem o tipo e os direitos de acesso dos
dados contidos. Os dispositivos escravo têm acesso direto a esses dados, que são hospedados
localmente nos dispositivos. Os dados que podem ser acessados pelo Modbus são de forma
geral um subconjunto da memória principal do dispositivo. Por outro lado, os mestres Modbus
Embora a especificação defina que diferentes tipos de dados devem existir em blocos diferentes e
atribua uma faixa de endereços local para cada tipo, isso não implica que haverá
necessariamente um esquema de endereçamento intuitivo ou facilmente compreensível para a
documentação da memória que pode ser acessada pelo Modbus para um determinado
dispositivo. Para simplificar a discussão sobre as posições dos blocos de memória, foi introduzido
um esquema de numeração que inclui prefixos ao endereço dos dados em questão.
Por exemplo, em vez de se referir a um item como registrador holding 14 no endereço 13, o
manual do dispositivo pode se referir a um item de dados no endereço 4.014, 40.014 ou 400.014.
Em todos esses casos, o primeiro número especificado é 4, que representa os registradores
holding; os demais números especificam um endereço. A diferença entre 4XXX, 4XXXX e
4XXXXX depende do espaço de endereços utilizado pelo dispositivo. Se todos os 65.536
registradores estiverem em uso, utilizaremos a notação 4XXXXX, pois ela permite o uso da faixa
de 400.001 a 465.536. Se apenas alguns registradores forem usados, uma prática comum é usar
a faixa de 4.001 a 4.999.
Nesse esquema de endereçamento, cada tipo de dados recebe um prefixo, como mostrado no
quadro abaixo
Coils utilizam o prefixo 0. Isso significa que a referência 4001 pode se referir ao registrador
holding 1 ou ao coil 4001. Por esse motivo, é recomendado que todas as implementações novas
utilizem o endereçamento de 6 dígitos com zeros na frente. Essa informação deverá ser anotada
na documentação. Dessa forma, o registrador holding 1 é referenciado como 400.001 e o coil
4001 é referenciado como 004.001
Faixas indexadas em 1 são muito usadas e altamente recomendadas. De qualquer forma, o valor
inicial de cada faixa sempre deverá ser indicado na documentação.
Tipos de dados para grandes valores
O padrão Modbus oferece um modelo de dados relativamente simples, que não inclui
outros tipos de dados além do valor do bit e palavra não sinalizada. Esses valores podem ser
suficientes para alguns sistemas, nos quais os valores de bit correspondem a solenóides e relés e
os valores das palavras correspondem a valores ADC sem escala, mas não para sistemas
avançados. Como resultado, muitas implementações do Modbus incluem tipos de dados que vão
além das fronteiras do registrador. O módulo LabVIEW Datalogging and Supervisory Control
(DSC) e o KEPServerEX definem alguns tipos de referência. Por exemplo, as strings
armazenadas em um registrador holding seguem o formato padrão (400.001), mas são seguidas
por um decimal, o comprimento e o byte que ordena a string (400.001.2H, uma string de 2
caracteres no registrador holding 1, onde o byte em nível alto corresponde ao primeiro caractere
da string). Isso é necessário porque cada requisição tem tamanho finito; dessa forma, o mestre
Modbus precisa saber exatamente onde a string começa e termina, em vez de procurar por um
comprimento fixo ou delimitador, como o NULL.
Acesso a bit
Além de permitir acesso a dados que vão além das fronteira do registrador, alguns mestres
Modbus permitem o uso de referências a bits individuais dentro de um registrador. Com isso, os
dispositivos podem combinar dados de todos os tipos em uma mesma faixa de memória sem ter
de separar dados binários no coil e faixas de entrada discretas. Normalmente, esse recurso é
indicado pelo uso de um ponto decimal e o índice de bit ou número, dependendo da
implementação. Ou seja, o primeiro bit do primeiro registrador pode ser 400.001.00 ou
400.001.01. É recomendado que toda documentação especifique o esquema de indexação
utilizado.
Configuração endian dos dados
Os dados de múltiplos registros, como valores de ponto flutuante de precisão única, podem
ser facilmente transferidos ao Modbus, com a separação dos dados em dois registradores. Como
isso não é definido pelo padrão, a ordem de bit (endian) utilizada nessa separação também não
está definida. Cada palavra não sinalizada deve ser enviada na ordem de bit usada pela rede (big
endian) para satisfazer o padrão, mas muitos dispositivos invertem a ordem de bytes no caso de
dados formados por vários bytes. A figura 2 mostra um exemplo incomum, mas válido, dessa
implantação.
Códigos de função
A PDU é formada por um código de função de 1 byte seguido por até 252 bytes de dados de
função.
O código de função é o primeiro item a ser validado. Se o código de função não for
reconhecido pelo dispositivo que recebe a requisição, ele responderá com uma exceção. Se o
código de função for aceito, o dispositivo escravo começará a decompor os dados conforme a
definição da função.
Como o tamanho do pacote é limitado a 254 bytes, os dispositivos são limitados com relação à
quantidade de dados que pode ser transferida. Os códigos de função mais comuns podem
transferir entre 240 e 250 bytes de dados do modelo de dados do escravo, dependendo do
código.
Execução da função pelo escravo
Conforme definido pelo modelo de dados, diferentes funções são definidas para acessar
diferentes blocos conceituais de dados. Uma implementação muito usada faz os códigos
acessarem posições estáticas de memória, mas outros comportamentos podem ser usados. Por
exemplo, código de função 1 (ler coils) e 3 (ler registradores holding) podem acessar a mesma
posição física na memória. Por outro lado, o código de função 3 (ler registradores holding) e 16
(escrever em registradores holding) podem acessar posições de memória completamente
diferentes. Dessa forma, a execução de cada código de função é melhor considerada como parte
da definição do modelo de dados do escravo.
Códigos da classe 0
Os códigos de função da classe 1 compreendem outros códigos necessários para acessar todos
os tipos do modelo de dados. Na definição original, essa lista incluía o código de função 7 (ler
exceção). Entretanto, esse código é definido pela especificação atual como código somente
serial.
Códigos da classe 2
Os códigos de função da classe 2 são funções mais especializadas, implementadas com menor
frequência. Por exemplo, Read/Write Multiple Registers pode ajudar a reduzir a quantidade total
de ciclos de requisição-resposta, mas o comportamento ainda pode ser implementado com
códigos de classe 0.
Interface encapsulada do Modbus
O código de interface encapsulada do Modbus (MEI), função 43, é usado para encapsular
outros dados dentro de um pacote Modbus. Até o momento, há dois números de MEI disponíveis,
13 (CANopen) e 14 (Device Identification).
A função 43/14 (Device Identification) é útil por permitir a transferência de até 256 objetos
exclusivos. Alguns desses objetos são pré-definidos e reservados, como nome do fornecedor e
código do produto, mas aplicações podem definir outros objetos a serem transferidos como
conjuntos de dados genéricos.
Os escravos usam exceções para indicar diversas condições problemáticas, de requisições mal
formadas a entradas incorretas. Entretanto, as exceções podem também ser geradas como
resposta no nível da aplicação a uma requisição inválida. Os escravos não respondem a
requisições emitidas com uma exceção. Nesses casos, o escravo ignora uma requisição
incompleta ou corrompida e começa a esperar pela chegada de uma nova mensagem.
No padrão, os quatro códigos de exceção mais comuns são 01, 02, 03 e 04. Esses códigos são
mostrados no quadro 7, com os significados padrão para cada função.
Além das funções definidas no núcleo da PDU do protocolo Modbus, você pode usar
diversos protocolos de rede. Os protocolos mais usados são TCP/IP e serial, mas você também
pode usar outros, como o UDP. Para transmitir os dados necessários para o Modbus em todas
essas camadas, o Modbus inclui um conjunto de variantes de ADU feitas especificamente para
cada protocolo de rede.
Recursos comuns
Formatos padrão
Os três formatos padrão para as ADUs são TCP, RTU (unidade de terminal remoto) e
ASCII. As ADUs dos tipos RTU e ASCII são tradicionalmente utilizadas por uma linha serial,
enquanto que o TCP é usado em redes TCP/IP ou UDP/IP modernas.
TCP/IP
As ADUs do tipo TCP são formadas pelo cabeçalho do Modbus Application Protocol (MBAP)
concatenado com a PDU do Modbus. O MBAP é um cabeçalho de uso geral, que depende de
uma camada de rede confiável. O formato dessa ADU, incluindo o header, é mostrado na figura 6.
Os campos de dados do cabeçalho indicam seu uso. Em primeiro lugar, ele contém um
identificador de transações. Esse é um recurso valioso em uma rede que pode ter várias
requisições em processamento simultaneamente. Com isso, por exemplo, um mestre pode enviar
requisições 1, 2 e 3. Em algum ponto posteriormente, um escravo pode responder na ordem 2, 1,
3. Nesse caso, o mestre pode combinar as requisições com suas respostas e interpretar os dados
corretamente. Esse é um recurso útil para redes Ethernet.
O identificador do protocolo normalmente é zero, mas você pode usá-lo para expandir o
comportamento do protocolo. O campo Length é usado pelo protocolo para delinear o
comprimento do restante do pacote. A posição desse elemento também indica a dependência
desse formato do cabeçalho em uma camada de rede confiável. Como os pacotes TCP possuem
verificação de erro incorporada e garantem a coerência e entrega dos dados, o comprimento do
pacote pode estar localizado em qualquer parte do cabeçalho. Em uma rede inerentemente
menos confiável, como uma rede serial, um pacote pode ser perdido. Nesse caso, mesmo que
um feixe de dados lido pela aplicação incluísse informações válidas de transação e protocolo, a
informação corrompida de comprimento tornaria o cabeçalho inválido. O TCP oferece um
razoável grau de proteção contra essa situação.
Para finalizar, a ADU contém uma PDU. O comprimento dessa PDU é ainda limitado a 253 bytes
no protocolo padrão.
RTU
A ADU da RTU parece ser muito mais simples, como mostrado na figura 7.
Diferentemente da ADU mais complexa do TCP/IP, essa ADU contém apenas duas partes de
informação além da PDU base. Em primeiro lugar, um endereço é usado para definir a qual
escravo a PDU é destinada. Na maior parte das redes, o endereço 0 é o endereço de "difusão".
Isso significa que se um mestre enviar um comando ao endereço 0, todos os escravos deverão
processar a requisição, mas nenhum deles deverá responder. Além desse endereço, um CRC é
usado para garantir a integridade dos dados.
Entretanto, nas implementações mais modernas a realidade está muito longe de ser simples. O
pacote é delimitado por um par de intervalos de silêncio — ou seja, períodos nos quais não há
comunicação no barramento. Para a taxa de bauds de 9.600, esse intervalo é de
aproximadamente 4 ms. O padrão define um intervalo de silêncio mínimo, independente da taxa
de bauds, um pouco menor que 2 ms.
Em primeiro lugar, isso traz uma desvantagem ao desempenho, pois o dispositivo precisa esperar
o término desse tempo de guarda antes de processar o pacote. Um problema maior, entretanto,
foi o surgimento de outras tecnologias utilizadas em transferências seriais e taxas de baud muito
maiores do que as existentes quando o padrão foi lançado. Ao utilizar um cabo de conversão
USB-serial, por exemplo, você não tem controle sobre o empacotamento e transferência dos
dados. Testes mostram que usar um cabo USB-serial com o driver NI-VISA introduz grandes
lacunas de tamanho variável no feixe de dados, e essas lacunas — períodos de silêncio —
confundem o código que segue a especificação, fazendo-o acreditar que a mensagem foi
concluída. Como a mensagem não está completa, isso normalmente leva a um CRC inválido e à
interpretação pelo dispositivo de que a ADU foi corrompida.
Um método muito usado para tratar desses problemas é separar a camada de abstração entre a
PDU do Modbus e a camada de rede. Com isso, o código serial interroga o pacote da PDU do
Modbus para determinar o código de função. Em conjunto com outros dados no pacote, o
comprimento do pacote restante pode ser descoberto e utilizado para determinar o final do
pacote. Tendo essa informação, é possível usar um tempo de timeout muito maior, permitindo
lacunas na transmissão, e o polling da aplicação pode ocorrer muito mais lentamente. Esse
mecanismo é recomendado para novos desenvolvimentos. Caso o seu código não empregue
esse mecanismo, você poderá ter uma quantidade de pacotes "corrompidos" maior que a
esperada.
ASCII
A ADU do ASCII é mais complexa que a RTU mostrada na figura 8, mas também evita muitos dos
problemas do pacote de RTU. Entretanto, ela tem suas próprias desvantagens.
ADU do ASCII
Para resolver o problema da determinação do tamanho do pacote, a ADU do ASCII tem início e
fim únicos e bem definidos para cada pacote. Cada pacote é iniciado por ":" e é encerrado com os
caracteres CR (carriage return) e LF (line feed). Além disso, APIs seriais como NI-VISA e o .NET
Framework SerialPort Class podem facilmente ler dados em um buffer até que um caractere
específico — como CR/LR — seja recebido. Essas características tornam mais fácil processar a
transmissão de dados na linha serial de maneira eficiente nos modernos códigos das aplicações.
A desvantagem da ADU de ASCII é que todos os dados são transferidos como caracteres
hexadecimais codificados em ASCII. Isso significa que em vez de enviar um único byte para o
código de função 3, 0x03, ela envia os caracteres ASCII “0” e “3”, ou 0x30/0x33. Isso facilita a
leitura do protocolo por um ser humano, mas isso também significa ser necessário transferir o
dobro dos dados pela rede serial, além disso, as aplicações de envio e recepção devem ser
capazes de interpretar os valores ASCII.
Extensão do Modbus
O Modbus é um padrão relativamente simples e aberto, que pode ser modificado conforme
as necessidades de uma determinada aplicação. Esse é o protocolo mais usado na comunicação
entre uma IHM e CLP ou CPA, pois essa é uma situação na qual uma única organização controla
as duas pontas do protocolo. Os desenvolvedores de sensores, por exemplo, têm maior
probabilidade de aderir ao padrão escrito, porque eles tipicamente somente controlam a
implementação de seus escravos, e a interoperabilidade é desejável.
De forma geral, não é recomendável modificar o protocolo. Esta seção é simplesmente fornecida
como um reconhecimento dos mecanismos que outros já usaram para ajustar o comportamento
do protocolo.
Novos códigos de função
Alguns códigos de função estão definidos, mas o padrão Modbus permite que você
desenvolva outros códigos de função. Especificamente os códigos de função de 1 a 64, 73 a 99 e
de 111 a 127 são códigos públicos, reservados e com exclusividade garantida. Os códigos
restantes, de 65 a 72 e 100 a 110 são para uso definido pelo usuário. Com esses códigos
definidos pelo usuário, você pode usar qualquer estrutura de dados. Os dados podem até mesmo
ultrapassar o limite de 253 bytes para a PDU do Modbus, mas toda a aplicação deve ser validada
para garantir que as outras camadas trabalharão como esperado quando a PDU ultrapassar o
limite padrão. Os códigos de função acima de 127 são reservados para respostas a exceções.
Camadas de rede
O Modbus pode ser executado em muitas camadas de rede além de serial e TCP. Uma
implementação potencial é o UDP, por ser adequado ao estilo de comunicação do Modbus. O
Modbus é basicamente um protocolo baseado em mensagem; assim, a capacidade da UDP de
enviar um pacote bem definido de informação sem qualquer informação adicional no nível da
aplicação, como um caractere inicial ou comprimento, torna a implementação do Modbus
extremamente simples. Em vez de exigir uma ADU adicional ou reutilizar uma ADU existente, os
pacotes de PDU do Modbus podem ser enviados pelo uso de uma API de UDP e serem
recebidos totalmente formados na outra extremidade. Embora o TCP seja vantajoso para alguns
protocolos, devido ao seu sistema interno de acknowledgement, o Modbus realiza esse
acknowledgement na camada de aplicação. Entretanto, usar o UDP dessa maneira elimina o
campo de identificador de transação da ADU do TCP, o que impede a possibilidade de haver
diversas transações simultâneas. Assim, o mestre deve ser síncrono ou o pacote do UDP deve
ter um identificador que ajude o mestre a organizar requisições e respostas. Uma sugestão de
implementação seria usar a ADU do TCP/IP em uma camada de rede do UDP.
Modificações da ADU
Para finalizar, uma aplicação pode escolher modificar uma ADU ou usar partes não
utilizadas de uma ADU existente, como o TCP. Por exemplo, o TCP define um campo de 16 bits,
um protocolo de 16 bits e uma Unit ID de 8 bits. Dado que a maior PDU do Modbus tem 253
bytes, o maior byte do comprimento é sempre zero. Para Modbus/TCP, o campo de protocolo e a
Unit ID são sempre zero. Uma extensão simples do protocolo poderia enviar três pacotes
simultaneamente alterando o campo de protocolo para um número diferente de zero e usando os
dois bytes não utilizados (Unit ID e maior byte do campo de comprimento) para o envio dos
comprimentos das duas PDUs adicionais (veja a figura 9).