Precision Time Protocol (PTP) e como usá-lo com Python
Criado por

Precision Time Protocol (PTP) e como usá‑lo com Python

1. Introdução

Este post não pretende ser uma implementação do protocolo PTP nem ser uma explicação exaustiva do PTP. Em vez disso, vamos explorar como podemos recolher e utilizar a hora sincronizada através do Precision Time Protocol em Python, tirando partido da infraestrutura PTP já existente (por exemplo, através de ptp4l e phc2sys).

2. O que é o PTP?

O Precision Time Protocol (PTP)[i], definido originalmente pelo IEEE[ii] (IEEE1588-2002[iii]), é um protocolo de sincronização de relógios concebido para redes informáticas.
Ao contrário do NTP (Network Time Protocol)[iv], que opera a nível de software e tipicamente alcança precisões de milissegundos, o PTP tira partido de “carimbos de tempo” (timestamps) de hardware e da compensação de atrasos na rede para atingir precisões na ordem dos microssegundos ou até nanosegundos (dependendo do hardware e da topologia).

Por exemplo, é usado em:

  • Sistemas financeiros: Para garantir que as transações têm carimbos temporais precisos e rastreáveis.
  • Automação industrial e controlo: Onde processos e robôs necessitam de executar tarefas sincronizadas ao microssegundo.
  • Telecomunicações / 5G: Para sincronizar estações base de redes móveis e reduzir a latência.
  • Sistemas multimédia / áudio sobre IP: O padrão AES67 para áudio profissional sobre IP utiliza PTPv2 para manter relógios sincronizados entre dispositivos.
  • Subestações e Automação IEC 61850: O PTP é usado para sincronizar equipamentos como IEDs (Intelligent Electronic Devices), relés de proteção, medidores de sincrofasores e sistemas SCADA. Mais informação nos standrds IEC61850 e IEEE C37.238[v]
  • Redes Inteligentes (Smart Grids): Em sistemas distribuídos com fontes renováveis (solar, eólica), o PTP ajuda a coordenar a geração e distribuição de energia.

Esta base teórica é essencial para compreender como o Precision Time Protocol em Python pode ser usado para integrar dados temporais com elevada precisão.

3. Como o PTP Funciona: A Mecânica

Quando aplicado em software, como no caso do Precision Time Protocol em Python, este processo permite integrar sincronização de hardware de forma eficiente.
O PTP alcança esta precisão através da trocas de mensagens entre o relógio principal (Grand master clock) e os relógios secundários (slave clocks). Eis uma explicação simplificada passo a passo:

3.1. Passo 1: Mensagens de Sincronização
  • O relógio principal envia periodicamente mensagens Sync, que incluem a hora exacta (timestamp) do momento em que foram enviadas (t1).
  • O relógio secundário regista o instante em que recebe essa mensagem (t2).

Nota: Em alguns equipamentos, o timestamp exato do envio só é conhecido depois de a mensagem sair da interface de rede. Nestes casos, o PTP utiliza uma segunda mensagem, chamada “de seguimento” (Follow_Up), que transmite ao relógio secundário o timestamp preciso da mensagem de Sync.
Existem dois modos de operação:

  • Two-step: envia-se o Sync seguido da mensagem de Follow_Up (quando o timestamp não pode ser inserido diretamente no Sync).
  • One-step: o timestamp final é inserido no próprio Sync (não há Follow_Up).

NOTA: Para simplificação, neste post consideraremos o modo one-step.

3.2. Passo 2: Pedido e Resposta de Atraso
  • O relógio secundário envia uma mensagem “pedido de atraso” (Delay Request) ao relógio principal, solicitando o instante exato em que esta mensagem é recebida.
  • O relógio principal responde com uma mensagem “resposta ao pedido de atraso” (Delay Response), contendo o timestamp t4 (momento em que recebeu o pedido).

Estes valores permitem medir o tempo de ida e volta da comunicação e ajustar o relógio.

3.3. Passo 3: Ajuste do Relógio
  • O relógio secundário calcula o offset (diferença entre o seu relógio e o relógio principal), considerando os atrasos da rede, e ajusta‑se para alinhar com o relógio principal.

Este processo repete-se várias vezes, por defeito, 125 vezes por minuto.

Por curiosidade, as mensagens têm um tamanho de 44-64 bytes havendo algumas com valores maiores mas utilizando valores habituais, sync a cada 125ms, folow up também,  pedidos de atraso de resposta e anuncios a cada 1s, estamos a falar de 9,6Kb/s. Nota: Em redes maiores o volume de tráfego pode aumentar e não foi considerado.

Tem outros modos de operação mas costuma correr em UPD, em Layer 2, para ser o mais leve, rapido e sem estado.

3.3.1 Como é calculado o ajuste?

O offset é calculado como:

