example-fs-bb48: SYS implementation

This commit is contained in:
NIIBE Yutaka
2016-05-27 17:17:44 +09:00
parent f2a8b01607
commit 960921f537
9 changed files with 354 additions and 64 deletions

View File

@@ -1,5 +1,20 @@
2016-05-27 NIIBE Yutaka <gniibe@fsij.org> 2016-05-27 NIIBE Yutaka <gniibe@fsij.org>
* example-fs-bb48/command.c (cmd_sysinfo): New.
* example-fs-bb48/sample.ld: Update.
* example-fs-bb48/sys.h: New.
Move crc32 functions declarations here.
* example-fs-bb48/sys.c: Rename from first-pages.c.
Include mcu/clk_gpio_init-kl.c to define clock_init and
gpio_init.
(set_led): New.
(reset): Initialize MSP.
(flash_config): Include comparison key.
(crc32_init, crc32_u8, crc32_u32): Change the API.
Write them in assembler so that the size of functions
keep unchanged.
(sys_version, sys_board_id, sys_board_name, sys_vector): New.
* chopstx.c (preempt): Fix IDLE thread stack pointer. * chopstx.c (preempt): Fix IDLE thread stack pointer.
2016-05-26 NIIBE Yutaka <gniibe@fsij.org> 2016-05-26 NIIBE Yutaka <gniibe@fsij.org>

View File

@@ -1,6 +1,10 @@
Consideration about SYS and the first pages of flash ROM Consideration about SYS and the first pages of flash ROM
======================================================== ========================================================
Now, I'm developing something like SYS for Kinetis L MCU, so, I write
this document.
About SYS on STM32F103 About SYS on STM32F103
====================== ======================
@@ -15,10 +19,6 @@ STM32F030, as well as STM32F103. But, it wouldn't be useful for
STM32F030. In fact, the file example-fsm-55/sys.c has name sys.c STM32F030. In fact, the file example-fsm-55/sys.c has name sys.c
but it doesn't include any system routines. but it doesn't include any system routines.
Now, I'm developing something like SYS for Kinetis L MCU, so, I write
this document.
The original issue was: The original issue was:
(1) When it's protected, STM32F103 can't change the first 4KiB of (1) When it's protected, STM32F103 can't change the first 4KiB of
@@ -77,7 +77,7 @@ and here is the list of all.
* flash ROM access routines * flash ROM access routines
unlock unlock
write word write halfword
erase page erase page
brank check brank check
write page write page
@@ -114,6 +114,75 @@ For Kinetis L, because it's ROM has the original firmware upgrade
support by the vendor (though USB HID), all that we needed for support by the vendor (though USB HID), all that we needed for
firmware upgrade would be just erasing to factory settings. firmware upgrade would be just erasing to factory settings.
And it has no limitation like STM32F103's first 4KiB flash ROM.
All pages can be updated at run time.
Nevertheless, the first two pages (2KiB) of KL27Z is still difficult
to use.
So, I decide to introduce something like SYS for Kinetis L.
* Layout
Three pages (3KiB) usage:
------------ The first page
End of RAM <-- not used but hardware define this
Address of reset entry
sys_version
sys_board_info (id, name)
sys_vector
SYS...
------------ The second page
FLASH CONFIG: 16-byte
Reset entry function
CRC-32 routine
CRC-32 table (768-byte of CRC-32 table)
------------ The third page
MAGIC 256-byte (256-byte of the last part of CRC-32 table)
...
vectors (MSP, reset, ...)
...
* data: Board identification
sys_version
sys_board_id
sys_board_name ; null terminated
* Board specific routines
* mcu/board lower level
clock_init
gpio_init
* led
set_led
* data: Board independent routines
* flash ROM access code to be loaded on to RAM
* system reset routine???
nvic_system_reset
* data: vectors for routines and data
sys_version
sys_board_id
address of set_led
address of clock_init
address of gpio_init
address of sys_board_name
address of ...
-- --

