Arquitetura do Subsistema RTC no Linux
O subsistema de Real Time Clock (RTC) no kernel Linux é estruturado em três camadas principais que garantem a abstração do hardware para o espaço do usuário:
- Interface do Usuário: Provedora de nós de dispositivo (ex:
/dev/rtc0) e interfaces emsysfseprocfs. - RTC Core: Define a API comum para drivers, gerenciando o registro de dispositivos e a lógica de tradução de tempo.
- Camada de Driver: Implementação específica para o hardware (ex:
rtc-sunxi.c), responsável por manipular registradores para definir hora, data e alarmes.
Estrutura de Arquivos
Depnedendo da versão do kernel (4.9 ou 5.4+), os arquivos fundamentais residem em drivers/rtc/. Os arquivos específicos para plataformas Allwinner são rtc-sunxi.c e rtc-sunxi.h, enquanto o núcleo do subsistema utiliza arquivos como class.c, interface.c e rtc-dev.c.
Configuração do Kernel (Menuconfig)
Kernel 4.9
Para configurar o suporte ao RTC em arquiteturas ARM/ARM64, acesse o menu de configuração:
Device Drivers --->
Real Time Clock --->
<*> Allwinner sunxi RTC
Para suportar funcionalidades como "fake poweroff" e flags de reboot, ative as opções support ir fake poweroff e Sunxi rtc reboot Feature. Isso permite que registradores mantidos por bateria ou capacitores preservem estados durante o reinício.
Kernel 5.4
Utilizando o script de build da plataforma:
./build.sh menuconfig
Navegue até Device Drivers -> Real Time Clock e selecione Allwinner sunxi RTC. Certifique-se de habilitar Sunxi rtc reboot flag e Sunxi rtc general register save bootcount para persistência de contagem de boot e flags de sistema.
Configuração via Device Tree (DTS)
As definições de hardware são divididas entre o arquivo da SoC (.dtsi) e o arquivo da placa (board.dts).
Exemplo de Definição no Kernel 5.4
rtc: rtc@7000000 {
compatible = "allwinner,sun50iw10p1-rtc";
reg = <0x0 0x07000000 0x0 0x200>;
interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&r_ccu CLK_R_AHB_BUS_RTC>, <&rtc_ccu CLK_RTC_1K>;
clock-names = "r-ahb-rtc", "rtc-1k";
resets = <&r_ccu RST_R_AHB_BUS_RTC>;
wakeup-source;
gpr_cur_pos = <6>;
};
No kernel 4.9, o parâmetro auto_switch é fundamental. Se presente, o hardware monitora o oscilador externo de 32kHz; se este falhar, o sistema alterna automaticamente para o clock interno RC16M, garantindo continuidade operacional.
Desenvolvimento de Aplicações (Espaço do Usuário)
A interação com o RTC em C utiliza chamadas de sistema padrão (POSIX) e ioctl.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/rtc.h>
#include <errno.h>
int configurar_calendario_rtc(int fd_rtc) {
struct rtc_time info_tempo = {0};
// Define: 25 de Dezembro de 2023, 14:30:00
info_tempo.tm_year = 2023 - 1900;
info_tempo.tm_mon = 12 - 1;
info_tempo.tm_mday = 25;
info_tempo.tm_hour = 14;
info_tempo.tm_min = 30;
info_tempo.tm_sec = 0;
if (ioctl(fd_rtc, RTC_SET_TIME, &info_tempo) == -1) {
perror("Erro ao definir tempo");
return -1;
}
struct rtc_time leitura;
if (ioctl(fd_rtc, RTC_RD_TIME, &leitura) != -1) {
printf("Hora RTC: %02d/%02d/%04d %02d:%02d:%02d\n",
leitura.tm_mday, leitura.tm_mon + 1, leitura.tm_year + 1900,
leitura.tm_hour, leitura.tm_min, leitura.tm_sec);
}
return 0;
}
int main() {
int fd = open("/dev/rtc0", O_RDWR);
if (fd < 0) return -ENODEV;
configurar_calendario_rtc(fd);
close(fd);
return 0;
}
Resolução de Problemas Comuns
Imprecisão no Tempo
- Verifique a fonte de clock ativa. Se for o RC16M interno, espere desvios significativos (até 50%) se a calibração não estiver ativa.
- Para cristais externos de 32kHz, verifique a carga capacitiva e a frequência real com um osciloscópio.
RTC Estático (Relógio não avança)
- Confirme se o cristal de 32kHz está oscilando corretamente. Nota: Pontas de prova capacitivas podem induzir a oscilação em cristais instáveis.
- Inspecione os registradores de status do RTC. No endereço base da SoC, verifique o registrador de controle (offset 0x0). Se bits de erro de oscilação estiverem setados, o hardware parou por falha de clock.
- Use o comando
memtooloudevmempara realizar o dump dos registradores e validar o estado dos bits de controle de energia.