Make a couple of demos build using picolibc (#1202)

* [RISC-V-Qemu-virt_GCC Demo] Add picolibc support

Add minimal picolibc support:

 * Use --specs=picolibc.specs to direct gcc at picolibc
 * Use -DPICOLIBC_INTEGER_PRINTF_SCANF to enable smaller printf implementation
 * Enable configUSE_PICOLIBC_TLS for thread local storage
 * Add TLS section to linker script

Signed-off-by: Keith Packard <keithpac@amazon.com>

* [CORTEX_MPU_M3_MPS2_QEMU_GCC Demo] Add picolibc support

Add minimal picolibc support to this demo

 * Use --specs=picolibc.specs to direct gcc at picolibc
 * Use -DPICOLIBC_INTEGER_PRINTF_SCANF to enable smaller printf implementation
 * Enable configUSE_PICOLIBC_TLS for thread local storage
 * Add TLS section to linker script
 * Replace newlib syscall hooks with picolibc ones

Signed-off-by: Keith Packard <keithpac@amazon.com>

---------

Signed-off-by: Keith Packard <keithpac@amazon.com>
Co-authored-by: Keith Packard <keithpac@amazon.com>
This commit is contained in:
Keith Packard 2024-04-02 21:43:14 -07:00 committed by GitHub
parent 7514cd3d54
commit eb97c5d325
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 89 additions and 2 deletions

View file

@ -44,6 +44,10 @@ extern void vAssertCalled( void );
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled() #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled()
#define configQUEUE_REGISTRY_SIZE 20 #define configQUEUE_REGISTRY_SIZE 20
#ifdef PICOLIBC_TLS
#define configUSE_PICOLIBC_TLS 1
#endif
#define configUSE_PREEMPTION 1 #define configUSE_PREEMPTION 1
#define configUSE_TIME_SLICING 0 #define configUSE_TIME_SLICING 0
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0

View file

@ -63,6 +63,11 @@ else
CFLAGS += -O3 CFLAGS += -O3
endif endif
ifeq ($(PICOLIBC), 1)
CFLAGS += --specs=picolibc.specs -DPICOLIBC_INTEGER_PRINTF_SCANF
LDFLAGS += --specs=picolibc.specs -DPICOLIBC_INTEGER_PRINTF_SCANF
endif
OBJ_FILES := $(SOURCE_FILES:%.c=$(BUILD_DIR)/%.o) OBJ_FILES := $(SOURCE_FILES:%.c=$(BUILD_DIR)/%.o)
.PHONY: clean .PHONY: clean

View file

@ -175,6 +175,26 @@ SECTIONS
_edata = .; _edata = .;
} > RAM AT > FLASH } > RAM AT > FLASH
.tdata : {
*(.tdata .tdata.*)
} >FLASH
.tbss (NOLOAD) : {
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tbss_end = . );
PROVIDE( __tls_end = . );
} >FLASH
PROVIDE( __tdata_source = LOADADDR(.tdata) );
PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) );
PROVIDE( __tdata_size = SIZEOF(.tdata) );
PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) );
PROVIDE( __tbss_start = ADDR(.tbss) );
PROVIDE( __tbss_size = SIZEOF(.tbss) );
PROVIDE( __tls_size = __tls_end - ADDR(.tdata) );
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
PROVIDE( __arm32_tls_tcb_offset = MAX(8, __tls_align) );
PROVIDE( __arm64_tls_tcb_offset = MAX(16, __tls_align) );
. = ALIGN(4); . = ALIGN(4);
.bss : .bss :
@ -195,8 +215,10 @@ SECTIONS
PROVIDE ( end = . ); PROVIDE ( end = . );
PROVIDE ( _end = . ); PROVIDE ( _end = . );
_heap_bottom = .; _heap_bottom = .;
__heap_start = .;
. = . + _Min_Heap_Size; . = . + _Min_Heap_Size;
_heap_top = .; _heap_top = .;
__heap_end = .;
. = . + _Min_Stack_Size; . = . + _Min_Stack_Size;
. = ALIGN(8); . = ALIGN(8);
} >RAM } >RAM

