Initial Commit
This commit is contained in:
commit
1f80a3a3dc
|
@ -0,0 +1 @@
|
|||
_build
|
|
@ -0,0 +1,18 @@
|
|||
# List all source files the application uses.
|
||||
APPLICATION_SRCS = $(notdir $(wildcard ./*.c))
|
||||
|
||||
PROJECT_NAME = cmac_aes128_test
|
||||
VERSION = 0.1
|
||||
|
||||
DEVICE = NRF51
|
||||
|
||||
#USE_SOFTDEVICE = s110
|
||||
|
||||
SDK_PATH = $(HOME)/devel/nrf-sdk/10.0/
|
||||
|
||||
TEMPLATE_PATH = ./template/
|
||||
|
||||
CFLAGS = -Os -Wall -Werror -flto -g
|
||||
LDFLAGS = -Os -flto -g
|
||||
|
||||
include $(TEMPLATE_PATH)Makefile
|
|
@ -0,0 +1,26 @@
|
|||
# CMAC-AES128 for nRF51
|
||||
|
||||
- Uses AES-ECB hardware peripheral
|
||||
- Includes target test app that runs the NIST 800-38B Examples
|
||||
- Includes host test app that checks the NIST 800-38B Examples
|
||||
(requires OpenSSL)
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
1. Edit `Makefile`, special note to edit the path to the NRF-SDK
|
||||
(tested against SDK 10.0)
|
||||
|
||||
2. Edit main.c:
|
||||
|
||||
> #define ERROR_LED_PIN 12
|
||||
> #define ERROR_LED_ACTIVE LOW
|
||||
|
||||
3. `make`:
|
||||
|
||||
Output files in `_build` directory. Program to nRF51 dev. board to
|
||||
run tests on target.
|
||||
|
||||
4. `make test`:
|
||||
|
||||
Fakes AES128 peripheral using openssl, then runs tests on host.
|
|
@ -0,0 +1,41 @@
|
|||
#include "aes.h"
|
||||
#include "block.h"
|
||||
|
||||
#ifndef HOST_BUILD
|
||||
#include "nrf.h"
|
||||
#else
|
||||
#include <openssl/evp.h>
|
||||
#endif /* HOST_BUILD */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static ecbdata_t g_ecbdata;
|
||||
|
||||
void aes128_init(uint8_t *key) {
|
||||
memmove(g_ecbdata.key, key, 16);
|
||||
#ifndef HOST_BUILD
|
||||
NRF_ECB->ECBDATAPTR = (uint32_t)&g_ecbdata;
|
||||
#endif /* HOST_BUILD */
|
||||
return;
|
||||
}
|
||||
|
||||
block_t aes128_ecb(block_t const * const in) {
|
||||
#ifdef HOST_BUILD
|
||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||
EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, g_ecbdata.key, NULL);
|
||||
|
||||
int outlen, tmplen;
|
||||
EVP_EncryptUpdate(ctx, g_ecbdata.out, &outlen, in->ui8, 16);
|
||||
EVP_EncryptFinal_ex(ctx, g_ecbdata.out + outlen, &tmplen);
|
||||
|
||||
/* Why the fuck does this segfault... I don't care. It's for testing
|
||||
on the host only. Let it leak */
|
||||
//EVP_CIPHER_CTX_free(ctx);
|
||||
#else
|
||||
memmove(g_ecbdata.in, in, 16);
|
||||
NRF_ECB->TASKS_STARTECB = 1;
|
||||
while (!NRF_ECB->EVENTS_ENDECB);
|
||||
NRF_ECB->EVENTS_ENDECB = 0;
|
||||
#endif /* HOST_BUILD */
|
||||
return *((block_t *)g_ecbdata.out);
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include "block.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint8_t key[16];
|
||||
uint8_t in[16];
|
||||
uint8_t out[16];
|
||||
} ecbdata_t;
|
||||
|
||||
|
||||
void aes128_init(uint8_t *);
|
||||
block_t aes128_ecb(block_t const * const);
|
|
@ -0,0 +1,71 @@
|
|||
/* Utility functions for manipulating block_t structures; 128bit
|
||||
blocks of data for AES & CMAC */
|
||||
|
||||
#include "block.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
bool block_cmp(block_t const * const a, block_t const * const b) {
|
||||
for (uint_fast8_t i = 0; i < 4; i++) {
|
||||
if (a->ui32[i] != b->ui32[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void block_print(char const * const label,
|
||||
block_t const * const b) {
|
||||
if (label != NULL) {
|
||||
printf("\n%s: ", label);
|
||||
} else {
|
||||
printf("\n");
|
||||
}
|
||||
for(int i = 0; i < 16; i++) {
|
||||
printf("%.2x", b->ui8[i]);
|
||||
if (!((i+1) % 4)) {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
block_t block_xor(block_t const * const a, block_t const * const b) {
|
||||
block_t c;
|
||||
for (uint_fast8_t i = 0; i < 4; i++) {
|
||||
c.ui32[i] = a->ui32[i] ^ b->ui32[i];
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
block_t block_shiftr(block_t const * const a, uint_fast8_t const num) {
|
||||
block_t c;
|
||||
uint_fast8_t n = (num <= 8 ? num : 8);
|
||||
for (int_fast8_t i = 15; i >= 0; i--) {
|
||||
/* Shift right from LSB to MSB */
|
||||
c.ui8[i] = a->ui8[i] >> n;
|
||||
if (i != 0) {
|
||||
/* If theres a more significant uint32, we need to pull in its lsb */
|
||||
c.ui8[i] |= (a->ui8[i-1] << (8 - n));
|
||||
}
|
||||
}
|
||||
return (num - n == 0 ? c : block_shiftr(&c, num - n));
|
||||
}
|
||||
|
||||
block_t block_shiftl(block_t const * const a, uint_fast8_t const num) {
|
||||
/* Shifts block b right by num bits (where num <= 32) */
|
||||
block_t c;
|
||||
uint_fast8_t n = (num <= 8 ? num : 8);
|
||||
for (int_fast8_t i = 0; i < 16; i++) {
|
||||
/* Shift right from LSB to MSB */
|
||||
c.ui8[i] = a->ui8[i] << n;
|
||||
if (i != 15) {
|
||||
/* If theres a less significant uint32, we need to pull in its msb */
|
||||
c.ui8[i] |= (a->ui8[i+1] >> (8 - n));
|
||||
}
|
||||
}
|
||||
return (num - n == 0 ? c : block_shiftl(&c, num - n));
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef union {
|
||||
uint32_t ui32[4];
|
||||
uint8_t ui8[16];
|
||||
} block_t;
|
||||
|
||||
bool block_cmp(block_t const * const, block_t const * const);
|
||||
void block_print(char const * const, block_t const * const);
|
||||
block_t block_shiftl(block_t const * const, uint_fast8_t);
|
||||
block_t block_shiftr(block_t const * const, uint_fast8_t);
|
||||
block_t block_xor(block_t const * const, block_t const * const);
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aes.h"
|
||||
#include "block.h"
|
||||
#include "cmac.h"
|
||||
|
||||
static const block_t zeros = {.ui32={0,0,0,0}};
|
||||
|
||||
static block_t g_k[2];
|
||||
|
||||
void cmac_aes128_init(block_t *key) {
|
||||
aes128_init(key->ui8);
|
||||
cmac_aes128_expand_key(key, g_k);
|
||||
}
|
||||
|
||||
void cmac_aes128_expand_key(block_t *key, block_t *out) {
|
||||
/* Given AES key k, generate the subkeys needed for CMAC */
|
||||
block_t *k1 = out,
|
||||
*k2 = (out+1);
|
||||
|
||||
block_t l = {0},
|
||||
Rb = {.ui8={0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0x87}};
|
||||
|
||||
l = aes128_ecb(&zeros);
|
||||
if ((l.ui8[0] >> 7) == 0) {
|
||||
*k1 = block_shiftl(&l, 1);
|
||||
} else {
|
||||
block_t tmp = block_shiftl(&l, 1);
|
||||
*k1 = block_xor(&tmp, &Rb);
|
||||
}
|
||||
if (!(k1->ui8[0] >> 7)) {
|
||||
*k2 = block_shiftl(k1, 1);
|
||||
} else {
|
||||
fflush(stdout);
|
||||
block_t tmp = block_shiftl(k1, 1);
|
||||
*k2 = block_xor(&tmp, &Rb);
|
||||
}
|
||||
}
|
||||
|
||||
void cmac_truncate_tag(uint8_t *dest, block_t *tag, uint_fast8_t tag_len_bits) {
|
||||
uint_fast8_t num_bytes = tag_len_bits / 8,
|
||||
last_byte_mask = 0xff << (8 - tag_len_bits % 8);
|
||||
memcpy(dest, tag->ui8, num_bytes);
|
||||
dest[num_bytes] = tag->ui8[num_bytes] & last_byte_mask;
|
||||
}
|
||||
|
||||
/* Address of the first uint8_t in a particular message block */
|
||||
#define BLOCK(x) (&alt_msg[x-1])
|
||||
|
||||
block_t cmac_aes128(uint8_t *msg, size_t msg_len) {
|
||||
/* Simulate ceiling integer division by adding a block if remainder */
|
||||
block_t *k1 = &g_k[0],
|
||||
*k2 = &g_k[1];
|
||||
uint_fast16_t num_blocks = msg_len / 16 + (msg_len % 16 ? 1 : 0);
|
||||
bool last_block_complete = !(msg_len % 16 ? 1 : 0);
|
||||
if (msg_len == 0) {
|
||||
num_blocks = 1;
|
||||
last_block_complete = false;
|
||||
}
|
||||
|
||||
block_t alt_msg[num_blocks];
|
||||
memset(&alt_msg, 0, num_blocks*16);
|
||||
memcpy(&alt_msg, msg, msg_len);
|
||||
|
||||
if (!last_block_complete) {
|
||||
/* Padding is single 1 bit, run out on 0s.. find the next byte,
|
||||
set it to 0b1000000 */
|
||||
alt_msg[num_blocks-1].ui8[msg_len % 16] = 0x80;
|
||||
alt_msg[num_blocks-1] = block_xor(BLOCK(num_blocks), k2);
|
||||
} else {
|
||||
alt_msg[num_blocks-1] = block_xor(BLOCK(num_blocks), k1);
|
||||
}
|
||||
|
||||
block_t x = { .ui32={0, 0, 0, 0}},
|
||||
y = { .ui32={0, 0, 0, 0}};
|
||||
|
||||
/* CBC */
|
||||
for (uint32_t i = 1; i <= num_blocks - 1; i++) {
|
||||
y = block_xor(&x, BLOCK(i));
|
||||
x = aes128_ecb(&y);
|
||||
}
|
||||
y = block_xor(&x, BLOCK(num_blocks));
|
||||
block_t tag = aes128_ecb(&y);
|
||||
return tag;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "block.h"
|
||||
|
||||
block_t cmac_aes128(uint8_t *, size_t);
|
||||
void cmac_aes128_expand_key(block_t *, block_t *);
|
||||
void cmac_aes128_init(block_t *);
|
||||
void cmac_truncate_tag(uint8_t *, block_t *, uint_fast8_t);
|
|
@ -0,0 +1,82 @@
|
|||
/* Copyright (c) 2016 Jaycon Systems, LLC. All Rights Reserved */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nrf.h"
|
||||
#include "nrf_gpio.h"
|
||||
|
||||
#include "cmac.h"
|
||||
|
||||
#define ERROR_LED_PIN 12
|
||||
#define ERROR_LED_ACTIVE LOW
|
||||
|
||||
#if (ERROR_LED_ACTIVE == LOW)
|
||||
#define ERROR_LED_OFF nrf_gpio_pin_set(ERROR_LED_PIN)
|
||||
#define ERROR_LED_ON nrf_gpio_pin_clear(ERROR_LED_PIN)
|
||||
#else
|
||||
#define ERROR_LED_OFF nrf_gpio_pin_clear(ERROR_LED_PIN)
|
||||
#define ERROR_LED_ON nrf_gpio_pin_set(ERROR_LED_PIN)
|
||||
#endif /* ERROR_LET_ACTIVE */
|
||||
|
||||
void test_cmac(void) {
|
||||
/* NIST Examples */
|
||||
block_t k = { .ui8={0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}};
|
||||
cmac_aes128_init(&k);
|
||||
/* Test Null Message, NIST Example */
|
||||
uint8_t msg1[] = "";
|
||||
block_t case1 = {.ui8={0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
|
||||
0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46}};
|
||||
block_t tag = cmac_aes128(msg1, 0);
|
||||
if (!block_cmp(&tag, &case1)) {
|
||||
ERROR_LED_ON;
|
||||
while(1);
|
||||
}
|
||||
/* 16b example */
|
||||
uint8_t msg2[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
|
||||
block_t case2 = {.ui8={0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
|
||||
0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c}};
|
||||
tag = cmac_aes128(msg2, sizeof(msg2));
|
||||
if (!block_cmp(&tag, &case2)) {
|
||||
ERROR_LED_ON;
|
||||
while(1);
|
||||
}
|
||||
/* 40b example */
|
||||
uint8_t msg3[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
|
||||
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
|
||||
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11};
|
||||
block_t case3 = {.ui8={0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
|
||||
0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27}};
|
||||
tag = cmac_aes128(msg3, sizeof(msg3));
|
||||
if (!block_cmp(&tag, &case3)) {
|
||||
ERROR_LED_ON;
|
||||
while(1);
|
||||
}
|
||||
/* 64b example */
|
||||
uint8_t msg4[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
|
||||
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
|
||||
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
|
||||
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
|
||||
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
|
||||
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
|
||||
block_t case4 = {.ui8={0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
|
||||
0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe}};
|
||||
tag = cmac_aes128(msg4, sizeof(msg4));
|
||||
if (!block_cmp(&tag, &case4)) {
|
||||
ERROR_LED_ON;
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
nrf_gpio_cfg_output(ERROR_LED_PIN);
|
||||
ERROR_LED_OFF;
|
||||
for (;;) {
|
||||
test_cmac();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
TOOLCHAIN_PREFIX ?= arm-none-eabi
|
||||
|
||||
AS = $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)-as
|
||||
CC = $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)-gcc
|
||||
LD = $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)-gcc
|
||||
OBJCOPY = $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)-objcopy
|
||||
OBJDUMP = $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)-objdump
|
||||
SIZE = $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)-size
|
||||
GDB = $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)-gdb
|
||||
|
||||
START_CODE ?= startup_nrf51.s
|
||||
SYSTEM_FILE ?= system_nrf51.c
|
||||
|
||||
ifdef DEV_BOARD
|
||||
CFLAGS += -DDEV_BOARD
|
||||
endif
|
||||
|
||||
ifeq ($(USE_SOFTDEVICE), s110)
|
||||
CFLAGS += -DS110
|
||||
USE_BLE = 1
|
||||
endif
|
||||
|
||||
ifeq ($(USE_SOFTDEVICE), s120)
|
||||
CFLAGS += -DS120
|
||||
USE_BLE = 1
|
||||
endif
|
||||
|
||||
ifeq ($(USE_SOFTDEVICE), s310)
|
||||
USE_BLE = 1
|
||||
USE_ANT = 1
|
||||
CFLAGS += -DS310
|
||||
endif
|
||||
|
||||
LIBRARY_PATHS += $(TEMPLATE_PATH)
|
||||
LIBRARY_PATHS += $(SDK_PATH)components/toolchain/gcc/
|
||||
LIBRARY_PATHS += $(SDK_PATH)components/toolchain/
|
||||
LIBRARY_PATHS += $(wildcard $(SDK_PATH)components/libraries/*/)
|
||||
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/ble_flash/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/clock/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/common/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/config/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/delay/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/gpiote/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/hal/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/lpcomp/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/ppi/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/pstorage/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/qdec/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/radio_config/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/rng/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/rtc/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/sdio/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/spi_master/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/spi_slave/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/swi/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/timer/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/twi_master/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/uart/
|
||||
LIBRARY_PATHS += $(SDK_PATH)/components/drivers_nrf/wdt/
|
||||
|
||||
LIBRARY_PATHS += $(wildcard $(SDK_PATH)components/device/)
|
||||
LIBRARY_PATHS += $(wildcard $(SDK_PATH)components/serialization/*/)
|
||||
|
||||
ifdef USE_BLE
|
||||
LIBRARY_PATHS += $(wildcard $(SDK_PATH)components/ble/*/)
|
||||
LIBRARY_PATHS += $(wildcard $(SDK_PATH)components/ble/ble_services/*/)
|
||||
CFLAGS += -DBLE_STACK_SUPPORT_REQD
|
||||
endif
|
||||
|
||||
ifdef USE_ANT
|
||||
CFLAGS += -DANT_STACK_SUPPORT_REQD
|
||||
endif
|
||||
|
||||
ifdef USE_SOFTDEVICE
|
||||
CFLAGS += -DSOFTDEVICE_PRESENT
|
||||
LIBRARY_PATHS += $(SDK_PATH)components/softdevice/common/softdevice_handler/
|
||||
LIBRARY_PATHS += $(SDK_PATH)components/softdevice/$(USE_SOFTDEVICE)/headers/
|
||||
else
|
||||
LIBRARY_PATHS += $(wildcard $(SDK_PATH)components/drivers_nrf/nrf_soc_nosd/)
|
||||
USE_SOFTDEVICE = blank
|
||||
endif
|
||||
|
||||
LINKER_SCRIPT ?= gcc_nrf51_$(USE_SOFTDEVICE).ld
|
||||
OUTPUT_NAME ?= $(addsuffix _$(USE_SOFTDEVICE)_$(VERSION), $(PROJECT_NAME))
|
||||
|
||||
ifdef USE_EXT_SENSORS
|
||||
LIBRARY_PATHS += $(wildcard $(SDK_PATH)components/ext_sensors/*/)
|
||||
endif
|
||||
|
||||
LIBRARY_INCLUDES = $(addprefix -I,$(LIBRARY_PATHS))
|
||||
|
||||
VPATH = $(LIBRARY_PATHS)
|
||||
|
||||
OUTPUT_PATH = _build/
|
||||
|
||||
CPUFLAGS += -mthumb -mcpu=cortex-m0 -mabi=aapcs -mfloat-abi=soft
|
||||
ifdef BOARD
|
||||
CFLAGS += -DBOARD=$(BOARD)
|
||||
endif
|
||||
CFLAGS += -std=gnu99 -c $(CPUFLAGS) -Wall -D$(DEVICE) $(LIBRARY_INCLUDES) -MD
|
||||
# keep every function in separate section. This will allow linker to dump unused functions
|
||||
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
|
||||
CFLAGS += -fno-builtin --short-enums
|
||||
|
||||
# keep every function in separate section. This will allow linker to dump unused functions
|
||||
LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
|
||||
LDFLAGS += -mcpu=cortex-m0
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
# use newlib in nano version
|
||||
LDFLAGS += --specs=nano.specs -lc -lnosys
|
||||
LDFLAGS += -Wl,-Map=$(OUTPUT_PATH)$(OUTPUT_NAME).Map
|
||||
|
||||
HEX = $(OUTPUT_PATH)$(OUTPUT_NAME).hex
|
||||
ELF = $(OUTPUT_PATH)$(OUTPUT_NAME).elf
|
||||
BIN = $(OUTPUT_PATH)$(OUTPUT_NAME).bin
|
||||
|
||||
SRCS = $(SYSTEM_FILE) $(notdir $(APPLICATION_SRCS))
|
||||
OBJS = $(addprefix $(OUTPUT_PATH), $(SRCS:.c=.o)) $(addprefix $(OUTPUT_PATH),$(APPLICATION_LIBS))
|
||||
DEPS = $(addprefix $(OUTPUT_PATH), $(SRCS:.c=.d))
|
||||
SRCS_AS = $(START_CODE)
|
||||
OBJS_AS = $(addprefix $(OUTPUT_PATH), $(SRCS_AS:.s=.os))
|
||||
|
||||
JLINK_OPTIONS = -device nrf51822 -if swd -speed 1000
|
||||
|
||||
all: $(OBJS) $(OBJS_AS) $(HEX)
|
||||
|
||||
rebuild: clean all
|
||||
|
||||
bootloader: clean
|
||||
make -C bootloader
|
||||
|
||||
combined: bootloader all
|
||||
srec_cat \
|
||||
softdevice/softdevice.hex -intel \
|
||||
bootloader/_build/sdk10_bootloader_s110.hex -intel -exclude 0x3FC00 0x3FC04 \
|
||||
_build/hiro_s110_$(VERSION).hex -intel \
|
||||
-generate 0x3FC00 0x3FC04 -const-le 0x01 4 \
|
||||
-output bulk-program/$(PROJECT_NAME)-combined-$(VERSION).hex -intel
|
||||
ln bulk-program/$(PROJECT_NAME)-combined-$(VERSION).hex bulk-program/$(PROJECT_NAME)-combined.hex
|
||||
|
||||
# combined: rebuild
|
||||
# srec_cat \
|
||||
# softdevice/softdevice.hex -intel \
|
||||
# _build/$(PROJECT_NAME)_$(USE_SOFTDEVICE)_$(VERSION).hex -intel \
|
||||
# -output bulk-program/combined.hex -intel
|
||||
# ln -s bulk-program/combined.hex bulk-program/$(PROJECT_NAME)-$(VERSION)-combined.hex
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
include $(TEMPLATE_PATH)Makefile.windows
|
||||
else
|
||||
include $(TEMPLATE_PATH)Makefile.posix
|
||||
endif
|
||||
|
||||
$(HEX): $(OBJS) $(OBJS_AS)
|
||||
$(LD) $(LDFLAGS) $(OBJS_AS) $(OBJS) -o $(ELF)
|
||||
$(OBJCOPY) -Oihex $(ELF) $(HEX)
|
||||
$(OBJCOPY) -Obinary $(ELF) $(BIN)
|
||||
$(SIZE) $(ELF)
|
||||
|
||||
size: $(ELF)
|
||||
$(SIZE) $(ELF)
|
||||
|
||||
$(OUTPUT_PATH)%.o: %.c
|
||||
$(MAKE_BUILD_FOLDER)
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) $< -o $@
|
||||
|
||||
$(OUTPUT_PATH)%.os: %.s
|
||||
$(MAKE_BUILD_FOLDER)
|
||||
$(AS) $< -o $@
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
.PHONY: all clean rebuild size
|
|
@ -0,0 +1,83 @@
|
|||
# Set toolchain path if arm-none-eabi- binaries are not in user path
|
||||
#TOOLCHAIN_PATH ?=
|
||||
TERMINAL ?= gnome-terminal -e
|
||||
|
||||
FLASH_START_ADDRESS = $(shell $(OBJDUMP) -h $(ELF) -j .text | grep .text | awk '{print $$4}')
|
||||
|
||||
ifdef SEGGER_SERIAL
|
||||
JLINKEXE_OPTION = -SelectEmuBySn $(SEGGER_SERIAL)
|
||||
JLINKGDBSERVER_OPTION = -select USB=$(SEGGER_SERIAL)
|
||||
endif
|
||||
|
||||
MAKE_BUILD_FOLDER = mkdir -p $(OUTPUT_PATH)
|
||||
|
||||
JLINK = -JLinkExe $(JLINK_OPTIONS) $(JLINKEXE_OPTION)
|
||||
JLINKGDBSERVER = JLinkGDBServer $(JLINK_OPTIONS) $(JLINKGDBSERVER_OPTION)
|
||||
|
||||
SOFTDEVICE_OUTPUT = $(OUTPUT_PATH)$(notdir $(SOFTDEVICE))
|
||||
|
||||
clean:
|
||||
rm -rf $(OUTPUT_PATH)
|
||||
rm -f *.jlink
|
||||
rm -f JLink.log
|
||||
rm -f .gdbinit
|
||||
rm -f bulk-program/*.hex
|
||||
|
||||
flash: all flash.jlink
|
||||
$(JLINK) flash.jlink
|
||||
|
||||
flash.jlink:
|
||||
printf "r\nloadbin $(BIN) $(FLASH_START_ADDRESS)\nr\ng\nexit\n" > flash.jlink
|
||||
|
||||
flash-softdevice: erase-all flash-softdevice.jlink
|
||||
ifndef SOFTDEVICE
|
||||
$(error "You need to set the SOFTDEVICE command-line parameter to a path (without spaces) to the softdevice hex-file")
|
||||
endif
|
||||
|
||||
$(OBJCOPY) -Iihex -Obinary $(SOFTDEVICE) $(SOFTDEVICE_OUTPUT:.hex=.bin)
|
||||
$(JLINK) flash-softdevice.jlink
|
||||
|
||||
flash-softdevice.jlink:
|
||||
# Write to NVMC to enable write. Write mainpart, write UICR. Assumes device is erased.
|
||||
printf "w4 4001e504 1\nloadbin \"$(SOFTDEVICE_OUTPUT:.hex=.bin)\" 0\nr\ng\nexit\n" > flash-softdevice.jlink
|
||||
|
||||
recover: recover.jlink erase-all.jlink pin-reset.jlink
|
||||
$(JLINK) recover.jlink
|
||||
$(JLINK) erase-all.jlink
|
||||
$(JLINK) pin-reset.jlink
|
||||
|
||||
recover.jlink:
|
||||
printf "si 0\nt0\nsleep 1\ntck1\nsleep 1\nt1\nsleep 2\nt0\nsleep 2\nt1\nsleep 2\nt0\nsleep 2\nt1\nsleep 2\nt0\nsleep 2\nt1\nsleep 2\nt0\nsleep 2\nt1\nsleep 2\nt0\nsleep 2\nt1\nsleep 2\nt0\nsleep 2\nt1\nsleep 2\ntck0\nsleep 100\nsi 1\nr\nexit\n" > recover.jlink
|
||||
|
||||
pin-reset.jlink:
|
||||
printf "w4 40000544 1\nr\nexit\n" > pin-reset.jlink
|
||||
|
||||
pin-reset: pin-reset.jlink
|
||||
$(JLINK) pin-reset.jlink
|
||||
|
||||
reset: reset.jlink
|
||||
$(JLINK) reset.jlink
|
||||
|
||||
reset.jlink:
|
||||
printf "r\ng\nexit\n" > reset.jlink
|
||||
|
||||
erase-all: erase-all.jlink
|
||||
$(JLINK) erase-all.jlink
|
||||
|
||||
erase-all.jlink:
|
||||
# Write to NVMC to enable erase, do erase all, wait for completion. reset
|
||||
printf "w4 4001e504 2\nw4 4001e50c 1\nsleep 100\nr\nexit\n" > erase-all.jlink
|
||||
|
||||
startdebug: debug-gdbinit
|
||||
$(TERMINAL) "$(JLINKGDBSERVER) -port $(GDB_PORT_NUMBER)"
|
||||
sleep 1
|
||||
$(TERMINAL) "$(GDB) $(ELF)"
|
||||
|
||||
debug-gdbinit:
|
||||
printf "target remote localhost:$(GDB_PORT_NUMBER)\nbreak main\n" > .gdbinit
|
||||
|
||||
.PHONY: flash flash-softdevice erase-all startdebug
|
||||
|
||||
test:
|
||||
gcc -g -std=gnu99 -Wall -Werror -I.. -DHOST_BUILD -lcrypto block.c aes.c cmac.c tests/test_cmac.c -o tests/test_cmac
|
||||
./tests/test_cmac
|
|
@ -0,0 +1,51 @@
|
|||
TOOLCHAIN_PATH = "c:\Program Files (x86)\GNU Tools ARM Embedded\4.8 2013q4\bin\"
|
||||
JLINK_PATH = "C:\Program Files (x86)\SEGGER\JLinkARM_V480\"
|
||||
|
||||
MAKE_BUILD_FOLDER = if not exist $(OUTPUT_PATH:/=\\) mkdir $(OUTPUT_PATH:/=\\)
|
||||
|
||||
# Make GDB server die after one run.
|
||||
JLINKGDBSERVER_OPTION = -s
|
||||
|
||||
ifdef SEGGER_SERIAL
|
||||
NRFJPROG_OPTIONS = --snr $(SEGGER_SERIAL)
|
||||
JLINKGDBSERVER_OPTION += -select USB=$(SEGGER_SERIAL)
|
||||
endif
|
||||
|
||||
NRFJPROG = nrfjprog $(NRFJPROG_OPTIONS)
|
||||
|
||||
clean:
|
||||
if exist .\$(OUTPUT_PATH:/=\\) rmdir /Q /S $(OUTPUT_PATH:/=)
|
||||
if exist *.jlink del /q *.jlink
|
||||
if exist JLink.log del /q JLink.log
|
||||
if exist .gdbinit del /q .gdbinit
|
||||
|
||||
$(OUTPUT_PATH):
|
||||
if not exist .\$(OUTPUT_PATH:/=\\) md $(OUTPUT_PATH)
|
||||
|
||||
flash:
|
||||
$(NRFJPROG) --program $(HEX) -r
|
||||
|
||||
flash-softdevice:
|
||||
ifndef SOFTDEVICE
|
||||
$(error "You need to set the SOFTDEVICE command-line parameter to a path (without spaces) to the softdevice hex-file")
|
||||
endif
|
||||
$(NRFJPROG) -e --programs "$(SOFTDEVICE)"
|
||||
|
||||
recover:
|
||||
$(NRFJPROG) --recover
|
||||
|
||||
pin-reset:
|
||||
$(NRFJPROG) --pinreset
|
||||
|
||||
reset:
|
||||
$(NRFJPROG) --reset
|
||||
|
||||
startdebug: debug-gdbinit
|
||||
start /D $(JLINK_PATH) JLinkGDBServer $(JLINKGDBSERVER_OPTION) $(JLINK_OPTIONS) -port $(GDB_PORT_NUMBER)
|
||||
timeout /t 1
|
||||
$(GDB) $(ELF) -x gdbinit
|
||||
|
||||
debug-gdbinit:
|
||||
@(echo target remote localhost:$(GDB_PORT_NUMBER) & echo break main) > gdbinit
|
||||
|
||||
.PHONY: clean flash startdebug debug-gdbinit
|
|
@ -0,0 +1,7 @@
|
|||
/* Linker script to configure memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x40000 /* 256k */
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x4000 /* 16k */
|
||||
}
|
||||
INCLUDE "gcc_nrf51_common.ld"
|
|
@ -0,0 +1,140 @@
|
|||
/* Library configurations */
|
||||
GROUP(libgcc.a libc.a libm.a libnosys.a)
|
||||
|
||||
/* Linker script to place sections and symbol values. Should be used together
|
||||
* with other linker script that defines memory regions FLASH and RAM.
|
||||
* It references following symbols, which must be defined in code:
|
||||
* Reset_Handler : Entry of reset handler
|
||||
*
|
||||
* It defines following symbols, which code can use without definition:
|
||||
* __exidx_start
|
||||
* __exidx_end
|
||||
* __etext
|
||||
* __data_start__
|
||||
* __preinit_array_start
|
||||
* __preinit_array_end
|
||||
* __init_array_start
|
||||
* __init_array_end
|
||||
* __fini_array_start
|
||||
* __fini_array_end
|
||||
* __data_end__
|
||||
* __bss_start__
|
||||
* __bss_end__
|
||||
* __end__
|
||||
* end
|
||||
* __HeapLimit
|
||||
* __StackLimit
|
||||
* __StackTop
|
||||
* __stack
|
||||
*/
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.isr_vector))
|
||||
*(.text*)
|
||||
|
||||
KEEP(*(.init))
|
||||
KEEP(*(.fini))
|
||||
|
||||
/* .ctors */
|
||||
*crtbegin.o(.ctors)
|
||||
*crtbegin?.o(.ctors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||
*(SORT(.ctors.*))
|
||||
*(.ctors)
|
||||
|
||||
/* .dtors */
|
||||
*crtbegin.o(.dtors)
|
||||
*crtbegin?.o(.dtors)
|
||||
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||
*(SORT(.dtors.*))
|
||||
*(.dtors)
|
||||
|
||||
*(.rodata*)
|
||||
|
||||
KEEP(*(.eh_frame*))
|
||||
} > FLASH
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} > FLASH
|
||||
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} > FLASH
|
||||
__exidx_end = .;
|
||||
|
||||
__etext = .;
|
||||
|
||||
.data : AT (__etext)
|
||||
{
|
||||
__data_start__ = .;
|
||||
*(vtable)
|
||||
*(.data*)
|
||||
|
||||
. = ALIGN(4);
|
||||
/* preinit data */
|
||||
PROVIDE (__preinit_array_start = .);
|
||||
*(.preinit_array)
|
||||
PROVIDE (__preinit_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* init data */
|
||||
PROVIDE (__init_array_start = .);
|
||||
*(SORT(.init_array.*))
|
||||
*(.init_array)
|
||||
PROVIDE (__init_array_end = .);
|
||||
|
||||
|
||||
. = ALIGN(4);
|
||||
/* finit data */
|
||||
PROVIDE (__fini_array_start = .);
|
||||
*(SORT(.fini_array.*))
|
||||
*(.fini_array)
|
||||
PROVIDE (__fini_array_end = .);
|
||||
|
||||
. = ALIGN(4);
|
||||
/* All data end */
|
||||
__data_end__ = .;
|
||||
|
||||
} > RAM
|
||||
|
||||
.bss :
|
||||
{
|
||||
__bss_start__ = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
__bss_end__ = .;
|
||||
} > RAM
|
||||
|
||||
.heap :
|
||||
{
|
||||
__end__ = .;
|
||||
end = __end__;
|
||||
*(.heap*)
|
||||
__HeapLimit = .;
|
||||
} > RAM
|
||||
|
||||
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||
* used for linker to calculate size of stack sections, and assign
|
||||
* values to stack symbols later */
|
||||
.stack_dummy :
|
||||
{
|
||||
*(.stack)
|
||||
} > RAM
|
||||
|
||||
/* Set stack top to end of RAM, and stack limit move down by
|
||||
* size of stack_dummy section */
|
||||
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||
PROVIDE(__stack = __StackTop);
|
||||
|
||||
/* Check if data + heap + stack exceeds RAM limit */
|
||||
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
/* Linker script to configure memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x0 + 96K, LENGTH = 128K - 96K /* 88 kB is taken by S110, rest for app. */
|
||||
RAM (rwx) : ORIGIN = 0x20000000 + 8K, LENGTH = 16K - 8K /* 8 kB is taken by S110, 8 kB for app. */
|
||||
}
|
||||
INCLUDE "gcc_nrf51_common.ld"
|
|
@ -0,0 +1,7 @@
|
|||
/* Linker script to configure memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x18000, LENGTH = 0x27000 /* 96 kB is taken by S120, 160 kB for app. */
|
||||
RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0x1800 /* 10 kB is taken by S120, 6 kB for app. */
|
||||
}
|
||||
INCLUDE "gcc_nrf51_common.ld"
|
|
@ -0,0 +1,7 @@
|
|||
/* Linker script to configure memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0xC000, LENGTH = 0x34000 /* 48 kB is taken by S210, 80 kB for app. */
|
||||
RAM (rwx) : ORIGIN = 0x20000900, LENGTH = 0x3700 /* 2.25 kB is taken by S210, 13.75 kB for app. */
|
||||
}
|
||||
INCLUDE "gcc_nrf51_common.ld"
|
|
@ -0,0 +1,7 @@
|
|||
/* Linker script to configure memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x20000, LENGTH = 0x20000 /* 128 kB is taken by S310, 128 kB for app. */
|
||||
RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0x1800 /* 10 kB is taken by S310, 6 kB for app. */
|
||||
}
|
||||
INCLUDE "gcc_nrf51_common.ld"
|
|
@ -0,0 +1,212 @@
|
|||
/* File: startup_ARMCM0.S
|
||||
* Purpose: startup file for Cortex-M0 devices. Should use with
|
||||
* GCC for ARM Embedded Processors
|
||||
* Version: V1.2
|
||||
* Date: 15 Nov 2011
|
||||
*
|
||||
* Copyright (c) 2011, ARM Limited
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the ARM Limited nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ARM LIMITED BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
.syntax unified
|
||||
.arch armv6-m
|
||||
|
||||
.section .stack
|
||||
.align 3
|
||||
#ifdef __STACK_SIZE
|
||||
.equ Stack_Size, __STACK_SIZE
|
||||
#else
|
||||
.equ Stack_Size, 0xc00
|
||||
#endif
|
||||
.globl __StackTop
|
||||
.globl __StackLimit
|
||||
__StackLimit:
|
||||
.space Stack_Size
|
||||
.size __StackLimit, . - __StackLimit
|
||||
__StackTop:
|
||||
.size __StackTop, . - __StackTop
|
||||
|
||||
.section .heap
|
||||
.align 3
|
||||
#ifdef __HEAP_SIZE
|
||||
.equ Heap_Size, __HEAP_SIZE
|
||||
#else
|
||||
.equ Heap_Size, 0x100
|
||||
#endif
|
||||
.globl __HeapBase
|
||||
.globl __HeapLimit
|
||||
__HeapBase:
|
||||
.space Heap_Size
|
||||
.size __HeapBase, . - __HeapBase
|
||||
__HeapLimit:
|
||||
.size __HeapLimit, . - __HeapLimit
|
||||
|
||||
.section .isr_vector
|
||||
.align 2
|
||||
.globl __Vectors
|
||||
__Vectors:
|
||||
.long __StackTop /* Top of Stack */
|
||||
.long Reset_Handler /* Reset Handler */
|
||||
.long NMI_Handler /* NMI Handler */
|
||||
.long HardFault_Handler /* Hard Fault Handler */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long SVC_Handler /* SVCall Handler */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long PendSV_Handler /* PendSV Handler */
|
||||
.long SysTick_Handler /* SysTick Handler */
|
||||
|
||||
/* External interrupts */
|
||||
.long POWER_CLOCK_IRQHandler /* POWER_CLOCK */
|
||||
.long RADIO_IRQHandler /* RADIO */
|
||||
.long UART0_IRQHandler /* UART0 */
|
||||
.long SPI0_TWI0_IRQHandler /* SPI0_TWI0 */
|
||||
.long SPI1_TWI1_IRQHandler /* SPI1_TWI1 */
|
||||
.long 0 /* Reserved */
|
||||
.long GPIOTE_IRQHandler /* GPIOTE */
|
||||
.long ADC_IRQHandler /* ADC */
|
||||
.long TIMER0_IRQHandler /* TIMER0 */
|
||||
.long TIMER1_IRQHandler /* TIMER1 */
|
||||
.long TIMER2_IRQHandler /* TIMER2 */
|
||||
.long RTC0_IRQHandler /* RTC0 */
|
||||
.long TEMP_IRQHandler /* TEMP */
|
||||
.long RNG_IRQHandler /* RNG */
|
||||
.long ECB_IRQHandler /* ECB */
|
||||
.long CCM_AAR_IRQHandler /* CCM_AAR */
|
||||
.long WDT_IRQHandler /* WDT */
|
||||
.long RTC1_IRQHandler /* RTC1 */
|
||||
.long QDEC_IRQHandler /* QDEC */
|
||||
.long 0 /* Reserved */
|
||||
.long SWI0_IRQHandler /* SWI0 */
|
||||
.long SWI1_IRQHandler /* SWI1 */
|
||||
.long SWI2_IRQHandler /* SWI2 */
|
||||
.long SWI3_IRQHandler /* SWI3 */
|
||||
.long SWI4_IRQHandler /* SWI4 */
|
||||
.long SWI5_IRQHandler /* SWI5 */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
.long 0 /* Reserved */
|
||||
|
||||
.size __Vectors, . - __Vectors
|
||||
|
||||
.text
|
||||
.thumb
|
||||
.thumb_func
|
||||
.align 2
|
||||
.globl Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
.equ NRF_POWER_RAMON_ADDRESS, 0x40000524
|
||||
.equ NRF_POWER_RAMON_RAM1ON_ONMODE_Msk, 0x3
|
||||
ldr r0, =NRF_POWER_RAMON_ADDRESS
|
||||
ldr r2, [r0]
|
||||
movs r1, #NRF_POWER_RAMON_RAM1ON_ONMODE_Msk
|
||||
orrs r2, r1
|
||||
str r2, [r0]
|
||||
|
||||
/* Loop to copy data from read only memory to RAM. The ranges
|
||||
* of copy from/to are specified by following symbols evaluated in
|
||||
* linker script.
|
||||
* __etext: End of code section, i.e., begin of data sections to copy from.
|
||||
* __data_start__/__data_end__: RAM address range that data should be
|
||||
* copied to. Both must be aligned to 4 bytes boundary. */
|
||||
ldr r1, =__etext
|
||||
ldr r2, =__data_start__
|
||||
ldr r3, =__data_end__
|
||||
|
||||
subs r3, r2
|
||||
ble .flash_to_ram_loop_end
|
||||
|
||||
movs r4, 0
|
||||
.flash_to_ram_loop:
|
||||
ldr r0, [r1,r4]
|
||||
str r0, [r2,r4]
|
||||
adds r4, 4
|
||||
cmp r4, r3
|
||||
blt .flash_to_ram_loop
|
||||
.flash_to_ram_loop_end:
|
||||
ldr r0, =SystemInit
|
||||
blx r0
|
||||
ldr r0, =_start
|
||||
bx r0
|
||||
.pool
|
||||
.size Reset_Handler, . - Reset_Handler
|
||||
|
||||
/* Macro to define default handlers. Default handler
|
||||
* will be weak symbol and just dead loops. They can be
|
||||
* overwritten by other handlers */
|
||||
.macro def_default_handler handler_name
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak \handler_name
|
||||
.type \handler_name, %function
|
||||
\handler_name :
|
||||
b .
|
||||
.size \handler_name, . - \handler_name
|
||||
.endm
|
||||
|
||||
def_default_handler NMI_Handler
|
||||
def_default_handler HardFault_Handler
|
||||
def_default_handler SVC_Handler
|
||||
def_default_handler PendSV_Handler
|
||||
def_default_handler SysTick_Handler
|
||||
def_default_handler Default_Handler
|
||||
def_default_handler POWER_CLOCK_IRQHandler
|
||||
def_default_handler RADIO_IRQHandler
|
||||
def_default_handler UART0_IRQHandler
|
||||
def_default_handler SPI0_TWI0_IRQHandler
|
||||
def_default_handler SPI1_TWI1_IRQHandler
|
||||
def_default_handler GPIOTE_IRQHandler
|
||||
def_default_handler ADC_IRQHandler
|
||||
def_default_handler TIMER0_IRQHandler
|
||||
def_default_handler TIMER1_IRQHandler
|
||||
def_default_handler TIMER2_IRQHandler
|
||||
def_default_handler RTC0_IRQHandler
|
||||
def_default_handler TEMP_IRQHandler
|
||||
def_default_handler RNG_IRQHandler
|
||||
def_default_handler ECB_IRQHandler
|
||||
def_default_handler CCM_AAR_IRQHandler
|
||||
def_default_handler WDT_IRQHandler
|
||||
def_default_handler RTC1_IRQHandler
|
||||
def_default_handler QDEC_IRQHandler
|
||||
def_default_handler SWI0_IRQHandler
|
||||
def_default_handler SWI1_IRQHandler
|
||||
def_default_handler SWI2_IRQHandler
|
||||
def_default_handler SWI3_IRQHandler
|
||||
def_default_handler SWI4_IRQHandler
|
||||
def_default_handler SWI5_IRQHandler
|
||||
|
||||
.weak DEF_IRQHandler
|
||||
.set DEF_IRQHandler, Default_Handler
|
||||
|
||||
.end
|
Loading…
Reference in New Issue