View File

@@ -6,7 +6,7 @@ PROJECT = sample
CHOPSTX = .. CHOPSTX = ..
LDSCRIPT= sample.ld LDSCRIPT= sample.ld
CSRC = sample.c first-pages.c usb_kl27z.c usb-cdc.c adc_kl27z.c command.c CSRC = sample.c sys.c usb_kl27z.c usb-cdc.c adc_kl27z.c command.c
################################### ###################################
CROSS = arm-none-eabi- CROSS = arm-none-eabi-
@@ -16,7 +16,7 @@ OBJCOPY = $(CROSS)objcopy
MCU = cortex-m0plus MCU = cortex-m0plus
CWARN = -Wall -Wextra -Wstrict-prototypes CWARN = -Wall -Wextra -Wstrict-prototypes
DEFS = -DFREE_STANDING -DMHZ=48 DEFS = -DFREE_STANDING -DMHZ=48 -DHAVE_SYS_H
OPT = -O3 -Os -g OPT = -O3 -Os -g
LIBS = LIBS =

View File

@@ -7,6 +7,8 @@
#include "adc.h" #include "adc.h"
static int adc_initialized = 0; static int adc_initialized = 0;
#endif #endif
#include "sys.h"
#include "board.h"
struct command_table struct command_table
{ {
@@ -33,6 +35,7 @@ static const char *help_string =
#ifdef ADC_SUPPORT #ifdef ADC_SUPPORT
"adc\r\n" "adc\r\n"
#endif #endif
"sysinfo\r\n"
"help\r\n"; "help\r\n";
static char hexchar (uint8_t x) static char hexchar (uint8_t x)
@@ -197,6 +200,8 @@ cmd_mww (struct tty *tty, const char *line)
#ifdef CRC32_SUPPORT #ifdef CRC32_SUPPORT
#include "crc32.h" #include "crc32.h"
static unsigned int crc_value;
static void static void
cmd_crc32 (struct tty *tty, const char *line) cmd_crc32 (struct tty *tty, const char *line)
{ {
@@ -204,10 +209,10 @@ cmd_crc32 (struct tty *tty, const char *line)
char string[10]; char string[10];
char *s; char *s;
crc32_init (); crc32_init (&crc_value);
while (*line) while (*line)
crc32_u8 (*line++); crc32_u8 (&crc_value, *line++);
v = crc32_value () ^ 0xffffffff; v = crc_value ^ 0xffffffff;
s = compose_hex (string, v); s = compose_hex (string, v);
*s++ = '\r'; *s++ = '\r';
@@ -264,6 +269,44 @@ cmd_adc (struct tty *tty, const char *line)
} }
#endif #endif
static void
cmd_sysinfo (struct tty *tty, const char *line)
{
char output[73];
char *s;
int i;
(void)line;
memcpy (output, "SYS version: ", 13);
s = output + 13;
*s++ = sys_version[2];
*s++ = sys_version[4];
*s++ = sys_version[6];
*s++ = '\r';
*s++ = '\n';
tty_send (tty, (uint8_t *)output, s - output);
memcpy (output, "Board ID: ", 10);
s = output + 10;
s = compose_hex (s, sys_board_id);
*s++ = '\r';
*s++ = '\n';
tty_send (tty, (uint8_t *)output, s - output);
memcpy (output, "Board name: ", 12);
s = output + 12;
for (i = 0; i < (int)sizeof (output) - 2; i ++)
if ((*s = sys_board_name[i]) == 0)
break;
else
s++;
*s++ = '\r';
*s++ = '\n';
tty_send (tty, (uint8_t *)output, s - output);
}
static void static void
cmd_help (struct tty *tty, const char *line) cmd_help (struct tty *tty, const char *line)
{ {
@@ -281,6 +324,7 @@ struct command_table command_table[] = {
#ifdef ADC_SUPPORT #ifdef ADC_SUPPORT
{ "adc", cmd_adc }, { "adc", cmd_adc },
#endif #endif
{ "sysinfo", cmd_sysinfo },
{ "help", cmd_help }, { "help", cmd_help },
}; };

22
example-fs-bb48/crc32.c Normal file
View File

@@ -0,0 +1,22 @@
const unsigned int *const crc32_table= (const unsigned int *const)0x00000480;
void
crc32_init (unsigned int *p)
{
*p = 0xffffffff;
}
static void
crc32_u8 (unsigned int *p, unsigned char v)
{
*p = crc32_table[(*p & 0xff) ^ v] ^ (*p >> 8);
}
void
crc32_u32 (unsigned int *p, unsigned int u)
{
crc32_u8 (p, u & 0xff);
crc32_u8 (p, (u >> 8)& 0xff);
crc32_u8 (p, (u >> 16)& 0xff);
crc32_u8 (p, (u >> 24)& 0xff);
}

View File

@@ -1,5 +1,3 @@
void crc32_init (void); void crc32_init (unsigned int *);
void crc32_u8 (unsigned char); void crc32_u8 (unsigned int *, unsigned char);
void crc32_u32 (unsigned int); void crc32_u32 (unsigned int *, unsigned int);
unsigned int crc32_value (void);

View File

@@ -23,17 +23,28 @@ SECTIONS
_text = .; _text = .;
.f2 : ALIGN(16) SUBALIGN(8) .text : ALIGN(16) SUBALIGN(8)
{ {
KEEP(*(.first_page.first_words)) KEEP(*(.first_page.first_words))
KEEP(*(.first_page)) KEEP(*(.sys.version))
KEEP(*(.flash_config)) KEEP(*(.sys.board_info))
KEEP(*(.flash_config_page)) KEEP(*(.sys.vectors))
} > flash =0xffffffff build/sys.o(.text)
build/sys.o(.text.*)
.text : ALIGN(16) SUBALIGN(16) build/sys.o(.rodata)
{ build/sys.o(.rodata.*)
. = ALIGN(1024); . = ALIGN(1024);
KEEP(*(.flash_config))
KEEP(*(.fixed_function.crc32_init))
KEEP(*(.fixed_function.crc32_u8))
KEEP(*(.fixed_function.crc32_u32))
KEEP(*(.reset.entry))
/*
* Because of alignment requirement
* of startup.vectors, align to 256.
*/
. = ALIGN(256);
KEEP(*(.crc32_table))
KEEP(*(.startup.vectors)) KEEP(*(.startup.vectors))
. = ALIGN(16); . = ALIGN(16);
*(.text.startup.*) *(.text.startup.*)

View File

@@ -1,5 +1,5 @@
/* /*
* first-pages.c - First pages for MKL27Z256. * sys.c - First pages for MKL27Z256.
* *
* Copyright (C) 2016 Flying Stone Technology * Copyright (C) 2016 Flying Stone Technology
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
@@ -18,22 +18,37 @@
* data for predefined purposes. * data for predefined purposes.
*/ */
#include <stdint.h> #include <stdint.h>
#include <stdlib.h>
#include "board.h"
extern uint8_t __main_stack_end__; #include "mcu/clk_gpio_init-kl.c"
static void __attribute__ ((naked,section(".flash_config_page"))) static void
set_led (int on)
{
if (on)
GPIOB->PCOR = (1 << 0); /* PTB0: Clear: Light on */
else
GPIOB->PSOR = (1 << 0); /* PTB0: Set : Light off */
}
#define ADDR_VECTORS (0x00000900)
#define ADDR_SCR_VTOR 0xe000ed08
static void __attribute__ ((naked,section(".reset.entry")))
reset (void) reset (void)
{ {
uint32_t r3 = 0xe000ed08; uint32_t r3 = ADDR_SCR_VTOR;
asm volatile ("str %2, [%0]\n\t" /* Set SCR->VTOR */ asm volatile ("str %2, [%0]\n\t" /* Set SCR->VTOR */
"ldr %0, [%2, #4]\n\t" /* Jump to the entry */ "ldr %0, [%2]\n\t" /* Stack address */
"bx %0\n\t" "msr MSP, %0\n\t" /* Exception handler stack. */
"ldr %0, [%2, #4]\n\t" /* The entry address */
"bx %0\n\t" /* Jump to the entry */
".align 2\n" ".align 2\n"
: "=r" (r3) : "=r" (r3)
: "0" (r3), "r" (0x00000800) : "0" (r3), "r" (ADDR_VECTORS)
: "memory"); : "memory");
/* Never reach here. */ /* Never reach here. */
@@ -42,16 +57,18 @@ reset (void)
static uint32_t static uint32_t
stack_entry[] __attribute__ ((section(".first_page.first_words"),used)) = { stack_entry[] __attribute__ ((section(".first_page.first_words"),used)) = {
(uint32_t)(&__main_stack_end__ - 32), /* Since MSP are soon modified in RESET, we put 0 here. */
0,
(uint32_t)reset, (uint32_t)reset,
}; };
/* /*
* NOTE: We don't use backdoor comparison key. The area is used by * Here comes SYS routines and data.
* CRC32 table.
*/ */
static uint32_t static uint32_t
flash_config[] __attribute__ ((section(".flash_config"),used)) = { flash_config[] __attribute__ ((section(".flash_config"),used)) = {
0xffffffff, 0xffffffff, /* Comparison Key */
0xffffffff, /* Protection bytes */ 0xffffffff, /* Protection bytes */
0xffff3ffe, /* FSEC=0xfe, FOPT=0x3f */ 0xffff3ffe, /* FSEC=0xfe, FOPT=0x3f */
/* FOPT=0x3f: /* FOPT=0x3f:
@@ -66,12 +83,96 @@ flash_config[] __attribute__ ((section(".flash_config"),used)) = {
/* /*
* CRC32 calculation routines. * CRC32 calculation routines.
*/ */
void __attribute__ ((naked,section(".fixed_function.crc32_init")))
crc32_init (unsigned int *p)
{
#ifdef ORIGINAL_IN_C
*p = 0xffffffff;
#else
register unsigned int r3 asm ("r3");
asm volatile ("mov %0, #1\n\t"
"neg %0, %0\n\t"
"str %0, [%1]\n\t"
"bx lr\n"
: "=r" (r3)
: "r" (p)
: "memory");
#endif
}
#ifdef ORIGINAL_IN_C
const unsigned int *const crc32_table= (const unsigned int *const)0x00000500;
#endif
void __attribute__ ((naked,section(".fixed_function.crc32_u8")))
crc32_u8 (unsigned int *p, unsigned char v)
{
#ifdef ORIGINAL_IN_C
*p = crc32_table[(*p & 0xff) ^ v] ^ (*p >> 8);
#else
register unsigned int r2 asm ("r2");
register unsigned int r3 asm ("r3");
asm volatile ("ldrb %2, [%4]\n\t"
"eor %0, %2\n\t"
"mov %2, #0xa0\n\t" /* (0x0500 >> 3) */
"lsl %0, %0, #2\n\t"
"lsl %2, %2, #3\n\t"
"add %0, %0, %2\n\t"
"ldr %2, [%4]\n\t"
"ldr %1, [%0]\n\t"
"lsr %2, %2, #8\n\t"
"eor %2, %1\n\t"
"str %2, [%4]\n\t"
"bx lr\n"
: "=r" (v), "=r" (r2), "=r" (r3)
: "0" (v), "r" (p)
: "memory");
#endif
}
void __attribute__ ((naked,section(".fixed_function.crc32_u32")))
crc32_u32 (unsigned int *p, unsigned int u)
{
#ifdef ORIGINAL_IN_C
crc32_u8 (p, u & 0xff);
crc32_u8 (p, (u >> 8)& 0xff);
crc32_u8 (p, (u >> 16)& 0xff);
crc32_u8 (p, (u >> 24)& 0xff);
#else
register unsigned int r3 asm ("r3");
register unsigned int r4 asm ("r4");
register unsigned int r5 asm ("r5");
asm volatile ("push {%1, %2, %3, lr}\n\t"
"mov %2, %0\n\t"
"mov %3, %5\n\t"
"uxtb %0, %0\n\t"
"bl crc32_u8\n\t"
"lsr %0, %2, #8\n\t"
"mov %5, %3\n\t"
"uxtb %0, %0\n\t"
"bl crc32_u8\n\t"
"lsr %0, %2, #16\n\t"
"mov %5, %3\n\t"
"uxtb %0, %0\n\t"
"bl crc32_u8\n\t"
"mov %5, %3\n\t"
"lsr %0, %2, #24\n\t"
"bl crc32_u8\n\t"
"pop {%1, %2, %3, pc}\n\t"
: "=r" (u), "=r" (r3), "=r" (r4), "=r" (r5)
: "0" (u), "r" (p)
: "memory");
#endif
}
/* /*
* Table of CRC32, generated by gen_crc_table.py * Table of CRC32, generated by gen_crc_table.py
*/ */
static unsigned int const unsigned int
crc32_table[256] __attribute__ ((section(".first_page"))) = { crc32_table[256] __attribute__ ((section(".crc32_table"))) = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
@@ -117,35 +218,27 @@ crc32_table[256] __attribute__ ((section(".first_page"))) = {
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
}; };
static unsigned int crc_reg;
__attribute__ ((section(".flash_config_page"))) const uint8_t sys_version[8] __attribute__((section(".sys.version"))) = {
void 3*2+2, /* bLength */
crc32_init (void) 0x03, /* bDescriptorType = STRING_DESCRIPTOR */
{ /* sys version: "3.0" */
crc_reg = 0xffffffff; '3', 0, '.', 0, '0', 0,
} };
__attribute__ ((section(".flash_config_page"))) static const uint8_t board_name_string[] = BOARD_NAME;
unsigned int
crc32_value (void)
{
return crc_reg;
}
__attribute__ ((section(".flash_config_page"))) const uint8_t __attribute__((section(".sys.board_info")))
void *const sys_board_name = board_name_string;
crc32_u8 (unsigned char bits_eight)
{
crc_reg = crc32_table[(crc_reg & 0xff) ^ bits_eight] ^ (crc_reg >> 8);
}
__attribute__ ((section(".flash_config_page"))) const uint32_t __attribute__((section(".sys.board_info")))
void sys_board_id = BOARD_ID;
crc32_u32 (unsigned int u)
{ typedef void (*handler)(void);
crc32_u8 (u & 0xff);
crc32_u8 ((u >> 8)& 0xff); handler sys_vector[] __attribute__ ((section(".sys.vectors"))) = {
crc32_u8 ((u >> 16)& 0xff); clock_init,
crc32_u8 ((u >> 24)& 0xff); gpio_init,
} (handler)set_led,
NULL,
};

38
example-fs-bb48/sys.h Normal file
View File

@@ -0,0 +1,38 @@
extern const uint8_t sys_version[8];
extern const uint32_t sys_board_id;
extern const char *const sys_board_name;
typedef void (*handler)(void);
extern handler sys_vector[16];
/*
* Users can override INLINE by 'attribute((used))' to have an
* implementation defined.
*/
#if !defined(INLINE)
#define INLINE __inline__
#endif
static INLINE void
clock_init (void)
{
(*sys_vector[0]) ();
}
static INLINE void
gpio_init (void)
{
(*sys_vector[1]) ();
}
static inline void
set_led (int on)
{
void (*func) (int) = (void (*)(int))sys_vector[2];
return (*func) (on);
}
void crc32_init (unsigned int *);
void crc32_u8 (unsigned int *, unsigned char);
void crc32_u32 (unsigned int *, unsigned int);