Offset = ((t2 − t1) − (t4 − t3)) / 2

  • t2 − t1: tempo de viagem da mensagem Sync (relógio principal → relógio secundário)
  • t4 − t3: tempo de viagem da mensagem Delay Request (relógio secundário → relógio principal)

A diferença entre esses valores dá a assimetria de ida e volta, o que a dividir por 2 estima o atraso de ida (one‑way delay).

Exemplo prático

Assumindo os seguintes tempos:

  • t1 = 10,000000000 s (Sync enviado pelo relógio principal)
  • t2 = 10,000000020 s (Sync recebido pelo relógio secundário)
  • t3 = 10,500000000 s (Delay Request enviado pelo relógio secundário)
  • t4 = 10,500000015 s (Delay Request recebido pelo relógio principal)

Passo 1: Calcular os termos da fórmula:

  • t2 − t1 = 0,000000020 s
  • t4 − t3 = 0,000000015 s

Passo 2: Calcular o offset
Offset = ((0,000000020 − 0,000000015)) / 2 = 0,0000000025 s

Resultado:
O relógio secundário está 2,5ns adiantado em relação ao relógio principal. Ele ajusta‑se “atrasando‑se” 2,5 ns para ficar sincronizado. (sobre simplificação do processo)

4. E as versões do protocolo? (PTPv1 vs PTPv2)

O que descrevemos acima corresponde à mecânica base, que é comum às duas versões (IEEE 1588‑2002 e IEEE 1588‑2008). No entanto, o PTPv2 trouxe melhorias significativas:

  • Mensagens adicionais: PTPv2 introduziu mensagens como Announce (para eleição do relógio principal) e Signaling (para funcionalidades avançadas).
  • Perfis específicos: A versao 2 define perfis padronizados (power profiles) (ex.: IEC 61850‑9‑3 para redes elétricas e IEEE C37.238 para sistemas de energia), com parâmetros de operação restritos.
  • Maior precisão: Melhor suporte a hardware timestamping e redução de variações de atraso.
  • Escalabilidade: Reformulação das estruturas de mensagens para facilitar a interoperabilidade em redes maiores.

Conclusão: A mecânica de sincronização (Sync, Follow_Up, Delay Request e Delay Response) mantém-se em ambas as versões, mas o PTPv2 amplia a robustez e o alcance do protocolo, sendo hoje o mais utilizado.

5. NTP vs PTP

Embora tanto o NTP como o PTP sirvam para sincronização de relógios em sistemas distribuídos, eles têm objetivos, requisitos e complexidades diferentes.

Critério PTP (Precision Time Protocol) NTP (Network Time Protocol)
Precisão Nanosegundos (sub-microsegundos em LAN) Milissegundos
Suporte de Hardware Requer timestamping dedicado (placas de rede, switches especificos) Funciona apenas com software
Casos de Uso Aplicações críticas: 5G, sistemas financeiros, energia Sincronização geral: servidores, PCs, redes domésticas
Sobrecarga de Rede Mais mensagens e gestão (Sync, Follow_Up, etc.) Menor custo de rede, menos mensagens
Complexidade Exige configuração detalhada e hardware compatível Simples de implementar e manter

O porquê da precisão?

Muitos outros exemplos poderiam ser apresentados mas fica a curiosidade

  1. Distância percorrida por um avião a 900km/h
    Um Airbus típico voa a cerca de 250 m/s. Em 1 ns percorre ~0,00025 mm; em 1ms percorre ~25 cm. Um caso típico para o NTP. Mas e se fosse para calcular a velocidade de para um recorde do guiness ou “photo finish”?
  2. Resolução de um radar altímetro
    Um radar mede distâncias com base no tempo de ida e volta do sinal (velocidade da luz). Em 1ns consegue distinguir ~15 cm; em 1 ms a resolução degrada‑se para 150 km.

… Sistemas de navegação por satélite (GNSS), Sistemas de controlo distribuído em fábricas, Infraestruturas críticas (ex. semáforos inteligentes, controlo ferroviário), Redes TSN (Time-Sensitive Networking), Veículos autónomos e ADAS (Advanced Driver Assistance Systems) para fusao de dados e tomada de decisoes em tempo real…

6. Comparação de mensagens do PTP vs NTP

Uma diferença essencial entre PTP e NTP está no número e tipo de mensagens trocadas para atingir a sincronização:

  • NTP: Utiliza um fluxo simples de 2 mensagens:
    • Request: O cliente envia um pedido ao servidor com o timestamp local (t1).
    • Response: O servidor responde com o timestamp de envio (t4) e os seus próprios timestamps (t2, t3).
  • PTP: É mais complexo e usa múltiplas mensagens (especialmente no modo unicast), permitindo maior precisão:
    • Announce: Permite ao relógio secundário conhecer e eleger o relógio principal.
    • Sync e Follow_Up (quando necessário): Fornecem timestamps precisos do relógio principal.
    • Delay Request / Response: Calculam o atraso de ida e volta da rede.

