From 1354e85acb7df38327d355c74f2eed7df7d0b695 Mon Sep 17 00:00:00 2001 From: Liam Teale Date: Sat, 26 Oct 2024 15:30:30 -0400 Subject: [PATCH 1/3] enable LTO --- common.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.mk b/common.mk index 39bd7d95..39316f5b 100644 --- a/common.mk +++ b/common.mk @@ -43,7 +43,7 @@ LDFLAGS=$(MFLAGS) $(WARNFLAGS) -nostdlib $(GCCFLAGS) SIZEFLAGS=-d --common NUMFMTFLAGS=--to=iec --format %.2f --suffix=B -AR:=$(ARCHTUPLE)ar +AR:=$(ARCHTUPLE)gcc-ar # using arm-none-eabi-as generates a listing by default. This produces a super verbose output. # Using gcc accomplishes the same thing without the extra output AS:=$(ARCHTUPLE)gcc From 8873cacb707d97bc2bee519cedb0d06f73d3600a Mon Sep 17 00:00:00 2001 From: Liam Teale Date: Sat, 26 Oct 2024 15:41:15 -0400 Subject: [PATCH 2/3] actually enable lto --- common.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.mk b/common.mk index 39316f5b..e414dd68 100644 --- a/common.mk +++ b/common.mk @@ -3,7 +3,7 @@ DEVICE=VEX EDR V5 MFLAGS=-mcpu=cortex-a9 -mfpu=neon-fp16 -mfloat-abi=hard -Os -g CPPFLAGS=-D_POSIX_THREADS -D_UNIX98_THREAD_MUTEX_ATTRIBUTES -D_POSIX_TIMERS -D_POSIX_MONOTONIC_CLOCK -GCCFLAGS=-ffunction-sections -fdata-sections -fdiagnostics-color -funwind-tables +GCCFLAGS=-ffunction-sections -fdata-sections -fdiagnostics-color -funwind-tables -flto # Check if the llemu files in libvgl exist. If they do, define macros that the # llemu headers in the kernel repo can use to conditionally include the libvgl From 16e7bfdd39f60aba334aedaa99490219b61cc4f5 Mon Sep 17 00:00:00 2001 From: Liam Teale Date: Sat, 26 Oct 2024 17:01:18 -0400 Subject: [PATCH 3/3] fix strict aliasing violations --- include/pros/rtos.h | 2 +- include/rtos/tcb.h | 22 ++++++++++++++++++++++ include/system/hot.h | 11 +++++++++++ src/rtos/tasks.c | 22 ---------------------- src/system/hot.c | 4 ++-- src/system/unwind.c | 8 -------- 6 files changed, 36 insertions(+), 33 deletions(-) diff --git a/include/pros/rtos.h b/include/pros/rtos.h index d6b9be48..06f53e65 100644 --- a/include/pros/rtos.h +++ b/include/pros/rtos.h @@ -820,7 +820,7 @@ uint32_t task_notify_take(bool clear_on_exit, uint32_t timeout); * } * \endcode */ -bool task_notify_clear(task_t task); +int32_t task_notify_clear(task_t task); /** * Creates a mutex. diff --git a/include/rtos/tcb.h b/include/rtos/tcb.h index ab4fd45a..4c0442e3 100644 --- a/include/rtos/tcb.h +++ b/include/rtos/tcb.h @@ -3,6 +3,28 @@ #include "rtos/FreeRTOS.h" #include "rtos/list.h" +/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using +dynamically allocated RAM, in which case when any task is deleted it is known +that both the task's stack and TCB need to be freed. Sometimes the +FreeRTOSConfig.h settings only allow a task to be created using statically +allocated RAM, in which case when any task is deleted it is known that neither +the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h +settings allow a task to be created using either statically or dynamically +allocated RAM, in which case a member of the TCB is used to record whether the +stack and/or TCB were allocated statically or dynamically, so when a task is +deleted the RAM that was allocated dynamically is freed again and no attempt is +made to free the RAM that was allocated statically. +tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a +task to be created using either statically or dynamically allocated RAM. Note +that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with +a statically allocated stack and a dynamically allocated TCB. +!!!NOTE!!! If the definition of tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is +changed then the definition of static_task_s_t must also be updated. */ +#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) +#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 ) +#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 ) +#define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 ) + /* * Task control block. A task control block (TCB) is allocated for each task, * and stores task state information, including a pointer to the task's context diff --git a/include/system/hot.h b/include/system/hot.h index bc5824f8..ee47cdd0 100644 --- a/include/system/hot.h +++ b/include/system/hot.h @@ -1,5 +1,7 @@ #pragma once +#include + struct hot_table { char const* compile_timestamp; char const* compile_directory; @@ -14,4 +16,13 @@ struct hot_table { } functions; }; +// exidx is the table that tells the unwinder how to unwind a stack frame +// for a PC. Under hot/cold, there's two tables and the unwinder was kind +// enough to let us implement a function to give it a table for a PC so +// support for hot/cold is as easy as it gets +struct __EIT_entry { + _uw fnoffset; + _uw content; +}; + extern struct hot_table* const HOT_TABLE; diff --git a/src/rtos/tasks.c b/src/rtos/tasks.c index a413af49..d29d5acf 100644 --- a/src/rtos/tasks.c +++ b/src/rtos/tasks.c @@ -77,28 +77,6 @@ functions but without including stdio.h here. */ */ #define tskSTACK_FILL_BYTE ( 0xa5U ) -/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using -dynamically allocated RAM, in which case when any task is deleted it is known -that both the task's stack and TCB need to be freed. Sometimes the -FreeRTOSConfig.h settings only allow a task to be created using statically -allocated RAM, in which case when any task is deleted it is known that neither -the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h -settings allow a task to be created using either statically or dynamically -allocated RAM, in which case a member of the TCB is used to record whether the -stack and/or TCB were allocated statically or dynamically, so when a task is -deleted the RAM that was allocated dynamically is freed again and no attempt is -made to free the RAM that was allocated statically. -tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a -task to be created using either statically or dynamically allocated RAM. Note -that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with -a statically allocated stack and a dynamically allocated TCB. -!!!NOTE!!! If the definition of tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is -changed then the definition of static_task_s_t must also be updated. */ -#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) -#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 ) -#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 ) -#define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 ) - /* If any of the following are set then task stacks are filled with a known value so the high water mark can be determined. If none of the following are set then don't fill the stack so there is no unnecessary dependency on memset. */ diff --git a/src/system/hot.c b/src/system/hot.c index 3341967a..c5f46608 100644 --- a/src/system/hot.c +++ b/src/system/hot.c @@ -23,8 +23,8 @@ extern char const* _PROS_COMPILE_TIMESTAMP; extern char const* _PROS_COMPILE_DIRECTORY; extern const int _PROS_COMPILE_TIMESTAMP_INT; -extern unsigned __exidx_start; -extern unsigned __exidx_end; +extern struct __EIT_entry __exidx_start; +extern struct __EIT_entry __exidx_end; // this expands to a bunch of: // extern void autonomous(); diff --git a/src/system/unwind.c b/src/system/unwind.c index 9ac6c180..cf68875a 100644 --- a/src/system/unwind.c +++ b/src/system/unwind.c @@ -72,14 +72,6 @@ static inline void print_phase2_vrs(struct phase2_vrs* vrs) { fputs("\n", stderr); } -// exidx is the table that tells the unwinder how to unwind a stack frame -// for a PC. Under hot/cold, there's two tables and the unwinder was kind -// enough to let us implement a function to give it a table for a PC so -// support for hot/cold is as easy as it gets -struct __EIT_entry { - _uw fnoffset; - _uw content; -}; // these are all defined by the linker extern struct __EIT_entry __exidx_start; extern struct __EIT_entry __exidx_end;