mirror of
https://github.com/kelvinlawson/atomthreads.git
synced 2026-01-11 18:33:16 +01:00
Some work on using newlib's reentry capabilities.
This commit is contained in:
@@ -42,6 +42,15 @@ extern "C" {
|
||||
/* Forward declaration */
|
||||
struct atom_tcb;
|
||||
|
||||
/*
|
||||
* Define THREAD_PORT_PRIV to be empty if the used atomport.h does not define
|
||||
* a port specific entry for the atom_tcb struct. This way we do not have an
|
||||
* unused element.
|
||||
*/
|
||||
#if !defined(THREAD_PORT_PRIV)
|
||||
#define THREAD_PORT_PRIV
|
||||
#endif
|
||||
|
||||
typedef struct atom_tcb
|
||||
{
|
||||
/*
|
||||
@@ -50,6 +59,12 @@ typedef struct atom_tcb
|
||||
*/
|
||||
POINTER sp_save_ptr;
|
||||
|
||||
/* Thread's port specific private data. Do not move, some poorly written
|
||||
* thread switching code (*cough* Cortex-M *cough*) might depend on a
|
||||
* known offset into the atom_tcb struct
|
||||
*/
|
||||
THREAD_PORT_PRIV;
|
||||
|
||||
/* Thread priority (0-255) */
|
||||
uint8_t priority;
|
||||
|
||||
|
||||
@@ -113,6 +113,10 @@ CPPFLAGS += -Wall -Wundef -Werror
|
||||
CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS)
|
||||
CPPFLAGS += -I$(board_dir) -I$(common_dir) -I$(src_dir) -I$(kernel_dir) -I$(tests_dir)
|
||||
|
||||
# Assembler flags
|
||||
ASFLAGS += -D__ASSEMBLY__
|
||||
ASFLAGS += -D__NEWLIB__
|
||||
|
||||
# Linker flags
|
||||
LDFLAGS += --static -nostartfiles
|
||||
LDFLAGS += -L$(LIB_DIR)
|
||||
@@ -254,7 +258,7 @@ $(build_dir)/%.elf $(build_dir)/%.map: $(LIB_DIR)/lib$(LIBNAME).a $(build_dir)/%
|
||||
$(build_dir)/%.o: $(src_dir)/%.S Makefile $(board_dir)/Makefile.include
|
||||
$(Q)mkdir -p `dirname $@`
|
||||
$(if $(Q), @echo " (AS) $(subst $(build_dir)/,,$@)")
|
||||
$(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -D__ASSEMBLY__ -I`dirname $<` -c $< -o $@
|
||||
$(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) $(ASFLAGS) -I`dirname $<` -c $< -o $@
|
||||
|
||||
$(build_dir)/%.o: $(src_dir)/%.c Makefile $(board_dir)/Makefile.include
|
||||
$(Q)mkdir -p `dirname $@`
|
||||
@@ -264,7 +268,7 @@ $(build_dir)/%.o: $(src_dir)/%.c Makefile $(board_dir)/Makefile.include
|
||||
$(build_dir)/%.o: $(board_dir)/%.S Makefile $(board_dir)/Makefile.include
|
||||
$(Q)mkdir -p `dirname $@`
|
||||
$(if $(Q), @echo " (AS) $(subst $(build_dir)/,,$@)")
|
||||
$(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -D__ASSEMBLY__ -I`dirname $<` -c $< -o $@
|
||||
$(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) $(ASFLAGS) -I`dirname $<` -c $< -o $@
|
||||
|
||||
$(build_dir)/%.o: $(board_dir)/%.c Makefile $(board_dir)/Makefile.include
|
||||
$(Q)mkdir -p `dirname $@`
|
||||
@@ -274,7 +278,7 @@ $(build_dir)/%.o: $(board_dir)/%.c Makefile $(board_dir)/Makefile.include
|
||||
$(build_dir)/%.o: $(common_dir)/%.S Makefile $(board_dir)/Makefile.include
|
||||
$(Q)mkdir -p `dirname $@`
|
||||
$(if $(Q), @echo " (AS) $(subst $(build_dir)/,,$@)")
|
||||
$(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -D__ASSEMBLY__ -I`dirname $<` -c $< -o $@
|
||||
$(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) $(ASFLAGS) -I`dirname $<` -c $< -o $@
|
||||
|
||||
$(build_dir)/%.o: $(common_dir)/%.c Makefile $(board_dir)/Makefile.include
|
||||
$(Q)mkdir -p `dirname $@`
|
||||
@@ -363,4 +367,4 @@ else
|
||||
endif
|
||||
|
||||
# Include auto-generated dependencies
|
||||
-include $(all_objs:.o=.d)
|
||||
-include $(all_objs:.o=.d)
|
||||
|
||||
@@ -49,6 +49,13 @@
|
||||
.extern CTX_SW_NFO
|
||||
.extern vector_table
|
||||
|
||||
#if defined(__NEWLIB__)
|
||||
/**
|
||||
* When using newlib, reentry context needs to be updated on task switch
|
||||
*/
|
||||
.extern _impure_ptr
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Some bit masks and registers used
|
||||
*/
|
||||
@@ -87,6 +94,17 @@ archFirstThreadRestore:
|
||||
ldr r1, [r0, #0]
|
||||
msr PSP, r1
|
||||
|
||||
#if defined(__NEWLIB__)
|
||||
/**
|
||||
* Store the thread's reentry context address in _impure_ptr. This
|
||||
* should be the TCB's second element
|
||||
*/
|
||||
ldr r1, = _impure_ptr
|
||||
mov r2, r0
|
||||
add r2, #4
|
||||
str r2, [r1, #0]
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set bit #1 in CONTROL. Causes switch to PSP, so we can work directly
|
||||
* with SP now and use pop/push.
|
||||
@@ -223,7 +241,8 @@ pend_sv_handler:
|
||||
|
||||
/**
|
||||
* Copy running thread's process stack pointer to r3 and use it to push
|
||||
* */
|
||||
* the thread's register context on its stack
|
||||
*/
|
||||
mrs r3, PSP
|
||||
|
||||
#if defined(THUMB_2)
|
||||
@@ -281,7 +300,7 @@ pend_sv_handler:
|
||||
subs r3, r3, #32
|
||||
#endif // !THUMB_2
|
||||
/**
|
||||
* Address of running TCB still in r1. Store threads current stack top
|
||||
* Address of running TCB still in r1. Store thread's current stack top
|
||||
* into its sp_save_ptr, which is the struct's first element
|
||||
*/
|
||||
str r3, [r1, #0]
|
||||
@@ -292,6 +311,17 @@ pend_sv_handler:
|
||||
*/
|
||||
str r2, [r0, #0]
|
||||
|
||||
#if defined(__NEWLIB__)
|
||||
/**
|
||||
* Store the thread's reentry context address in _impure_ptr. This
|
||||
* should be the TCB's second element
|
||||
*/
|
||||
mov r4, r2
|
||||
add r4, #4
|
||||
ldr r3, = _impure_ptr
|
||||
str r4, [r3, #0]
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Fetch next thread's stack pointer from its TCB's sp_save_ptr and restore
|
||||
* the thread's register context.
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <libopencm3/cm3/nvic.h>
|
||||
#include <libopencm3/cm3/systick.h>
|
||||
#include <libopencm3/cm3/cortex.h>
|
||||
@@ -201,5 +203,12 @@ void archThreadContextInit(ATOM_TCB *tcb_ptr, void *stack_top,
|
||||
tcb_ptr->sp_save_ptr = tsk_ctx;
|
||||
tcb_ptr->entry_point = entry_point;
|
||||
tcb_ptr->entry_param = entry_param;
|
||||
|
||||
#if defined(__NEWLIB__)
|
||||
/**
|
||||
* Initialise thread's reentry context for newlib
|
||||
*/
|
||||
_REENT_INIT_PTR(&(tcb_ptr->port_priv.reent));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <libopencm3/cm3/cortex.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Required number of system ticks per second (normally 100 for 10ms tick) */
|
||||
#define SYSTEM_TICKS_PER_SEC 100
|
||||
@@ -61,6 +62,18 @@
|
||||
#define CRITICAL_START() __irq_flags = cm_mask_interrupts(true)
|
||||
#define CRITICAL_END() (void) cm_mask_interrupts(__irq_flags)
|
||||
|
||||
/**
|
||||
* When using newlib, define port private field in atom_tcb to be a
|
||||
* struct _reent.
|
||||
*/
|
||||
#if defined(__NEWLIB__)
|
||||
struct cortex_port_priv {
|
||||
struct _reent reent;
|
||||
};
|
||||
|
||||
#define THREAD_PORT_PRIV struct cortex_port_priv port_priv
|
||||
#endif
|
||||
|
||||
/* Uncomment to enable stack-checking */
|
||||
/* #define ATOM_STACK_CHECKING */
|
||||
|
||||
|
||||
@@ -64,19 +64,23 @@ static char *heap_end = 0;
|
||||
caddr_t _sbrk(int incr)
|
||||
{
|
||||
char *prev_end;
|
||||
CRITICAL_STORE;
|
||||
|
||||
if(heap_end == 0){
|
||||
prev_end = NULL;
|
||||
|
||||
CRITICAL_START();
|
||||
|
||||
if(unlikely(heap_end == 0)){
|
||||
heap_end = &end;
|
||||
}
|
||||
|
||||
prev_end = heap_end;
|
||||
|
||||
if(heap_end + incr + MST_SIZE > (char *) vector_table.initial_sp_value){
|
||||
/* new heap size would collide with main stack area*/
|
||||
return (caddr_t) 0;
|
||||
/* make sure new heap size does not collide with main stack area*/
|
||||
if(heap_end + incr + MST_SIZE <= (char *) vector_table.initial_sp_value){
|
||||
prev_end = heap_end;
|
||||
heap_end += incr;
|
||||
}
|
||||
|
||||
heap_end += incr;
|
||||
CRITICAL_END();
|
||||
|
||||
return (caddr_t) prev_end;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user