1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//!
//! Applications can use this library to access CRCs written by the `canadensis_write_crc` tool.
//!
//! # Steps (for ARM Cortex-M targets)
//!
//! * In the application, call the `get_crc` function
//! * Compile the application, generating a .elf file
//! * Run `canadensis_write_crc` on the .elf file to calculate and fill in the CRC
//!     * Caution: Don't use `cargo build` or `cargo run` at this stage. It will overwrite the
//!       binary and clear the CRC.
//! * Load the .elf file onto the target microcontroller and run it as usual
//!

#![no_std]
#![deny(missing_docs)]

use core::ptr;

/// The CRC of this compiled image
///
/// This will be filled in by `canadensis_write_crc`
#[no_mangle]
static CANADENSIS_CRC: u64 = 0;
/// 1 if `CANADENSIS_CRC` is valid
///
/// This will be filled in by `canadensis_write_crc`
#[no_mangle]
static CANADENSIS_CRC_VALID: u8 = 0;

/// Returns the CRC of the compiled image, if one has been set
pub fn get_crc() -> Option<u64> {
    // If these are not volatile reads, the compiler will optimize them away and the symbols
    // will be missing from the binary.
    let valid = unsafe { ptr::read_volatile(&CANADENSIS_CRC_VALID) };
    if valid == 1 {
        let crc = unsafe { ptr::read_volatile(&CANADENSIS_CRC) };
        Some(crc)
    } else {
        None
    }
}