tools/testing/selftests/rtc/rtctest.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/rtc/rtctest.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/rtc/rtctest.c
Extension
.c
Size
12552 bytes
Lines
510
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/*
 * Real Time Clock Driver Test Program
 *
 * Copyright (c) 2018 Alexandre Belloni <alexandre.belloni@bootlin.com>
 */

#include <errno.h>
#include <fcntl.h>
#include <linux/rtc.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include "kselftest_harness.h"

#define NUM_UIE 3
#define ALARM_DELTA 3
#define READ_LOOP_DURATION_SEC 30
#define READ_LOOP_SLEEP_MS 11

static char *rtc_file = "/dev/rtc0";

enum rtc_alarm_state {
	RTC_ALARM_UNKNOWN,
	RTC_ALARM_ENABLED,
	RTC_ALARM_DISABLED,
	RTC_ALARM_RES_MINUTE,
};

FIXTURE(rtc) {
	int fd;
};

FIXTURE_SETUP(rtc) {
	self->fd = open(rtc_file, O_RDONLY);
}

FIXTURE_TEARDOWN(rtc) {
	close(self->fd);
}

TEST_F(rtc, date_read) {
	int rc;
	struct rtc_time rtc_tm;

	if (self->fd == -1 && errno == ENOENT)
		SKIP(return, "Skipping test since %s does not exist", rtc_file);
	ASSERT_NE(-1, self->fd);

	/* Read the RTC time/date */
	rc = ioctl(self->fd, RTC_RD_TIME, &rtc_tm);
	ASSERT_NE(-1, rc);

	TH_LOG("Current RTC date/time is %02d/%02d/%02d %02d:%02d:%02d.",
	       rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,
	       rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
}

static time_t rtc_time_to_timestamp(struct rtc_time *rtc_time)
{
	struct tm tm_time = {
	       .tm_sec = rtc_time->tm_sec,
	       .tm_min = rtc_time->tm_min,
	       .tm_hour = rtc_time->tm_hour,
	       .tm_mday = rtc_time->tm_mday,
	       .tm_mon = rtc_time->tm_mon,
	       .tm_year = rtc_time->tm_year,
	};

	return mktime(&tm_time);
}

static void nanosleep_with_retries(long ns)
{
	struct timespec req = {
		.tv_sec = 0,
		.tv_nsec = ns,
	};
	struct timespec rem;

	while (nanosleep(&req, &rem) != 0) {
		req.tv_sec = rem.tv_sec;
		req.tv_nsec = rem.tv_nsec;
	}
}

Annotation

Implementation Notes