Isto significa que, enquanto o NTP é mais leve e simples, o PTP troca mais mensagens para compensar atrasos assimétricos e garantir precisão na ordem dos microssegundos e eventualmente nanosegundos.

Fonte: Meinberg Global Blog

7. PTP e Segurança

Nem todos os protocolos de segurança exigem precisão extrema. Por exemplo, TOTP (Time‑based One‑Time Password) baseia‑se em janelas de 30 s, para as quais o NTP é suficiente.

Mas o PTP é essencial em:

  • Registos/Logs regulamentares e assinaturas digitais (MiFID II, SEC Rule 613): timestamps sub‑milissegundo para rastrear a ordem de eventos.
  • Redes industriais e elétricas (IEC 61850‑9‑3, IEEE C37.238): sincronização de medições e eventos em subestações.
  • Correlação de eventos em SIEMs: análise forense precisa em ambientes distribuídos.
  • Criptografia avançada e QKD: troca de chaves com requisitos temporais extremamente rigorosos.

Em sistemas de gestão e decisão, como um Sistema de Informação para a Direção (SID), a fiabilidade depende de dados precisos e coerentes. O Precision Time Protocol em Python garante que registos e eventos possuem marca temporal exata, algo crítico para análises e auditorias.

8. Usar PTP com Python

8.1. O que não é prático fazer em Python com PTP

Embora o Python seja excelente para monitorizar e integrar sistemas, há operações do PTP que não são viáveis implementar diretamente:

  • Atuar como relógio principal ou secundário completo: Implementar toda a pilha do IEEE 1588 em Python não é prático.
    Uma operação típica em Python pode levar dezenas a centenas de microssegundos.
    Em C/C++ reduz‑se para poucos microssegundos, e ao nível de kernel (timestamping de hardware) para nanosegundos.
  • Enviar ou receber tramas PTP a nível de camada 2 ou usar timestamping de hardware: Estas operações requerem acesso ao kernel e suporte específico das placas de rede.
8.2. Recomendações:
  • Use ferramentas como ptp4l ou chronyd para a sincronização PTP.
  • Use Python para monitorizar, analisar logs ou integrar com outras ferramentas.

9. Exemplos práticos com Python

Estes exemplos mostram como o Precision Time Protocol em Python e abordagens como a sincronização PTP em Python podem ser aplicados em cenários reais.

9.1. Ler a hora do sistema (sincronizada por PTP)

import datetime

now = datetime.datetime.now(datetime.timezone.utc)

print(“Hora atual (UTC):”, now.strftime(“%Y-%m-%d %H:%M:%S.%f”))

Não é necessário que o Python tenha suporte direto para PTP — ele apenas lê o tempo que o sistema já sincronizou.

Se quiser confirmar que o sistema está a usar PTP corretamente pode-se usar:
sudo ptp4l -m ou verificar o estado com: pmc -u -b 0 'GET CURRENT_DATA_SET'

9.2. Ler diretamente o relógio PTP (/dev/ptp0)

Informação: Importar as bibliotecas para processar chamadas de sistema (ctypes), acesso a dispositivos (OS) e manipulação de tempo (datetime).

# Este bloco Importar as bibliotecas para processar chamadas de sistema (ctypes),
# acesso a dispositivos (OS) e manipulação de tempo (datetime).

import ctypes
import os
from datetime import datetime, timezone

# Este bloco define uma estrutura C chamada timespec, usada para armazenar tempo em segundos
# e nanossegundos (como no clock_gettime do Linux).

class timespec(ctypes.Structure):
_fields_ = [(“tv_sec”, ctypes.c_long), (“tv_nsec”, ctypes.c_long)]

# Este por sua vez
# – Carrega a biblioteca librt que contém clock_gettime.
# – Abre o dispositivo /dev/ptp0, que representa o relógio de hardware sincronizado via PTP.
# – Calcula o identificador do relógio (CLOCK_PTP) usando um truque com CLOCKFD.

librt = ctypes.CDLL(“librt.so.1”, use_errno=True)
fd = os.open(“/dev/ptp0”, os.O_RDONLY)

CLOCKFD = 3 << 3
CLOCK_PTP = CLOCKFD | fd

# Segue-se a chamada clock_gettime para obter o tempo diretamente do relógio PTP.

ts = timespec()
librt.clock_gettime(CLOCK_PTP, ctypes.byref(ts))

# por fim converte o tempo obtido para um objeto datetime e imprime com precisão até aos nanossegundos.

dt = datetime.fromtimestamp(ts.tv_sec + ts.tv_nsec / 1e9, tz=timezone.utc)

