From fe25510fc23031f1a3c1b42edd37067d1989a9f6 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sat, 17 Dec 2016 20:58:36 -0800 Subject: altos/arm: Align data so that gcc 5.4 doesn't do byte-accesses. Add -Wcast-align Gcc 5.4.1 tracks alignment of data through assignments, so that a uint32_t pointer which comes from byte-aligned uint8_t data: extern uint8_t foo[]; uint32_t *q = (void *) foo; Fetches and stores through this pointer are done bytewise. This is slow (meh), but if q references a device register, things to bad very quickly. This patch works around this bug in the compiler by adding __attribute__((aligned(4))) tags to some variables, or changing them from uint8_t to uint32_t. Places doing this will now be caught as I've added -Wcast-align to the compiler flags. That required adding (void *) casts, after the relevant code was checked to make sure the compiler could tell that the addresses were aligned. Signed-off-by: Keith Packard --- src/stmf0/Makefile-stmf0.defs | 2 +- src/stmf0/ao_adc_fast.h | 2 +- src/stmf0/ao_arch_funcs.h | 2 +- src/stmf0/ao_usb_stm.c | 2 +- src/stmf0/stm32f0.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/stmf0') diff --git a/src/stmf0/Makefile-stmf0.defs b/src/stmf0/Makefile-stmf0.defs index 4862f46e..f3296b69 100644 --- a/src/stmf0/Makefile-stmf0.defs +++ b/src/stmf0/Makefile-stmf0.defs @@ -25,7 +25,7 @@ endif ELFTOHEX=$(TOPDIR)/../ao-tools/ao-elftohex/ao-elftohex CC=$(ARM_CC) -WARN_FLAGS=-Wall -Wextra -Werror +WARN_FLAGS=-Wall -Wextra -Werror -Wcast-align AO_CFLAGS=-I. -I$(TOPDIR)/stmf0 -I$(TOPDIR)/kernel -I$(TOPDIR)/drivers -I$(TOPDIR)/product -I$(TOPDIR) -I$(TOPDIR)/math $(PDCLIB_INCLUDES) STMF0_CFLAGS=-std=gnu99 -mlittle-endian -mcpu=cortex-m0 -mthumb\ diff --git a/src/stmf0/ao_adc_fast.h b/src/stmf0/ao_adc_fast.h index b8b5e003..3f0b0547 100644 --- a/src/stmf0/ao_adc_fast.h +++ b/src/stmf0/ao_adc_fast.h @@ -28,7 +28,7 @@ ao_adc_init(void); /* Total ring size in samples */ #define AO_ADC_RING_SIZE 256 -extern uint16_t ao_adc_ring[AO_ADC_RING_SIZE]; +extern uint16_t ao_adc_ring[AO_ADC_RING_SIZE] __attribute__((aligned(4))); #define ao_adc_ring_step(pos,inc) (((pos) + (inc)) & (AO_ADC_RING_SIZE - 1)) diff --git a/src/stmf0/ao_arch_funcs.h b/src/stmf0/ao_arch_funcs.h index 8b6234c4..0cb0e43d 100644 --- a/src/stmf0/ao_arch_funcs.h +++ b/src/stmf0/ao_arch_funcs.h @@ -355,7 +355,7 @@ ao_arch_memory_barrier() { static inline void ao_arch_init_stack(struct ao_task *task, void *start) { - uint32_t *sp = (uint32_t *) (task->stack + AO_STACK_SIZE); + uint32_t *sp = (uint32_t *) ((void *) task->stack + AO_STACK_SIZE); uint32_t a = (uint32_t) start; int i; diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c index cbedb996..652b3b6c 100644 --- a/src/stmf0/ao_usb_stm.c +++ b/src/stmf0/ao_usb_stm.c @@ -185,7 +185,7 @@ static inline uint32_t set_toggle(uint32_t current_value, static inline uint16_t *ao_usb_packet_buffer_addr(uint16_t sram_addr) { - return (uint16_t *) (stm_usb_sram + sram_addr); + return (uint16_t *) (void *) (stm_usb_sram + sram_addr); } static inline uint16_t ao_usb_packet_buffer_offset(uint16_t *addr) diff --git a/src/stmf0/stm32f0.h b/src/stmf0/stm32f0.h index 054200e0..bafa763a 100644 --- a/src/stmf0/stm32f0.h +++ b/src/stmf0/stm32f0.h @@ -1996,7 +1996,7 @@ union stm_usb_bdt { #define STM_USB_BDT_SIZE 8 -extern uint8_t stm_usb_sram[]; +extern uint8_t stm_usb_sram[] __attribute__((aligned(4))); struct stm_exti { vuint32_t imr; -- cgit v1.2.3