Contiki 3.x
random.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, Eistec AB.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holder nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * This file is part of the Mulle platform port of the Contiki operating system.
30  *
31  */
32 
33 /**
34  * \file
35  * Simple linear-congruential generator generic C implementation.
36  *
37  * \authors
38  * Joakim Gebart <joakim.gebart@eistec.se>
39  */
40 
41 #include <stdint.h>
42 #include "random.h"
43 
44 /* Constants must be chosen carefully to generate a full cycle sequence. */
45 /* These specific numeric values are sometimes referred to as BCPL in literature. */
46 #define RAND_MULTIPLIER 2147001325u
47 #define RAND_INCREMENT 715136305u
48 
49 /* Defines to match API definitions in Contiki */
50 #define RAND_STATE_TYPE uint32_t
51 #define RAND_SEED_TYPE unsigned short
52 #define RAND_RETURN_TYPE unsigned short
53 
54 /** Saved state between invocations of random_rand() */
55 static RAND_STATE_TYPE rand_state;
56 
57 /** Initialize the PRNG.
58  *
59  * \note seed is only a short (likely 16 bits), but the saved state is actually 32 bits.
60  */
61 void
62 random_init(RAND_SEED_TYPE seed)
63 {
64  rand_state = seed;
65  /** \todo Use CPU UUID for additional random seeding */
66 }
67 
68 /**
69  * Generate the next state and return the upper part of it.
70  */
71 RAND_RETURN_TYPE
73 {
74  /* LCG iteration, the compiler will know to optimize this into a Fused
75  * Multiply-Add (FMA) instruction or similar.
76  * GCC 4.8.3 -mcpu=cortex-m4 yields:
77  * ldr r1, [r0, #0]
78  * movw r2, #7473 ; 0x1d31
79  * movt r2, #10912 ; 0x2aa0
80  * movw r3, #41965 ; 0xa3ed
81  * movt r3, #32760 ; 0x7ff8
82  * mla r1, r1, r3, r2
83  * str r1, [r0, #0]
84  * where r1 contains the rand_state variable.
85  */
86  rand_state = rand_state * RAND_MULTIPLIER + RAND_INCREMENT;
87  /* Return topmost bits, this also gets optimized by the compiler into a read
88  * with offset instead of a separate shift instruction since the shift is an
89  * even number of bytes. */
90  /* With a power of two modulo, the top bits have a better distribution than
91  * the lower bits, e.g. Bit 0 will be inverted in every iteration. */
92 
93  return (rand_state >> ((sizeof(RAND_STATE_TYPE) - sizeof(RAND_RETURN_TYPE)) * 8));
94 }
void random_init(unsigned short seed)
Seed the cc2430 random number generator.
Definition: random.c:41
unsigned short random_rand(void)
Generate the next state and return the upper part of it.
Definition: random.c:47