print(f”PTP Clock: {dt.strftime(‘%Y-%m-%d %H:%M:%S’)}”)
print(f”Microsegundos: {int(ts.tv_nsec/1000)}”)

print(f”Nanosegundos: {ts.tv_nsec}”)

9.3. Ler o estado do ptp4l via pmc

def get_ptp_status():
try:
# Executa o comando pmc:
# -u: usa o modo Unix domain socket
# -b 0: usa a porta padrão
# “GET CURRENT_DATA_SET”: obtém dados do estado atual

output = subprocess.check_output(
[“pmc”, “-u”, “-b”, “0”, “GET CURRENT_DATA_SET”],
stderr=subprocess.STDOUT,
text=True
)

return output

except subprocess.CalledProcessError as e:
return f”Erro ao obter estado do PTP: {e.output}”

Exemplo de uso

status = get_ptp_status()
print(status)

O que faz:

  • Usa o pmc para enviar o comando GET CURRENT_DATA_SET ao ptp4l.
  • Devolve o estado atual do PTP: offset, delay médio, variância, frequência, entre outros.

Exemplo de saída:

sending: GET CURRENT_DATA_SET

84 (CURRENT_DATA_SET) offsetFromMaster -12 s0 freq 0 path_delay 123

9.4. Monitorizar o offset do PTP (via logs)

Abre o ficheiro de log do daemon ptp4l, que normalmente contém mensagens sobre a sincronização PTP.

Usa o contexto with, que garante que o ficheiro será fechado automaticamente após a leitura.

Itera/percorre linha a linha pelo conteúdo do ficheiro.

Verifica se a linha contém a palavra “offset”, que normalmente aparece em mensagens que indicam

a diferença entre o relógio local e o relógio mestre PTP e imprime-as

with open(“/var/log/ptp4l.log”) as log:
for line in log:
if “offset” in line:
print(line.strip())
9.5. Ler offsets diretamente dos logs do ptp4l (mais detalhado do ponto anterior)

def get_ptp_offsets(log_path=”/var/log/ptp4l.log”, max_lines=20):
# Lê as últimas linhas do log do ptp4l e extrai offsets.

offsets = []

with open(log_path, “r”) as log:
# Lê apenas as últimas N linhas (por eficiência)
lines = log.readlines()[-max_lines:]

for line in lines:
# Filtra linhas que contêm “offset”
if “offset” in line:
offsets.append(line.strip())

return offsets

Exemplo de uso

for entry in get_ptp_offsets():
print(entry)

O que faz:

  • Abre o log do ptp4l (por padrão, /var/log/ptp4l.log).
  • Lê apenas as últimas max_lines linhas para eficiência.
  • Filtra e devolve apenas as que contêm “offset”, mostrando a evolução da sincronização.

Exemplo de saída:

ptp4l[123.456]: rms 12 max 24 freq +0 +/- 1 delay 123 offset -15
ptp4l[124.789]: rms 10 max 20 freq +0 +/- 1 delay 125 offset -12
9.6. Comandos úteis do pmc
Comando Descrição
GET CURRENT_DATA_SET Estado atual do PTP (offset, delay, freq).
GET PARENT_DATA_SET Informação sobre o relógio principal atual.
GET TIME_STATUS_NP Estado geral de tempo e sincronização.
GET PORT_DATA_SET Informação das portas PTP (estado, estatísticas).

10. Conclusão

O Precision Time Protocol em Python é essencial quando a precisão temporal é crítica. Ao combinar sincronização PTP com Python, é possível criar soluções robustas para monitorização e integração. Esta abordagem oferece versatilidade para aplicações que vão desde redes industriais até sistemas financeiros e telecomunicações.

[i] https://pt.wikipedia.org/wiki/Precision_Time_Protocol / https://en.wikipedia.org/wiki/Precision_Time_Protocol

[ii] IEEE – https://www.ieee.org/ em portugal: https://ieee-pt.org/

[iii] PTPv1- https://standards.ieee.org/ieee/1588/3140/ (2002)

PTPv2 – https://standards.ieee.org/ieee/1588/4355/ (2008)

Actualizado em – https://standards.ieee.org/ieee/1588/6825 (2019)

[iv] David L. Mills (12 de dezembro de 2010). Computer Network Time Synchronization: The Network Time Protocol. [S.l.]: Taylor & Francis. pp. 12–. ISBN 978-0-8493-5805-0.

[v] SINCRONIZAÇÃO TEMPORAL DE EQUIPAMENTOS USANDO REDE ETHERNET – ANÁLISE DO ESTADO DA ARTE – https://www.researchgate.net/publication/270566616_SINCRONIZACAO_TEMPORAL_DE_EQUIPAMENTOS_USANDO_REDE_ETHERNET_-_ANALISE_DO_ESTADO_DA_ARTE

Subscreva a nossa Newsletter

Receba todas as novidades GTI na sua caixa de correio eletrónico