diff --git a/platforms/lpc17xx/README b/platforms/lpc17xx/README new file mode 100644 index 0000000..d23d34f --- /dev/null +++ b/platforms/lpc17xx/README @@ -0,0 +1,16 @@ +--------------------------------------------------------------------------- + +Library: Atomthreads NXP LPC17xx Platform. +Author: Natie van Rooyen +License: BSD Revised + +--------------------------------------------------------------------------- + +NXP LPC17xx Platform + +The "lpc17xx" platform contains sources for building a sample Atomthreads +application for the NXP LPC17xx platform. + +The platform was tested on the mbed NXP LPC1768 (http://www.mbed.org). + + diff --git a/platforms/qemu_integratorcp/modules.h b/platforms/qemu_integratorcp/modules.h index a94140a..538dec6 100644 --- a/platforms/qemu_integratorcp/modules.h +++ b/platforms/qemu_integratorcp/modules.h @@ -36,23 +36,19 @@ #include "atomport.h" -typedef volatile unsigned int REG_DWORD ; -typedef volatile unsigned short REG_WORD ; -typedef volatile unsigned char REG_BYTE ; - // ***************************************************************************** // INTEGRATORCP TIMER // ***************************************************************************** typedef struct ICP_TIMER_S { // offset read/write word size reset Description - REG_DWORD LOAD ; // 0x0000 Read/write 32 0x00000000 Load value for Timer - REG_DWORD VALUE ; // 0x0004 Read 32 0xFFFFFFFF The current value for Timer - REG_BYTE CONTROL ; // 0x0008 Read/write 8 0x20 Timer control register - REG_DWORD INTCLR ; // 0x000C Write - - Timer interrupt clear - REG_DWORD RIS ; // 0x0010 Read 1 0x0 Timer raw interrupt status - REG_DWORD MIS ; // 0x0014 Read 1 0x0 Timer masked interrupt status - REG_DWORD BGLOAD ; // 0x0018 Read/write 32 0x00000000 Background load value for Timer + __IO uint32_t LOAD ; // 0x0000 Read/write 32 0x00000000 Load value for Timer + __I uint32_t VALUE ; // 0x0004 Read 32 0xFFFFFFFF The current value for Timer + __IO uint8_t CONTROL ; // 0x0008 Read/write 8 0x20 Timer control register + __O uint32_t INTCLR ; // 0x000C Write - - Timer interrupt clear + __I uint32_t RIS ; // 0x0010 Read 1 0x0 Timer raw interrupt status + __I uint32_t MIS ; // 0x0014 Read 1 0x0 Timer masked interrupt status + __IO uint32_t BGLOAD ; // 0x0018 Read/write 32 0x00000000 Background load value for Timer } ICP_TIMER_T, *PICP_TIMER_T ; @@ -82,17 +78,17 @@ typedef struct ICP_TIMER_S { // ***************************************************************************** typedef struct ICP_PIC_S { // offset read/write word size reset Description - REG_DWORD IRQ_STATUS ; // 0x0000 Read 22 IRQ gated interrupt status - REG_DWORD IRQ_RAWSTAT ; // 0x0004 Read 22 IRQ raw interrupt status - REG_DWORD IRQ_ENABLESET ; // 0x0008 Read/write 22 IRQ enable set - REG_DWORD IRQ_ENABLECLR ; // 0x000C Write 22 IRQ enable clear - REG_DWORD INT_SOFTSET ; // 0x0010 Read/write 16 Software interrupt set - REG_DWORD INT_SOFTCLR ; // 0x0014 Write 16 Software interrupt clear - REG_DWORD RESERVED[2] ; // 0x0018 - REG_DWORD FIQ_STATUS ; // 0x0020 Read 22 FIQ gated interrupt status - REG_DWORD FIQ_RAWSTAT ; // 0x0024 Read 22 FIQ raw interrupt status - REG_DWORD FIQ_ENABLESET ; // 0x0028 Read/write 22 FIQ enable set - REG_DWORD FIQ_ENABLECLR ; // 0x002C Write-only 22 FIQ enable clear + __I uint32_t IRQ_STATUS ; // 0x0000 Read 22 IRQ gated interrupt status + __I uint32_t IRQ_RAWSTAT ; // 0x0004 Read 22 IRQ raw interrupt status + __IO uint32_t IRQ_ENABLESET ; // 0x0008 Read/write 22 IRQ enable set + __O uint32_t IRQ_ENABLECLR ; // 0x000C Write 22 IRQ enable clear + __IO uint32_t INT_SOFTSET ; // 0x0010 Read/write 16 Software interrupt set + __O uint32_t INT_SOFTCLR ; // 0x0014 Write 16 Software interrupt clear + uint32_t RESERVED[2] ; // 0x0018 + __I uint32_t FIQ_STATUS ; // 0x0020 Read 22 FIQ gated interrupt status + __I uint32_t FIQ_RAWSTAT ; // 0x0024 Read 22 FIQ raw interrupt status + __IO uint32_t FIQ_ENABLESET ; // 0x0028 Read/write 22 FIQ enable set + __O uint32_t FIQ_ENABLECLR ; // 0x002C Write-only 22 FIQ enable clear } ICP_PIC_T, *PICP_PIC_T ; diff --git a/platforms/qemu_lm3s/Makefile b/platforms/qemu_lm3s/Makefile index dc9c117..fbdb94f 100644 --- a/platforms/qemu_lm3s/Makefile +++ b/platforms/qemu_lm3s/Makefile @@ -87,6 +87,7 @@ all_tests: fail_tests: make run_test "TEST_NAME=mutex4" + make run_test "TEST_NAME=timer4" make run_test "TEST_NAME=sem4" diff --git a/platforms/qemu_lm3s/modules.h b/platforms/qemu_lm3s/modules.h index 5a074b4..cc0d5f0 100644 --- a/platforms/qemu_lm3s/modules.h +++ b/platforms/qemu_lm3s/modules.h @@ -36,36 +36,31 @@ #include "atomport.h" -typedef volatile unsigned int REG_DWORD ; -typedef volatile unsigned short REG_WORD ; -typedef volatile unsigned char REG_BYTE ; - - // ***************************************************************************** // The Stellaris General-Purpose Timer Module (GPTM) // ***************************************************************************** typedef struct GPTM_TIMER_S { // offset read/write reset Description - REG_DWORD CFG ; // 0x000 R/W 0x00000000 GPTM Configuration 345 - REG_DWORD TAMR ; // 0x004 R/W 0x00000000 GPTM TimerA Mode 346 - REG_DWORD TBMR ; // 0x008 R/W 0x00000000 GPTM TimerB Mode 348 - REG_DWORD CTL ; // 0x00C R/W 0x00000000 GPTM Control 350 - REG_DWORD Reserved[2] ; // 0x010 - REG_DWORD IMR ; // 0x018 R/W 0x00000000 GPTM Interrupt Mask 353 - REG_DWORD RIS ; // 0x01C RO 0x00000000 GPTM Raw Interrupt Status 355 - REG_DWORD MIS ; // 0x020 RO 0x00000000 GPTM Masked Interrupt Status 356 - REG_DWORD ICR ; // 0x024 W1C 0x00000000 GPTM Interrupt Clear 357 - REG_DWORD TAILR ; // 0x028 R/W 0xFFFFFFFF GPTM TimerA Interval Load 359 - REG_DWORD TBILR ; // 0x02C R/W 0x0000FFFF GPTM TimerB Interval Load 360 - REG_DWORD TAMATCHR ; // 0x030 R/W 0xFFFFFFFF GPTM TimerA Match 361 - REG_DWORD TBMATCHR ; // 0x034 R/W 0x0000FFFF GPTM TimerB Match 362 - REG_DWORD TAPR ; // 0x038 R/W 0x00000000 GPTM TimerA Prescale 363 - REG_DWORD TBPR ; // 0x03C R/W 0x00000000 GPTM TimerB Prescale 364 - REG_DWORD TAPMR ; // 0x040 R/W 0x00000000 GPTM TimerA Prescale Match 365 - REG_DWORD TBPMR ; // 0x044 R/W 0x00000000 GPTM TimerB Prescale Match 366 - REG_DWORD TAR ; // 0x048 RO 0xFFFFFFFF GPTM TimerA 367 - REG_DWORD TBR ; // 0x04C RO 0x0000FFFF GPTM TimerB 368 + __IO uint32_t CFG ; // 0x000 R/W 0x00000000 GPTM Configuration 345 + __IO uint32_t TAMR ; // 0x004 R/W 0x00000000 GPTM TimerA Mode 346 + __IO uint32_t TBMR ; // 0x008 R/W 0x00000000 GPTM TimerB Mode 348 + __IO uint32_t CTL ; // 0x00C R/W 0x00000000 GPTM Control 350 + uint32_t Reserved[2] ; // 0x010 + __IO uint32_t IMR ; // 0x018 R/W 0x00000000 GPTM Interrupt Mask 353 + __I uint32_t RIS ; // 0x01C RO 0x00000000 GPTM Raw Interrupt Status 355 + __I uint32_t MIS ; // 0x020 RO 0x00000000 GPTM Masked Interrupt Status 356 + __O uint32_t ICR ; // 0x024 W1C 0x00000000 GPTM Interrupt Clear 357 + __IO uint32_t TAILR ; // 0x028 R/W 0xFFFFFFFF GPTM TimerA Interval Load 359 + __IO uint32_t TBILR ; // 0x02C R/W 0x0000FFFF GPTM TimerB Interval Load 360 + __IO uint32_t TAMATCHR ; // 0x030 R/W 0xFFFFFFFF GPTM TimerA Match 361 + __IO uint32_t TBMATCHR ; // 0x034 R/W 0x0000FFFF GPTM TimerB Match 362 + __IO uint32_t TAPR ; // 0x038 R/W 0x00000000 GPTM TimerA Prescale 363 + __IO uint32_t TBPR ; // 0x03C R/W 0x00000000 GPTM TimerB Prescale 364 + __IO uint32_t TAPMR ; // 0x040 R/W 0x00000000 GPTM TimerA Prescale Match 365 + __IO uint32_t TBPMR ; // 0x044 R/W 0x00000000 GPTM TimerB Prescale Match 366 + __I uint32_t TAR ; // 0x048 RO 0xFFFFFFFF GPTM TimerA 367 + __I uint32_t TBR ; // 0x04C RO 0x0000FFFF GPTM TimerB 368 } GPTM_TIMER_T, *PGPTM_TIMER_T ; @@ -89,7 +84,7 @@ typedef struct GPTM_TIMER_S { #define GPTM_TIMER_CTL_TBEVENT ((unsigned int)0x03 << 10) // Both edges #define GPTM_TIMER_CTL_TBSTALL ((unsigned int)0x01 << 9) // GPTM Timer B Stall Enable. 0 Timer B continues counting while the processor is halted by the debugger #define GPTM_TIMER_CTL_TBEN ((unsigned int)0x01 << 8) // GPTM TimerB Enable -// -------- // +// -------- #define GPTM_TIMER_CTL_TAPWML ((unsigned int)0x01 << 6) // GPTM TimerA PWM Output Level. 0 Output is unaffected. 1 Output is inverted. #define GPTM_TIMER_CTL_TAOTE ((unsigned int)0x01 << 5) // GPTM TimerA Output Trigger Enable. 0 The output TimerB ADC trigger is disabled. 1 The output TimerB ADC trigger is enabled. #define GPTM_TIMER_CTL_RTCEN ((unsigned int)0x01 << 4) // GPTM RTC Enable @@ -106,7 +101,7 @@ typedef struct GPTM_TIMER_S { #define GPTM_TIMER_INT_CBEIM ((unsigned int)0x01 << 10) // GPTM CaptureB Event Interrupt Mask #define GPTM_TIMER_INT_CBMIM ((unsigned int)0x01 << 9) // GPTM CaptureB Match Interrupt Mask #define GPTM_TIMER_INT_TBTOIM ((unsigned int)0x01 << 8) // GPTM TimerB Time-Out Interrupt Mask -// -------- // +// -------- #define GPTM_TIMER_INT_RTCIM ((unsigned int)0x01 << 3) // GPTM RTC Interrupt Mask #define GPTM_TIMER_INT_CAEIM ((unsigned int)0x01 << 2) // GPTM CaptureA Event Interrupt Mask #define GPTM_TIMER_INT_CAMIM ((unsigned int)0x01 << 1) // GPTM CaptureA Match Interrupt Mask @@ -119,14 +114,14 @@ typedef struct GPTM_TIMER_S { // ***************************************************************************** typedef struct SYSTICK_S { - REG_DWORD Res0[1] ; // 0xE000E000 - REG_DWORD ICT ; // 0xE000E004 - REG_DWORD Res1[2] ; // 0xE000E008 - REG_DWORD STCTRL ; // 0xE000E010 - REG_DWORD STRELOAD ; // 0xE000E014 - REG_DWORD STCURRENT; // 0xE000E018 - REG_DWORD STCALIB ; // 0xE000E01C - REG_DWORD Res2[56] ; // 0xE000E020 + uint32_t Res0[1] ; // 0xE000E000 + __IO uint32_t ICT ; // 0xE000E004 + uint32_t Res1[2] ; // 0xE000E008 + __IO uint32_t STCTRL ; // 0xE000E010 + __IO uint32_t STRELOAD ; // 0xE000E014 + __IO uint32_t STCURRENT; // 0xE000E018 + __IO uint32_t STCALIB ; // 0xE000E01C + uint32_t Res2[56] ; // 0xE000E020 } SYSTICK_T, *PSYSTICK_T ; @@ -145,18 +140,18 @@ typedef struct SYSTICK_S { // ***************************************************************************** typedef struct NVIC_S { - REG_DWORD ISER[2] ; // 0xE000E100 - REG_DWORD Res3[30] ; // 0xE000E120 - REG_DWORD ICER[2] ; // 0xE000E180 - REG_DWORD Res4[30] ; // 0xE000E1A0 - REG_DWORD ISPR[2] ; // 0xE000E200 - REG_DWORD Res5[30] ; // 0xE000E220 - REG_DWORD ICPR[2] ; // 0xE000E280 - REG_DWORD Res6[30] ; // 0xE000E2A0 - REG_DWORD IABR[2] ; // 0xE000E300 - REG_DWORD Res7[64] ; // 0xE000E320 - REG_DWORD IPR[2] ; // 0xE000E400 - // REG_DWORD Res7[515] ; // 0xE000E4F4 + __IO uint32_t ISER[2] ; // 0xE000E100 + uint32_t Res3[30] ; // 0xE000E120 + __IO uint32_t ICER[2] ; // 0xE000E180 + uint32_t Res4[30] ; // 0xE000E1A0 + __IO uint32_t ISPR[2] ; // 0xE000E200 + uint32_t Res5[30] ; // 0xE000E220 + __IO uint32_t ICPR[2] ; // 0xE000E280 + uint32_t Res6[30] ; // 0xE000E2A0 + __IO uint32_t IABR[2] ; // 0xE000E300 + uint32_t Res7[64] ; // 0xE000E320 + __IO uint32_t IPR[2] ; // 0xE000E400 + // uint32_t Res7[515] ; // 0xE000E4F4 } NVIC_T, *PNVIC_T ; @@ -176,17 +171,17 @@ typedef struct NVIC_S { // ***************************************************************************** typedef struct SCB_S { - REG_DWORD CPUID ; // 0xE000ED00 - REG_DWORD ICSR ; // 0xE000ED04 - REG_DWORD VTOR ; // 0xE000ED08 - REG_DWORD AIRCR ; // 0xE000ED0C - REG_DWORD SCR ; // 0xE000ED10 - REG_DWORD CCR ; // 0xE000ED14 + __IO uint32_t CPUID ; // 0xE000ED00 + __IO uint32_t ICSR ; // 0xE000ED04 + __IO uint32_t VTOR ; // 0xE000ED08 + __IO uint32_t AIRCR ; // 0xE000ED0C + __IO uint32_t SCR ; // 0xE000ED10 + __IO uint32_t CCR ; // 0xE000ED14 - REG_DWORD SYS_PRIO[3] ; // 0xE000ED18 - REG_DWORD SYSHNDCTRL ; // 0xE000ED24 - //REG_DWORD FAULTSTAT ; // 0xE000ED28 - //REG_DWORD HFAULTSTAT ; // 0xE000ED2C + __IO uint32_t SYS_PRIO[3] ; // 0xE000ED18 + __IO uint32_t SYSHNDCTRL ; // 0xE000ED24 + //__IO uint32_t FAULTSTAT ; // 0xE000ED28 + //__IO uint32_t HFAULTSTAT ; // 0xE000ED2C } SCB_T, *PSCB_T ; diff --git a/platforms/rules.mk b/platforms/rules.mk index 7f0f767..2d2210d 100644 --- a/platforms/rules.mk +++ b/platforms/rules.mk @@ -20,6 +20,8 @@ all: target target: $(OBJS) $(LN) $(LFLAGS) $(LIBFLAGS) $(OBJS) $(LLIBS) -o $(TARGET_NAME).elf @echo $(TARGET_NAME).elf was compiled + arm-none-eabi-objcopy -O binary $(TARGET_NAME).elf $(TARGET_NAME).bin + arm-none-eabi-objdump -dxS $(TARGET_NAME).elf > $(TARGET_NAME).out clean: rm -f $(OBJS) diff --git a/ports/arm/types.h b/ports/arm/types.h index c07e295..d06e82f 100644 --- a/ports/arm/types.h +++ b/ports/arm/types.h @@ -48,6 +48,10 @@ typedef char int8_t ; #define INLINE __inline #endif +/* IO definitions (access restrictions to peripheral registers) */ +#define __I volatile /*!< defines 'read only' permissions */ +#define __O volatile /*!< defines 'write only' permissions */ +#define __IO volatile /*!< defines 'read / write' permissions */ #endif /* __TYPES_H__ */ diff --git a/ports/cortex_m/atomport_s.S b/ports/cortex_m/atomport_s.S index 2e25d93..0300234 100644 --- a/ports/cortex_m/atomport_s.S +++ b/ports/cortex_m/atomport_s.S @@ -45,7 +45,11 @@ .equ NVIC_INT_CTRL, 0xE000ED04 // Interrupt control state register .equ NVIC_PENDSVSET, 0x10000000 // Value to trigger PendSV exception .equ NVIC_PR_12_15_ADDR, 0xE000ED20 // System Handlers 12-15 Priority Register Address +#ifdef PLATFORM_QEMU_LM3S_HACK .equ NVIC_PENDS_VPRIORITY, 0x00F00000 // PendSV priority is minimal (0xFF -- 0x00FF0000) +#else +.equ NVIC_PENDS_VPRIORITY, 0x00FF0000 // PendSV priority is minimal (0xFF -- 0x00FF0000) +#endif #ifdef PLATFORM_QEMU_LM3S_HACK .equ NVIC_ISER, 0xE000E100 diff --git a/ports/cortex_m/types.h b/ports/cortex_m/types.h index c07e295..e6f927d 100644 --- a/ports/cortex_m/types.h +++ b/ports/cortex_m/types.h @@ -30,6 +30,7 @@ #ifndef __TYPES_H__ #define __TYPES_H__ +#ifndef _STDINT_H typedef unsigned int uintptr_t ; typedef int intptr_t ; typedef unsigned long long uint64_t ; @@ -39,6 +40,7 @@ typedef unsigned char uint8_t ; typedef int int32_t ; typedef short int16_t ; typedef char int8_t ; +#endif #ifndef OFFSETOF #define OFFSETOF(TYPE, MEMBER) ((int) &((TYPE *)0)->MEMBER) @@ -48,6 +50,10 @@ typedef char int8_t ; #define INLINE __inline #endif +/* IO definitions (access restrictions to peripheral registers) */ +#define __I volatile /*!< defines 'read only' permissions */ +#define __O volatile /*!< defines 'write only' permissions */ +#define __IO volatile /*!< defines 'read / write' permissions */ #endif /* __TYPES_H__ */ diff --git a/tests/stress1.c b/tests/stress1.c new file mode 100644 index 0000000..c27b01e --- /dev/null +++ b/tests/stress1.c @@ -0,0 +1,176 @@ +#include +#include "stress1.h" +#include "atom.h" +#include "atommutex.h" +#include "atomsem.h" +#include "atomport.h" +#include "atomport-tests.h" + + +#define MAX_TEST_THREADS 36 + +static unsigned char idle_stack[IDLE_STACK_BYTE_SIZE] ; +static unsigned char monitor_stack[MONITOR_STACK_BYTE_SIZE] ; +static unsigned char stress_test_stack[MAX_TEST_THREADS+1][TEST_STACK_BYTE_SIZE] ; +static unsigned int test_counter[MAX_TEST_THREADS+1] = {0} ; + + +//static unsigned char test_idle_stack[TEST_STACK_BYTE_SIZE] ; + + +static uint8_t test_prio[120] = { + 005,010,100,200,250, 200,200,200,200,200, + 150,150,150,150,150, 250,250,250,250,250, + 101,102,103,104,105, 202,204,206,208,210, + 150,150,150,150,150, 250,250,250,250,250, + 121,122,123,124,125, 061,063,065,067,061, + 150,150,150,150,150, 250,250,250,250,250, + 005,010,100,200,250, 200,200,200,200,200, + 150,150,150,150,150, 250,250,250,250,250, + 101,102,103,104,105, 202,204,206,208,210, + 150,150,150,150,150, 250,250,250,250,250, + 121,122,123,124,125, 061,063,065,067,061, + 150,150,150,150,150, 250,250,250,250,250, + }; + +static uint32_t test_interv[120] = { + 002,001,001,001,001, 002,003,004,005,006, + 015,015,015,015,015, 025,024,023,022,021, + 905,005,005,005,805, 050,051,052,053,054, + 015,015,015,015,015, 025,024,023,022,021, + 030,030,030,030,030, 070,071,072,073,474, + 005,006,007,007,001, 001,001,003,003,005, + 001,001,001,001,001, 002,003,004,005,006, + 015,015,015,015,015, 025,024,023,022,021, + 905,005,005,005,805, 050,051,052,053,054, + 015,015,015,015,015, 025,024,023,022,021, + 030,030,030,030,030, 070,071,072,073,474, + 005,006,007,007,001, 001,001,003,003,005, + }; + + +ATOM_TCB test_tcb[MAX_TEST_THREADS+1] ; +ATOM_TCB monitor_tcb ; +ATOM_TCB test2_tcb ; +ATOM_TCB test3_tcb ; +ATOM_TCB test_idle_tcb ; + +void +monitor_thread (uint32_t parm) +{ + CRITICAL_STORE; + int i ; + unsigned int counter = 0 ; + ATOM_TCB *tcb ; + uint32_t print_lines_count = 0 ; + + tcb = atomCurrentContext() ; + + if (parm) { + print_lines_count = ((parm-1)>>2) + 1; + } + + for (;;counter++) + { + uint32_t time = atomTimeGet() ; + + CRITICAL_START(); + ATOMLOG (_STR("\r\nMonitor %d threads # %d (%08d)\r\n"), parm, counter, (unsigned int)time) ; + ATOMLOG (_STR("------------------------------\r\n")) ; + //CRITICAL_END(); + + for (i=0; i MAX_TEST_THREADS) { + thread_count = MAX_TEST_THREADS ; + } + + ATOMLOG (_STR("\r\natomthreads_stress_test %.3d threads\r\n"), thread_count) ; + ATOMLOG (_STR("-----------------------------------\r\n")) ; + + + atomOSInit(&idle_stack[0], IDLE_STACK_BYTE_SIZE, TRUE) ; + for (i=0; i< thread_count;i++) { + atomThreadCreate ((ATOM_TCB *)&test_tcb[i], test_prio[i], stress_test_thread, i, + &stress_test_stack[i][0], TEST_STACK_BYTE_SIZE, TRUE); + } + + atomThreadCreate ((ATOM_TCB *)&monitor_tcb, 150, monitor_thread, thread_count, + &monitor_stack[0], MONITOR_STACK_BYTE_SIZE, TRUE); + + atomOSStart() ; +} diff --git a/tests/stress1.h b/tests/stress1.h new file mode 100644 index 0000000..303e867 --- /dev/null +++ b/tests/stress1.h @@ -0,0 +1,18 @@ +#ifndef __STRESS1_H__ +#define __STRESS1_H__ + +#include "types.h" + +#define TEST_STACK_BYTE_SIZE 0x200 +#define IDLE_STACK_BYTE_SIZE 0x200 +#define MONITOR_STACK_BYTE_SIZE 0x400 + +#ifndef TEST_THREADS +#define TEST_THREADS 16 +#endif + +extern void atomthreads_stress_test (uint32_t thread_count) ; +extern uint32_t test_start (void) ; + +#endif /* __STRESS1_H__ */ +