Tag: linux

New Linux Timing Code

New Linux Timing Code

silver and white round analog watch

For some time, I had a problem with my old Linux timing code. The units hr_time.h/c had to have the includes arranged in the right order and some flags set for it to compile. Plus it never seemed right having to do this in hr_time.h

#include <linux/time.h>
#define __timespec_defined 1
#define __itimerspec_defined 1
#define __timeval_defined 1

But today I found some better code on this SolarianProgrammer website and I’m always happy to give credit where it’s due. I’ve witched to using C17 which clang on Ubuntu (clang 14) and Raspberry Pi (clang 11) both seem to accept.

So now my hr_time.h looks like this:

hr_time.h

#pragma once
#include <stdlib.h>
#include <time.h>

void startTimer();
void stopTimer();
double diff();

hr_time.c

#include "hr_time.h"
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

struct timespec start;
struct timespec end;

void startTimer() {
	if (timespec_get(&start, TIME_UTC) != TIME_UTC) {
		printf("Error in calling timespec_get\n");
		exit(EXIT_FAILURE);
	}
};

void stopTimer() {
	if (timespec_get(&end, TIME_UTC) != TIME_UTC) {
		printf("Error in calling timespec_get\n");
		exit(EXIT_FAILURE);
	}
};

double diff()
{
	return  (double)(end.tv_sec - start.tv_sec) + 
			((double)(end.tv_nsec - start.tv_nsec) / 1000000000L);
}

I’m only ever using one timer, if you want to modify this to pass in a timer in the startTimer and stopTimer then it’s easy enough.

Identifying a Linux system in code

Identifying a Linux system in code

Since I got asteroids running on a Raspberry Pi, I have decided I want to incorporate the temperature in the window caption when you switch it to debug mod by pressing Tab. Currently all that does is display position info on moving objects and bounding boxes.

But if I include that code in, I want to be sure that it only works when running on a Raspberry Pi. So I need some code to identify the system. A bit of digging and I discovered the Linux uname command. That link goes to an online man page for uname.

If I run uname -a on my Ubuntu 18.04LTS I get this.

Linux david-Virtual-Machine 4.15.0-96-generic #97-Ubuntu SMP Wed Apr 1 03:25:46 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

And on my PI.

Linux raspberrypi 4.19.97-v7+ #1294 SMP Thu Jan 30 13:15:58 GMT 2020 armv7l GNU/Linux

In fact the uname -n command gives david-Virtual-Machine on Ubuntu and raspberrypi on the PI. These are the names though names are often changeable and what if someone is running ubuntu on a PI? Yes it is a thing. But the uname -m identifies the CPU.  x86-64 on my Ubuntu and armv71 on the pi.

I did a bit of digging and found a C program on stackoverflow that will do the same as uname.

#include 
#include 
#include 
#include <sys/utsname.h>

int main(void) {

   struct utsname buffer;

   errno = 0;
   if (uname(&buffer) != 0) {
      perror("uname");
      exit(EXIT_FAILURE);
   }

   printf("system name = %s\n", buffer.sysname);
   printf("node name   = %s\n", buffer.nodename);
   printf("release     = %s\n", buffer.release);
   printf("version     = %s\n", buffer.version);
   printf("machine     = %s\n", buffer.machine);

   #ifdef _GNU_SOURCE
      printf("domain name = %s\n", buffer.domainname);
   #endif

   return EXIT_SUCCESS;
}

And this is what it outputs on a PI.


system name = Linux
node name   = raspberrypi
release     = 4.19.97-v7+
version     = #1294 SMP Thu Jan 30 13:15:58 GMT 2020
machine     = armv7l

So that bit is easy to do. Next is getting the temperature, but that’s for another blog entry…

The joys of Linux C Compilation

The joys of Linux C Compilation

I’m slowly working my way through 30 odd examples of C code that I wrote for the first 20 chapters in my Ebook., And finding odd compile errors. Here’s an example.

I’ve rewritten my stopWatch object for high-precision timing. This is the header.

#include 

struct _stopWatch {
  struct timespec start; 
  struct timespec stop;
} stopWatch;

typedef struct _stopWatch stopWatch;

void startTimer(stopWatch *timer);
void stopTimer(stopWatch *timer);
double diff(stopWatch *timer);

It won’t compile, and keeps on complaining that timespec is an incomplete type. I saw one solution which was to redefine timespec like this:

struct timespec {
  time_t tv_sec; /* seconds */
  long tv_nsec; /* nanoseconds */
};

But that got Clang wound up about timespec redefined errors. I searched and searched and eventually found the answer. Instead of

#include <time>

Use this as well

#include <time> 
#include <linux/time.h>

Simple when you know how!