We have an embedded Linux system where the user needs to be able to permanently set the system's timezone by supplying a POSIX string (e.g. WEuropeStandardTime-1DaylightTime,M3.5.0,M10.5.0/3).
The user interacts with the system over a webservice we develop so we have complete control of the implementation. I'm looking for a C/C++ solution.
I've been looking at timedatectl -set-timezone, but it only accepts Olson timezone descriptions, not POSIX timezone strings. I was thinking I could parse the tzdata to find a match for the POSIZ timezone string, but before starting down that path I'd like to know if there is a better way or if there is already a library to do this conversion.
I've discounted setting the TZ environment variable as it is an override for the system date and time set by timedatectl and it feels like a bodge. Also, I'm not sure how I'd set it early enough that all software running from boot would see the same time.
What you ask is not possible. There is much more information in the data represented behind an IANA (aka "Olson") time zone identifier than can fit in a POSIX time zone string. In particular a POSIX time zone string can only contain one single pair of transition rules. It provides no facilities for tracking how those rules have changed over time or how they might be scheduled to change in the future. It also doesn't provide for cases where the standard time offset has changed, or where there are more than one pair of transitions in a single year. You can read more about this in the section "POSIX style time zones" towards the bottom of the timezone tag wiki.
However, since you said the user interacts with the system over a web service, you might instead consider projecting a POSIX string. The user would pick an IANA time zone for the device (or you could look it up by location), and you'd store that. Then when communicating with the device, you'd generate a POSIX string to deliver for use on the device over a given period. You'd want to periodically update it, perhaps every time the device checks in or is updated (depending on your scenario).
I know of one commercial offering with this capability built-in: the Azure Maps Timezone API. In its responses, you'll see a PosixTz string. (This was added specifically for IoT scenarios.)
Alternatively, you could do this yourself in your own server-side code. The logic is a bit tricky, but it is indeed possible.
If your back end is .NET - you're in luck. My TimeZoneConverter.Posix library can do this for you. For example:
string posix = PosixTimeZone.FromIanaTimeZoneName("Australia/Sydney");
// Result: "AEST-10AEDT,M10.1.0,M4.1.0/3"
If your back end is JavaScript, there's some unsupported code in Moment-Timezone issue #314 that you can leverage or adapt.
If your back end is something else, I'm not aware of readily available solutions. However, you may be able to port the code in either of the above to your platform.
Related
When a company updates a product's embedded C code application firmware (via a bootloader on the microcontroller, or JTAG, etc.), do they normally flash a whole new .hex/.bin file that contains the new features + old software? Therefore, wiping out the old program entirely?
Or is it standard to make partial application updates via separate .hex/.bin files?
I am asking this question because I want to know the best industry practice for releasing different embedded software packages. Ideally it would be nice to be able to flash specific updates for a feature of a project without updating the entire program memory.
For example:
Lets say your project's embedded C software has 3 features:
user input handling
displaying an output
Power supply management
If you had many software versions of each feature and wanted to test combinations of different versions, can you have separate .hex/.bin for each feature that gets flashed onto the MCU?
You can't really update the program partially unless you have designed certain parts of it as position-independent code and then linked those parts starting at fixed addresses. It can be done, but adds extra complexity during design.
Otherwise if you haven't designed your program like this, the machine code will be full of absolute addresses and jump to the wrong places.
The normal way is to update the whole program at once (perhaps minus any bootloader parts present). And optionally update data flash/eeprom separately.
It depend on the OS, architecture and the need of your system.
If all parts are always independent, it is possible to update partially. This would help to reduce the time for update firmware/software.
If the interface between component might change: it is not recommend to use partial update since it might lead to undefine behavior when the interface change. If required, special check need to implement for consistency of interface.
Partial update is used very commonly, but in a different way than the one you have described.
The most common used case is where you have a bootloade+application and only the application is updated.
This approach is suitable when the applications are completely separate from each other.
The case that you are describing implies that each feature need to communicate with each other or with the main application. In this case, it would be way too much trouble to try and separate the features into separate flash regions.
You'd have to give a separate flash segment for each "feature", resulting in gaps (wasted space), while hoping that your feature does not outgrow the allocated space. Additionally, you'd have to worry about how to implement communication between different features, maintaining compatibility etc...
Just link everything together and update everything at once.
I searched for info about this but didn't find anything.
The idea is:
If I code a program in C, or any other languages, what else do I need to do for it to get recognized in BIOS and started by it as a DOS program or just a prompt program?
I got this idea after I booted an flash drive with windows using the ISO and Rufus, which put some code in the flash drive for the BIOS to recognize it and run, so I would like to do the same with a program of mine, for example.
Thanks in advance!
An interesting, but rather challenging exercise!
The BIOS will fetch a specific zone from the boot device, called a master boot record. In a "normal" situation with an OS and one or more partitions, the MBR will need to figure out where to find the OS, load that into memory, and pass control to it. At that time the regular boot sequence starts and somewhat later the OS will be running and be able to interact with you. More detail on the initial activities can be found here
Now, for educational purposes, this is not strictly necessary. You could write an MBR that just reads in a fixed part of the disk (the BIOS has functions that will allow you to read raw sectors off a disk, a disk can be considered as just a bunch of sectors each containing 512 bytes of information) and starts that code. You can find an open source MBR here and basically in any open source OS.
That was the "easy" part, because now you probably want to do something interesting. Unless you want to interact with each part of the hardware yourself, you will have to rely on the services provided by the BIOS to interact with keyboard, screen and disk. The traditionally best source about BIOS services is Ralf Brown's interrupt list.
One specific consideration: your C compiler comes with a standard library, and that library will need a specific OS for many of its operations (eg, to perform output to the screen, it will ask the operating system to perform that output, and the OS will typically use the BIOS or some direct access to the hardware to perform that task). So, in going the route explained above, you will also need to figure out a way to replace these services by some that use the BIOS and nothing more - ie, more or less rewrite the standard library.
In short, to arrive at something usable, you will be writing the essential parts of an operating system...
Actually BIOS is going to be dead in the next two years (INTEL will not support any BIOSes after this date) so you may want to learn UEFI standard. UEFI from v2.4 allows to write and add custom UEFI applications. (BTW the "traditional" BIOS settings on the UEFI computers is often implemented as a custom UEFI App).
Hi I am trying to write a java applet that will get some hard ware info, mac address(which I have done), cpuid motherboard serial number and hard drive serial number. I know I need to use jna to do this. My question is, is there a way in c/c++ to get that information that is not platform dependent? Everything i have seen would work only on windows, and I need it to work on all platforms. I need this information so I can create a unique id of that computer. any help or a point in the right direction would be much appreciated.
My question is, is there a way in c/c++ to get that information that is not platform dependent?
Not possible. Heck, within the same PC market, querying e.g. BIOS version differs from one MB manufacturer/OEM to another. And that if the PC still has BIOS - not the newer EFI.
Sun/SPARCs are notable exception: their H/W has a relatively unique ID, provisioned mainly for inventorial purposes. It is not precisely unique (what brings up another point) as that might infer on privacy and Sun had no choice but to make sure it is not globally unique.
IOW unique identification of the hardware is illegal in many parts of the world, thus no reliable (least portable) method exists to achieve what you want.
I'd say binding to the MAC address should be already good enough. And that information is rather easy to access on pretty much all platforms. As long as your license check would be lenient enough for user to have sufficient time to receive new license key (in case of hardware replacement) there should be few problems.
There's a project called OSHI that aims to do that. It's looking for contributors to write the *nix implementatoin.
Is there a cross platform C API that can be used to get system usage metrics?
I've worked with libstatgrab before. Gets you some pretty useful system statistics for the main Unix-like variants and Windows through Cygwin (supposedly - never tried). Different OS's work so differently - especially when it comes to usage metrics - it may be challenging to get what you want. Even something as simple sounding as "free memory" can be tricky to act on in a cross-platform way. Perhaps if you narrow things down a bit, maybe we can find something.
Unfortunately not.
The C standard is pretty much limited to dynamic allocation, string manipulation, math and text I/O. Once you get beyond that, you need OS APIs which by definition are OS specific and not cross platform.
Depending on the metrics you want to collect, you may want to consider looking at PCP (Performance Co-Pilot). This is an open-source performance framework, originally developed at Silicon Graphics, which collects and collates a vast number of possible metrics from a vast number of sources, and lets you monitor them from anywhere.
Basically PCP would involve adding another 'layer' into your system -- for example, you might monitor a distributed cluster of mixed-OS machines, each with PCP installed locally; a set of 'agents' collect the performance data on each machine, and your code could then use libpcp to collect those metrics as required.
It's hard to say without knowing your exact usage scenario (if you're talking about something running seamlessly on end-users' machines, PCP may not suit but if you want to monitor machines which you control, and are happy to run the PCP service on them, it's an awesome solution).
We use PCP very happily to collect metrics from Windows and Linux boxes, as well as internal metrics from our application, and log them all centrally, report on them, monitor trends, etc.
The good old SNMP provides C libraries for the client and server side. If you prefer something newer you should try Prometheus. They have Node Exporter ready to use and the client libraries for many languages including C.
Also note that PCP (mentioned in Cowan's answer) supports the OpenMetrics standard since version 4, so if you decide to use Prometheus as the metric data collector extending PCP or writing a custom Prometheus client are better solutions that SNMP which also supported by Prometheus through SNMP Exporter, but more difficult to set up due to the way it handles MIBs and authentication.
I am currently working on a project with a requirement that our software must operate until at least 2050. Recently we have run into problems dealing with the Y2.036K "bug" in the NTP protocol and also the Y2.038K bug. Basically, our software must continue to run past these dates with all data recorded using correct time stamps. Given that there is currently no solution to either of these bugs a workaround must be employed.
It is critical that our software keeps running after these two events and records dates correctly. It is not critical that the OS system time be correct. Given that we are using Java we should be able to handle dates relative to the prime epoch of 1900 after it rolls over. However, the java JVM will not even run if the system time is set before Unix epoch in 1970! It just crashes.
To add fuel to the fire, the NTP server is supplied by another vendor and we have no control over it. So using another protocol or modifying the server to handle any of this is not possible.
A creative solution is required. Needless to say, some deep voodoo must take place. We have considered the following:
Modify the ntpd client software to somehow co-operate with the ntp server and offset the local time from a date greater than Unix epoch in 1970 rather than 1900. Thus allowing the JVM to run without crashing on initialization. All time stamps will then be handled relative to our chosen rollover date. (So basically, make sure we rollover to a date greater than the Unix epoch).
Allow the ntp corrected time to rollover to 1900 epoch and find a fix so that the JVM will not crash.
Has anyone else tackled this issue? And also, are there any other issues that may occur which I have not foreseen, making one or both of these solutions not feasible at all?
Install your software on a 64 bit Linux with a 64 bit JVM. time_t and friends are 64 bit here, adjust the time past 2038 see if stuff still works. If you're good, toss away NTP, find a gps or other source which can be used as a precise clock and guarantees they don't have 32 bit problems, interface your software to read/sync time from that.