View file

@ -50,8 +50,6 @@ extern unsigned long _heap_bottom;
extern unsigned long _heap_top; extern unsigned long _heap_top;
extern unsigned long g_ulBase; extern unsigned long g_ulBase;
static void * heap_end = 0;
/** /**
* @brief initializes the UART emulated hardware * @brief initializes the UART emulated hardware
*/ */
@ -61,6 +59,34 @@ void uart_init()
UART0_ADDR->CTRL = UART_CTRL_TX_EN; UART0_ADDR->CTRL = UART_CTRL_TX_EN;
} }
#ifdef __PICOLIBC__
#include <stdio.h>
/**
* @brief Write byte to the UART channel to be displayed on the command line
* with qemu
* @param [in] c byte to send
* @param [in] file ignored
* @returns the character written (cast to unsigned so it is not an error value)
*/
int
_uart_putc(char c, FILE *file)
{
(void) file;
UART_DR( UART0_ADDR ) = c;
return (unsigned char) c;
}
static FILE __stdio = FDEV_SETUP_STREAM(_uart_putc, NULL, NULL, _FDEV_SETUP_WRITE);
FILE *const stdout = &__stdio;
#else
static void * heap_end = 0;
/** /**
* @brief not used anywhere in the code * @brief not used anywhere in the code
* @todo implement if necessary * @todo implement if necessary
@ -181,6 +207,8 @@ int _getpid()
return 1; return 1;
} }
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -45,6 +45,10 @@
#define configMTIME_BASE_ADDRESS ( CLINT_ADDR + CLINT_MTIME ) #define configMTIME_BASE_ADDRESS ( CLINT_ADDR + CLINT_MTIME )
#define configMTIMECMP_BASE_ADDRESS ( CLINT_ADDR + CLINT_MTIMECMP ) #define configMTIMECMP_BASE_ADDRESS ( CLINT_ADDR + CLINT_MTIMECMP )
#ifdef PICOLIBC_TLS
#define configUSE_PICOLIBC_TLS 1
#endif
#define configUSE_PREEMPTION 1 #define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0 #define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 1 #define configUSE_TICK_HOOK 1

View file

@ -43,6 +43,11 @@ else
CFLAGS += -O2 CFLAGS += -O2
endif endif
ifeq ($(PICOLIBC), 1)
CFLAGS += --specs=picolibc.specs -DPICOLIBC_INTEGER_PRINTF_SCANF
LDFLAGS += --specs=picolibc.specs -DPICOLIBC_INTEGER_PRINTF_SCANF
endif
SRCS = main.c main_blinky.c riscv-virt.c ns16550.c \ SRCS = main.c main_blinky.c riscv-virt.c ns16550.c \
$(DEMO_SOURCE_DIR)/EventGroupsDemo.c \ $(DEMO_SOURCE_DIR)/EventGroupsDemo.c \
$(DEMO_SOURCE_DIR)/TaskNotify.c \ $(DEMO_SOURCE_DIR)/TaskNotify.c \

View file

@ -81,6 +81,25 @@ SECTIONS
_edata = .; _edata = .;
} >ram AT>rom } >ram AT>rom
.tdata : {
*(.tdata .tdata.*)
} >rom AT>rom
.tbss (NOLOAD) : {
*(.tbss .tbss.* .gnu.linkonce.tb.*)
*(.tcommon)
PROVIDE( __tbss_end = . );
PROVIDE( __tls_end = . );
} >rom AT>rom
PROVIDE( __tdata_source = LOADADDR(.tdata) );
PROVIDE( __tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) );
PROVIDE( __tdata_size = SIZEOF(.tdata) );
PROVIDE( __tbss_offset = ADDR(.tbss) - ADDR(.tdata) );
PROVIDE( __tbss_start = ADDR(.tbss) );
PROVIDE( __tbss_size = SIZEOF(.tbss) );
PROVIDE( __tls_size = __tls_end - ADDR(.tdata) );
PROVIDE( __tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) );
.bss.align : .bss.align :
{ {
. = ALIGN(4); . = ALIGN(4);