181 lines
5.4 KiB
ReStructuredText
181 lines
5.4 KiB
ReStructuredText
==================
|
|
libs/libc/zoneinfo
|
|
==================
|
|
|
|
Author: Gregory Nutt <gnutt@nuttx.org>
|
|
|
|
Directory Contents
|
|
==================
|
|
|
|
This directory contains logic to create a version of the TZ/Olson database.
|
|
This database is required if localtime() support is selected via
|
|
CONFIG_LIBC_LOCALTIME. This logic in this directory does the following:
|
|
|
|
- It downloads the current TZ database from the IANA website
|
|
- It downloads the current timezone tools from the same location
|
|
- It builds the tools and constructs the binary TZ database
|
|
- It will then, optionally, build a ROMFS filesystem image containing
|
|
the data base.
|
|
|
|
Creating and Mounting a ROMFS TZ Database
|
|
=========================================
|
|
|
|
The ROMFS filesystem image can that be mounted during the boot-up sequence
|
|
so that it is available for the localtime() logic. There are two steps to
|
|
doing this:
|
|
|
|
- First, a ROM disk device must be created. This is done by calling
|
|
the function romdisk_register() as described in
|
|
nuttx/include/nuttx/drivers/ramdisk.h. This is an OS level operation
|
|
and must be done in the board-level logic before your application
|
|
starts.
|
|
|
|
romdisk_register() will create a block driver at /dev/ramN where N
|
|
is the device minor number that was provided to romdisk_register.
|
|
|
|
- The second step is to mount the file system. This step can be
|
|
performed either in your board configuration logic or by your
|
|
application using the mount() interface described in
|
|
nuttx/include/sys/mount.h.
|
|
|
|
These steps, however, must be done very early in initialization,
|
|
before there is any need for time-related services.
|
|
|
|
Both of these steps are shown together in the following code sample at the
|
|
end of this page.
|
|
|
|
Example Configuration
|
|
=====================
|
|
|
|
I have tested this using the sim/nsh configuration. Here are the
|
|
modifications to the configuration that I used for testing::
|
|
|
|
CONFIG_BOARD_LATE_INITIALIZE=y
|
|
|
|
CONFIG_LIBC_LOCALTIME=y
|
|
CONFIG_LIBC_TZDIR="/share/zoneinfo"
|
|
CONFIG_LIBC_TZ_MAX_TIMES=370
|
|
CONFIG_LIBC_TZ_MAX_TYPES=20
|
|
|
|
CONFIG_LIBC_ZONEINFO=y
|
|
CONFIG_LIBC_ZONEINFO_ROMFS=y
|
|
|
|
NOTE: The full TZ database is quite large. To create a reasonable sized
|
|
ROMFS image, I had to trim some of the files like this::
|
|
|
|
cd nuttx
|
|
tools/configure.sh sim:nsh
|
|
make menuconfig
|
|
|
|
Select the above localtime() and nuttx/zoneinfo configuration settings.
|
|
Then::
|
|
|
|
make context
|
|
cd ../nuttx/libs/libc/zoneinfo/tzbin/usr/share/zoneinfo
|
|
|
|
Remove as many timezone files as you can. Do not remove the GMT, localtime,
|
|
or posixrules files. Those might be needed in any event. Then you can
|
|
force rebuilding of the ROMFS filesystem be removing some files::
|
|
|
|
cd ../../..
|
|
rm romfs_zoneinfo.*
|
|
rm *.o
|
|
cd ../../nuttx
|
|
make
|
|
|
|
If you have problems building the simulator on your platform, check out
|
|
:doc:`/platforms/sim/sim/boards/sim/index`.
|
|
You might find some help there.
|
|
|
|
Here is a sample run. I have not seen any errors in single stepping through
|
|
the logic but neither am I certain that everything is working properly::
|
|
|
|
NuttShell (NSH)
|
|
nsh> date
|
|
Jul 01 00:00:02 2008
|
|
nsh> set TZ US/Mountain
|
|
nsh> date -s "Apr 11 11:53:00 2015"
|
|
nsh> date
|
|
Apr 11 17:53:00 2015
|
|
|
|
NOTE: Because of daylight savings time, US/Mountain is GMT-6 on Apr 11. The
|
|
above suggests that perhaps the NSH data command may be setting local time,
|
|
but printing GMT time?
|
|
|
|
Sample Code to Mount the ROMFS Filesystem
|
|
=========================================
|
|
|
|
.. code-block:: C
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <nuttx/config.h>
|
|
|
|
#include <sys/mount.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
|
|
#include <nuttx/drivers/ramdisk.h>
|
|
#include <nuttx/zoneinfo.h>
|
|
|
|
/****************************************************************************
|
|
* Pre-processor Definitions
|
|
****************************************************************************/
|
|
|
|
#ifndef CONFIG_LIBC_TZDIR
|
|
# error CONFIG_LIBC_TZDIR is not defined
|
|
#endif
|
|
|
|
#ifdef CONFIG_DISABLE_MOUNTPOINT
|
|
# error "Mountpoint support is disabled"
|
|
#endif
|
|
|
|
#ifndef CONFIG_FS_ROMFS
|
|
# error "ROMFS support not enabled"
|
|
#endif
|
|
|
|
#define SECTORSIZE 64
|
|
#define NSECTORS(b) (((b)+SECTORSIZE-1)/SECTORSIZE)
|
|
|
|
/****************************************************************************
|
|
* Public Functions
|
|
****************************************************************************/
|
|
|
|
int mount_zoneinfo(int minor)
|
|
{
|
|
char devname[32];
|
|
int ret;
|
|
|
|
/* Create a RAM disk for the test */
|
|
|
|
ret = romdisk_register(minor, romfs_zoneinfo_img,
|
|
NSECTORS(romfs_zoneinfo_img_len), SECTORSIZE);
|
|
if (ret < 0)
|
|
{
|
|
printf("ERROR: Failed to create RAM disk\n");
|
|
return ret;
|
|
}
|
|
|
|
/* Use the minor number to create a name for the ROM disk block device */
|
|
|
|
snprintf(devname, 32, "/dev/ram%d", minor);
|
|
|
|
/* Mount the ROMFS file system */
|
|
|
|
printf("Mounting ROMFS filesystem at target=%s with source=%s\n",
|
|
CONFIG_LIBC_TZDIR, devname);
|
|
|
|
ret = mount(devname, CONFIG_LIBC_TZDIR, "romfs", MS_RDONLY, NULL);
|
|
if (ret < 0)
|
|
{
|
|
printf("ERROR: Mount failed: %d\n", errno);
|
|
return ret;
|
|
}
|
|
|
|
printf("TZ database mounted at %s\n", CONFIG_LIBC_TZDIR);
|
|
return OK;
|
|
}
|