0

I need to generate a random number in C and I did it using srand() and rand() functions. It worked fine when I ran it in the normal compiler, but when I am trying to compile the file in the Contiki OS, it's throwing an 'undefined reference to clock_gettime' error.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
int a;
srand(time(NULL));
a=rand() % 10000 + 2;
char *str = (char*)malloc(a);
int i=0;
for(i=0; i<a-1;i++){
  str[i]='s';
}
str[i] = '\0';
strcat(str,"Hello %d from the client ");
sprintf(buf,str, seq_id);

this is the error picture

Can someone help me with this?

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • 4
    Where is `main()` function? You cannot have all this code outside functions – Jorengarenar Sep 03 '21 at 12:09
  • This may help: https://stackoverflow.com/q/2418157/260313. It could be that your glibc version in Contiki OS is smaller than 2.17, and you need to specify linkage to `-lrt`. – rturrado Sep 03 '21 at 12:13
  • 1
    That `strcat` call will result in a buffer overflow. – Ian Abbott Sep 03 '21 at 12:28
  • 1
    Welcome to StackOverflow! Please take the [tour] and read "[ask]" to learn how this site works. -- Please don't post images of code or text. Copy it verbatim. -- Please consult Contiki's documentation, you might need to provide that missed function to be able to call `time()`. You can remove the call of `time()` and use the predefined or undefined initial value inside `rand()`. – the busybee Sep 03 '21 at 12:54
  • You could use the return value of `clock_time()` (declared by `#include "sys/clock.h"` from Contiki's clock library) as the seed. – Ian Abbott Sep 03 '21 at 13:09
  • You know you can take a screenshot directly of just the relevant window rather than photographing your screen!? Even then what you are trying to show is _text_, which could simply (and more usefully) be copy & pasted directly into the question. _Pictures of text_ are seldom appropriate. – Clifford Sep 03 '21 at 14:42
  • @IanAbbott : The Contiki clock library is still necessarily platform dependent (https://contiki-ng.readthedocs.io/en/master/_api/group__clock.html#details), so unless there is explicit board support for a suitable real-time clock source, that may not work either. If there was board support for it I'd expect it to be mapped to the standard library too. – Clifford Sep 03 '21 at 14:45
  • You should remove all code not necessary to the question, because the rest of the code is very questionable (buffer overrun, certain to cause heap corruption), and is a distraction from your actual question. – Clifford Sep 03 '21 at 14:51
  • 1
    @rturrado - that is unlikley to help. The target is embedded on MSP430 MCU - it is not even a given that it has an RTC to use a time source. That must be provided by the BSP or by the user. Besides the requirement here is to obtain a suitable PRNG seed, not to actually get clock time. There are more appropriate methods for this platform. – Clifford Sep 03 '21 at 14:55
  • @Clifford Many thanks for the comment. I just did a quick search and answered with something I thought it could be quickly testable and may actually help. Your comments and answer are no doubt much more thorough. – rturrado Sep 03 '21 at 15:00
  • Updated your tags. Ubuntu (even if it is the development host) is irrelevant here. – Clifford Sep 03 '21 at 15:00
  • 1
    @rturrado : That is fair enough, especially as the question was mis-tagged "Ubuntu" and never mentioned the target. MSP430 is only apparent in the screenshot. I am not sure about "more thorough" - I have 30+ years experience in embedded systems and am making educated guesses. I have never used Contiki - it appears from what I can tell to use Newlib rather then glibc, which would make sense for resource constrained embedded systems that Contiki targets. – Clifford Sep 03 '21 at 15:20

2 Answers2

2

By "normal compiler" I presume you mean the native compiler for your host system? In that case the development host is standard hardware with an operating system that provides "wall-clock" time through operating services that ultimately get time from the RTC or NTP.

In embedded systems the standard library is generic and needs to be retargeted to your platform. Typically I/O, heap management and time services need retargeting. In this case you need to define clock_gettime() to resolve the link (or simply redefine an override for time() - as described here). How you implement it will depend on your specific hardware. Typically you would get time from the RTC, but if your hardware lacks an RTC crystal and a battery backup thereof, it will serve little purpose. Time has to come from somewhere, and the library cannot determine where for your specific hardware.

If you actually never need wall-clock time and are simply following the common idiom of using time(NULL) as a random number generator seed, then rather then fully supporting a time() function you don't need; consider an alternative means of generating a seed such as that described in this Application Note which uses two independent clock sources (VLO and DCO) to generate a random bit sequence. The method is time consuming, so you would normally do it once, then use that as a seed for the standard PRNG via srand().

There is an implementation of the App Note algorithm at https://github.com/0/msp430-rng/blob/master/rand.c, but it is implemented as an override for the standard rand(). I recommend you rename to something like generate_seed(), then call:

srand( generate_seed() ) ;
Clifford
  • 88,407
  • 13
  • 85
  • 165
0

My suggestion is to use the chip unique values from the TLV memory that is pre-programmed at the factory. Each chip will contain unique values (such as calibration data), so just hash all TLV memory to arrive at a seed value, then plug that into the rand() function. If you don't have a hash function handy, then just use any CRC32 calculation over all the bytes.

See this code for example how to read from the TLV memory. Keep in mind that every MSP430 family is different, so consult the device datasheet for the exact memory locations.

If your application initializes the Real Time Clock (RTC) hardware inside every MSP430 chip (and updates it through power cycles) then you could add that to the hash result. Just continue the hash (or CRC32) using the RTC date and time registers for your seed value.

icodeplenty
  • 252
  • 1
  • 6