Guia Técnico: Implementação e Configuração de RTC no Linux (Sunxi)

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 em sysfs e procfs.
  • 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

  1. Verifique a fonte de clock ativa. Se for o RC16M interno, espere desvios significativos (até 50%) se a calibração não estiver ativa.
  2. 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)

  1. Confirme se o cristal de 32kHz está oscilando corretamente. Nota: Pontas de prova capacitivas podem induzir a oscilação em cristais instáveis.
  2. 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.
  3. Use o comando memtool ou devmem para realizar o dump dos registradores e validar o estado dos bits de controle de energia.

Tags: Linux Kernel RTC Driver Allwinner Sunxi Device Tree Embedded C

Publicado em 7-7 19:37