mirror of https://github.com/ARMmbed/mbed-os.git
Merge remote-tracking branch 'upstream/master'
commit
0718c7671a
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
LR_IROM1 0x00000000 0x8000 { ; load region size_region (32k)
|
||||||
|
ER_IROM1 0x00000000 0x8000 { ; load address = execution address
|
||||||
|
*.o (RESET, +First)
|
||||||
|
*(InRoot$$Sections)
|
||||||
|
.ANY (+RO)
|
||||||
|
}
|
||||||
|
; 8_byte_aligned(48 vect * 4 bytes) = 8_byte_aligned(0xC0) = 0xC0
|
||||||
|
; 6KB - 0xC0 = 0x1740
|
||||||
|
RW_IRAM1 0x100000C0 0x1740 {
|
||||||
|
.ANY (+RW +ZI)
|
||||||
|
}
|
||||||
|
RW_IRAM2 0x20004000 0x800 { ; RW data, USB RAM
|
||||||
|
.ANY (USBRAM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
LR_IROM1 0x00000000 0x10000 { ; load region size_region (64k)
|
||||||
|
ER_IROM1 0x00000000 0x10000 { ; load address = execution address
|
||||||
|
*.o (RESET, +First)
|
||||||
|
*(InRoot$$Sections)
|
||||||
|
.ANY (+RO)
|
||||||
|
}
|
||||||
|
; 8_byte_aligned(48 vect * 4 bytes) = 8_byte_aligned(0xC0) = 0xC0
|
||||||
|
; 8KB - 0xC0 = 0x1F40
|
||||||
|
RW_IRAM1 0x100000C0 0x1F40 {
|
||||||
|
.ANY (+RW +ZI)
|
||||||
|
}
|
||||||
|
RW_IRAM2 0x20004000 0x800 { ; RW data, USB RAM
|
||||||
|
.ANY (USBRAM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
LR_IROM1 0x00000000 0x8000 { ; load region size_region (32k)
|
||||||
|
ER_IROM1 0x00000000 0x8000 { ; load address = execution address
|
||||||
|
*.o (RESET, +First)
|
||||||
|
*(InRoot$$Sections)
|
||||||
|
.ANY (+RO)
|
||||||
|
}
|
||||||
|
; 8_byte_aligned(48 vect * 4 bytes) = 8_byte_aligned(0xC0) = 0xC0
|
||||||
|
; 6KB - 0xC0 = 0x1740
|
||||||
|
RW_IRAM1 0x100000C0 0x1740 {
|
||||||
|
.ANY (+RW +ZI)
|
||||||
|
}
|
||||||
|
RW_IRAM2 0x20004000 0x800 { ; RW data, USB RAM
|
||||||
|
.ANY (USBRAM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
LR_IROM1 0x00000000 0x10000 { ; load region size_region (64k)
|
||||||
|
ER_IROM1 0x00000000 0x10000 { ; load address = execution address
|
||||||
|
*.o (RESET, +First)
|
||||||
|
*(InRoot$$Sections)
|
||||||
|
.ANY (+RO)
|
||||||
|
}
|
||||||
|
; 8_byte_aligned(48 vect * 4 bytes) = 8_byte_aligned(0xC0) = 0xC0
|
||||||
|
; 8KB - 0xC0 = 0x1F40
|
||||||
|
RW_IRAM1 0x100000C0 0x1F40 {
|
||||||
|
.ANY (+RW +ZI)
|
||||||
|
}
|
||||||
|
RW_IRAM2 0x20004000 0x800 { ; RW data, USB RAM
|
||||||
|
.ANY (USBRAM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
/* Linker script to configure memory regions. */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 64K
|
||||||
|
RAM (rwx) : ORIGIN = 0x100000C0, LENGTH = 0x1F40
|
||||||
|
USB_RAM (rwx): ORIGIN = 0x20004000, LENGTH = 0x800
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Linker script to place sections and symbol values. Should be used together
|
||||||
|
* with other linker script that defines memory regions FLASH and RAM.
|
||||||
|
* It references following symbols, which must be defined in code:
|
||||||
|
* Reset_Handler : Entry of reset handler
|
||||||
|
*
|
||||||
|
* It defines following symbols, which code can use without definition:
|
||||||
|
* __exidx_start
|
||||||
|
* __exidx_end
|
||||||
|
* __etext
|
||||||
|
* __data_start__
|
||||||
|
* __preinit_array_start
|
||||||
|
* __preinit_array_end
|
||||||
|
* __init_array_start
|
||||||
|
* __init_array_end
|
||||||
|
* __fini_array_start
|
||||||
|
* __fini_array_end
|
||||||
|
* __data_end__
|
||||||
|
* __bss_start__
|
||||||
|
* __bss_end__
|
||||||
|
* __end__
|
||||||
|
* end
|
||||||
|
* __HeapLimit
|
||||||
|
* __StackLimit
|
||||||
|
* __StackTop
|
||||||
|
* __stack
|
||||||
|
*/
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
KEEP(*(.isr_vector))
|
||||||
|
*(.text.Reset_Handler)
|
||||||
|
*(.text.SystemInit)
|
||||||
|
|
||||||
|
/* Only vectors and code running at reset are safe to be in first 512
|
||||||
|
bytes since RAM can be mapped into this area for RAM based interrupt
|
||||||
|
vectors. */
|
||||||
|
. = 0x00000200;
|
||||||
|
*(.text*)
|
||||||
|
|
||||||
|
KEEP(*(.init))
|
||||||
|
KEEP(*(.fini))
|
||||||
|
|
||||||
|
/* .ctors */
|
||||||
|
*crtbegin.o(.ctors)
|
||||||
|
*crtbegin?.o(.ctors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||||
|
*(SORT(.ctors.*))
|
||||||
|
*(.ctors)
|
||||||
|
|
||||||
|
/* .dtors */
|
||||||
|
*crtbegin.o(.dtors)
|
||||||
|
*crtbegin?.o(.dtors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||||
|
*(SORT(.dtors.*))
|
||||||
|
*(.dtors)
|
||||||
|
|
||||||
|
*(.rodata*)
|
||||||
|
|
||||||
|
KEEP(*(.eh_frame*))
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.ARM.extab :
|
||||||
|
{
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
__exidx_start = .;
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > FLASH
|
||||||
|
__exidx_end = .;
|
||||||
|
|
||||||
|
__etext = .;
|
||||||
|
|
||||||
|
.data : AT (__etext)
|
||||||
|
{
|
||||||
|
__data_start__ = .;
|
||||||
|
*(vtable)
|
||||||
|
*(.data*)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* preinit data */
|
||||||
|
PROVIDE (__preinit_array_start = .);
|
||||||
|
KEEP(*(.preinit_array))
|
||||||
|
PROVIDE (__preinit_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* init data */
|
||||||
|
PROVIDE (__init_array_start = .);
|
||||||
|
KEEP(*(SORT(.init_array.*)))
|
||||||
|
KEEP(*(.init_array))
|
||||||
|
PROVIDE (__init_array_end = .);
|
||||||
|
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* finit data */
|
||||||
|
PROVIDE (__fini_array_start = .);
|
||||||
|
KEEP(*(SORT(.fini_array.*)))
|
||||||
|
KEEP(*(.fini_array))
|
||||||
|
PROVIDE (__fini_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* All data end */
|
||||||
|
__data_end__ = .;
|
||||||
|
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
__bss_end__ = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.heap :
|
||||||
|
{
|
||||||
|
__end__ = .;
|
||||||
|
end = __end__;
|
||||||
|
*(.heap*)
|
||||||
|
__HeapLimit = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* .stack_dummy section doesn't contains any symbols. It is only
|
||||||
|
* used for linker to calculate size of stack sections, and assign
|
||||||
|
* values to stack symbols later */
|
||||||
|
.stack_dummy :
|
||||||
|
{
|
||||||
|
*(.stack)
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* Set stack top to end of RAM, and stack limit move down by
|
||||||
|
* size of stack_dummy section */
|
||||||
|
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
|
||||||
|
PROVIDE(__stack = __StackTop);
|
||||||
|
|
||||||
|
/* Check if data + heap + stack exceeds RAM limit */
|
||||||
|
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 32K
|
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 32K
|
||||||
RAM (rwx) : ORIGIN = 0x10000000, LENGTH = 2K
|
RAM (rwx) : ORIGIN = 0x100000C0, LENGTH = 0x0F40
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Linker script to place sections and symbol values. Should be used together
|
/* Linker script to place sections and symbol values. Should be used together
|
||||||
|
@ -40,6 +40,9 @@ SECTIONS
|
||||||
.text :
|
.text :
|
||||||
{
|
{
|
||||||
KEEP(*(.isr_vector))
|
KEEP(*(.isr_vector))
|
||||||
|
*(.text.Reset_Handler)
|
||||||
|
*(.text.SystemInit)
|
||||||
|
. = 0x200;
|
||||||
*(.text*)
|
*(.text*)
|
||||||
|
|
||||||
KEEP(*(.init))
|
KEEP(*(.init))
|
||||||
|
|
|
@ -142,6 +142,7 @@ SECTIONS
|
||||||
/* Heap starts here and grows up in memory */
|
/* Heap starts here and grows up in memory */
|
||||||
. = ALIGN( 8 ) ;
|
. = ALIGN( 8 ) ;
|
||||||
__heap_start__ = . ;
|
__heap_start__ = . ;
|
||||||
|
end = . ;
|
||||||
|
|
||||||
.stab 0 (NOLOAD) : { *(.stab) }
|
.stab 0 (NOLOAD) : { *(.stab) }
|
||||||
.stabstr 0 (NOLOAD) : { *(.stabstr) }
|
.stabstr 0 (NOLOAD) : { *(.stabstr) }
|
||||||
|
|
|
@ -1,180 +1,149 @@
|
||||||
# 1 "vector_functions.s"
|
/* .include "vector_defns.h" */
|
||||||
# 1 "<built-in>"
|
|
||||||
# 1 "<command line>"
|
|
||||||
# 1 "vector_functions.s"
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
|
|
||||||
# 1 "vector_defns.h" 1
|
|
||||||
# 6 "vector_functions.s" 2
|
|
||||||
|
.section .privileged_code, "ax"
|
||||||
|
.arm
|
||||||
|
|
||||||
|
|
||||||
|
.weak __mbed_fiq
|
||||||
|
.weak __mbed_undef
|
||||||
|
.weak __mbed_prefetch_abort
|
||||||
|
.weak __mbed_data_abort
|
||||||
|
.weak __mbed_irq
|
||||||
|
.weak __mbed_swi
|
||||||
|
.weak __mbed_dcc_irq
|
||||||
|
.weak __mbed_reset
|
||||||
|
.global __mbed_init_realmonitor
|
||||||
|
/* .global __mbed_init */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.section VECFUNCS, "ax"
|
|
||||||
.arm
|
|
||||||
|
|
||||||
|
|
||||||
.weak __mbed_fiq
|
|
||||||
.weak __mbed_undef
|
|
||||||
.weak __mbed_prefetch_abort
|
|
||||||
.weak __mbed_data_abort
|
|
||||||
.weak __mbed_irq
|
|
||||||
.weak __mbed_swi
|
|
||||||
.weak __mbed_dcc_irq
|
|
||||||
.weak __mbed_reset
|
|
||||||
.global __mbed_init_realmonitor
|
|
||||||
.global __mbed_init
|
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_fiq:
|
__mbed_fiq:
|
||||||
B __mbed_fiq
|
B __mbed_fiq
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_undef:
|
__mbed_undef:
|
||||||
LDR PC, =0x7fffffa0
|
LDR PC, =0x7fffffa0
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_prefetch_abort:
|
__mbed_prefetch_abort:
|
||||||
LDR PC, =0x7fffffb0
|
LDR PC, =0x7fffffb0
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_data_abort:
|
__mbed_data_abort:
|
||||||
LDR PC, =0x7fffffc0
|
LDR PC, =0x7fffffc0
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_irq:
|
__mbed_irq:
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x1F|0x80|0x40
|
MSR CPSR_c, #0x1F|0x80|0x40
|
||||||
|
|
||||||
;
|
|
||||||
STMDB sp!, {r0-r3,r12,lr}
|
STMDB sp!, {r0-r3,r12,lr}
|
||||||
|
|
||||||
;
|
|
||||||
MOV r0, #0xFFFFFF00
|
MOV r0, #0xFFFFFF00
|
||||||
LDR r0, [r0]
|
LDR r0, [r0]
|
||||||
|
|
||||||
;
|
|
||||||
MOV lr, pc
|
MOV lr, pc
|
||||||
BX r0
|
BX r0
|
||||||
|
|
||||||
;
|
|
||||||
MOV r0, #0xFFFFFF00
|
MOV r0, #0xFFFFFF00
|
||||||
STR r0, [r0] ;
|
STR r0, [r0]
|
||||||
|
|
||||||
;
|
|
||||||
LDMFD sp!,{r0-r3,r12,lr}
|
LDMFD sp!,{r0-r3,r12,lr}
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x12|0x80|0x40
|
MSR CPSR_c, #0x12|0x80|0x40
|
||||||
|
|
||||||
;
|
|
||||||
SUBS pc, lr, #4
|
SUBS pc, lr, #4
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_swi:
|
__mbed_swi:
|
||||||
;
|
|
||||||
;
|
|
||||||
STMFD sp!, {a4, r4, ip, lr}
|
STMFD sp!, {a4, r4, ip, lr}
|
||||||
|
|
||||||
;
|
|
||||||
LDR r4, =0x40000040
|
LDR r4, =0x40000040
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
LDR a4, =0x00940000
|
LDR a4, =0x00940000
|
||||||
LDR PC, =0x7ffff820
|
LDR PC, =0x7ffff820
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_dcc_irq:
|
__mbed_dcc_irq:
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
;
|
|
||||||
LDMFD sp!,{r0-r3,r12,lr}
|
LDMFD sp!,{r0-r3,r12,lr}
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x12|0x80|0x40
|
MSR CPSR_c, #0x12|0x80|0x40
|
||||||
|
|
||||||
;
|
SUB lr, lr, #4
|
||||||
|
STMFD sp!, {ip,lr}
|
||||||
|
|
||||||
;
|
|
||||||
SUB lr, lr, #4 ;
|
|
||||||
STMFD sp!, {ip,lr} ;
|
|
||||||
|
|
||||||
;
|
|
||||||
LDR LR, =0xfffff000
|
LDR LR, =0xfffff000
|
||||||
STR LR, [LR, #0xf00]
|
STR LR, [LR, #0xf00]
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
LDR PC, =0x7fffffe0
|
LDR PC, =0x7fffffe0
|
||||||
|
/*
|
||||||
|
__mbed_reset is called after reset
|
||||||
|
we setup the stacks and realmonitor, then call Reset_Handler like on M3
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section .text, "ax"
|
||||||
|
.arm
|
||||||
|
.global Reset_handler
|
||||||
|
Reset_Handler:
|
||||||
|
.extern __libc_init_array
|
||||||
|
.extern SystemInit
|
||||||
|
.extern __wrap_main
|
||||||
|
LDR R0, =SystemInit
|
||||||
|
MOV LR, PC
|
||||||
|
BX R0
|
||||||
|
|
||||||
|
LDR R0, =__libc_init_array
|
||||||
|
MOV LR, PC
|
||||||
|
BX R0
|
||||||
|
|
||||||
|
LDR R0, =__wrap_main
|
||||||
|
BX R0
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_reset:
|
__mbed_reset:
|
||||||
|
LDR R0, =( __SRAM_segment_end__ )
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
LDR R0, =(0x40000000 + 0x8000)
|
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x1B|0x80|0x40
|
MSR CPSR_c, #0x1B|0x80|0x40
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
SUB R0, R0, #0x00000040
|
SUB R0, R0, #0x00000040
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x17|0x80|0x40
|
MSR CPSR_c, #0x17|0x80|0x40
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
SUB R0, R0, #0x00000040
|
SUB R0, R0, #0x00000040
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x11|0x80|0x40
|
MSR CPSR_c, #0x11|0x80|0x40
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
SUB R0, R0, #0x00000000
|
SUB R0, R0, #0x00000000
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x12|0x80|0x40
|
MSR CPSR_c, #0x12|0x80|0x40
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
SUB R0, R0, #0x00000040
|
SUB R0, R0, #0x00000040
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x13|0x80|0x40
|
MSR CPSR_c, #0x13|0x80|0x40
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
SUB R0, R0, #0x00000040
|
SUB R0, R0, #0x00000040
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x10
|
MSR CPSR_c, #0x10
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
|
|
||||||
;
|
/* Relocate .data section (Copy from ROM to RAM) */
|
||||||
|
LDR R1, =__text_end__ /* _etext */
|
||||||
|
LDR R2, =__data_start__ /* _data */
|
||||||
|
LDR R3, =__data_end__ /* _edata */
|
||||||
|
CMP R2, R3
|
||||||
|
BEQ DataIsEmpty
|
||||||
|
LoopRel: CMP R2, R3
|
||||||
|
LDRLO R0, [R1], #4
|
||||||
|
STRLO R0, [R2], #4
|
||||||
|
BLO LoopRel
|
||||||
|
DataIsEmpty:
|
||||||
|
|
||||||
|
/* Clear .bss section (Zero init) */
|
||||||
|
MOV R0, #0
|
||||||
|
LDR R1, =__bss_start__
|
||||||
|
LDR R2, =__bss_end__
|
||||||
|
CMP R1,R2
|
||||||
|
BEQ BSSIsEmpty
|
||||||
|
LoopZI: CMP R1, R2
|
||||||
|
STRLO R0, [R1], #4
|
||||||
|
BLO LoopZI
|
||||||
|
BSSIsEmpty:
|
||||||
|
|
||||||
|
|
||||||
|
/* Init realmonitor */
|
||||||
LDR R0, =__mbed_init_realmonitor
|
LDR R0, =__mbed_init_realmonitor
|
||||||
MOV LR, PC
|
MOV LR, PC
|
||||||
BX R0
|
BX R0
|
||||||
|
|
||||||
;
|
/* Go to Reset_Handler */
|
||||||
LDR R0, =__mbed_init
|
LDR R0, =Reset_Handler
|
||||||
BX R0
|
BX R0
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.section VECTOR_TABLE, "ax"
|
.section .vectors, "ax"
|
||||||
.arm
|
.arm
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
__main:
|
_start:
|
||||||
LDR PC, =__mbed_reset
|
LDR PC, =__mbed_reset
|
||||||
LDR PC, =__mbed_undef
|
LDR PC, =__mbed_undef
|
||||||
LDR PC, =__mbed_swi
|
LDR PC, =__mbed_swi
|
||||||
|
|
|
@ -2,7 +2,7 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||||
OUTPUT_ARCH(arm)
|
OUTPUT_ARCH(arm)
|
||||||
ENTRY(vectors)
|
ENTRY(vectors)
|
||||||
|
|
||||||
GROUP(-lsupc++ -lm -lc -lgcc)
|
GROUP( libgcc.a libc.a libm.a libcr_newlib_nohost.a crti.o crtn.o crtbegin.o crtend.o )
|
||||||
|
|
||||||
/* Memory Definitions: */
|
/* Memory Definitions: */
|
||||||
MEMORY
|
MEMORY
|
||||||
|
@ -144,6 +144,8 @@ SECTIONS
|
||||||
/* Heap starts here and grows up in memory */
|
/* Heap starts here and grows up in memory */
|
||||||
. = ALIGN( 8 ) ;
|
. = ALIGN( 8 ) ;
|
||||||
__heap_start__ = . ;
|
__heap_start__ = . ;
|
||||||
|
_pvHeapStart = . ;
|
||||||
|
end = . ;
|
||||||
|
|
||||||
.stab 0 (NOLOAD) : { *(.stab) }
|
.stab 0 (NOLOAD) : { *(.stab) }
|
||||||
.stabstr 0 (NOLOAD) : { *(.stabstr) }
|
.stabstr 0 (NOLOAD) : { *(.stabstr) }
|
||||||
|
|
|
@ -1,180 +1,149 @@
|
||||||
# 1 "vector_functions.s"
|
/* .include "vector_defns.h" */
|
||||||
# 1 "<built-in>"
|
|
||||||
# 1 "<command line>"
|
|
||||||
# 1 "vector_functions.s"
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
|
|
||||||
# 1 "vector_defns.h" 1
|
|
||||||
# 6 "vector_functions.s" 2
|
|
||||||
|
.section .privileged_code, "ax"
|
||||||
|
.arm
|
||||||
|
|
||||||
|
|
||||||
|
.weak __mbed_fiq
|
||||||
|
.weak __mbed_undef
|
||||||
|
.weak __mbed_prefetch_abort
|
||||||
|
.weak __mbed_data_abort
|
||||||
|
.weak __mbed_irq
|
||||||
|
.weak __mbed_swi
|
||||||
|
.weak __mbed_dcc_irq
|
||||||
|
.weak __mbed_reset
|
||||||
|
.global __mbed_init_realmonitor
|
||||||
|
/* .global __mbed_init */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.section VECFUNCS, "ax"
|
|
||||||
.arm
|
|
||||||
|
|
||||||
|
|
||||||
.weak __mbed_fiq
|
|
||||||
.weak __mbed_undef
|
|
||||||
.weak __mbed_prefetch_abort
|
|
||||||
.weak __mbed_data_abort
|
|
||||||
.weak __mbed_irq
|
|
||||||
.weak __mbed_swi
|
|
||||||
.weak __mbed_dcc_irq
|
|
||||||
.weak __mbed_reset
|
|
||||||
.global __mbed_init_realmonitor
|
|
||||||
.global __mbed_init
|
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_fiq:
|
__mbed_fiq:
|
||||||
B __mbed_fiq
|
B __mbed_fiq
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_undef:
|
__mbed_undef:
|
||||||
LDR PC, =0x7fffffa0
|
LDR PC, =0x7fffffa0
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_prefetch_abort:
|
__mbed_prefetch_abort:
|
||||||
LDR PC, =0x7fffffb0
|
LDR PC, =0x7fffffb0
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_data_abort:
|
__mbed_data_abort:
|
||||||
LDR PC, =0x7fffffc0
|
LDR PC, =0x7fffffc0
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_irq:
|
__mbed_irq:
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x1F|0x80|0x40
|
MSR CPSR_c, #0x1F|0x80|0x40
|
||||||
|
|
||||||
;
|
|
||||||
STMDB sp!, {r0-r3,r12,lr}
|
STMDB sp!, {r0-r3,r12,lr}
|
||||||
|
|
||||||
;
|
|
||||||
MOV r0, #0xFFFFFF00
|
MOV r0, #0xFFFFFF00
|
||||||
LDR r0, [r0]
|
LDR r0, [r0]
|
||||||
|
|
||||||
;
|
|
||||||
MOV lr, pc
|
MOV lr, pc
|
||||||
BX r0
|
BX r0
|
||||||
|
|
||||||
;
|
|
||||||
MOV r0, #0xFFFFFF00
|
MOV r0, #0xFFFFFF00
|
||||||
STR r0, [r0] ;
|
STR r0, [r0]
|
||||||
|
|
||||||
;
|
|
||||||
LDMFD sp!,{r0-r3,r12,lr}
|
LDMFD sp!,{r0-r3,r12,lr}
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x12|0x80|0x40
|
MSR CPSR_c, #0x12|0x80|0x40
|
||||||
|
|
||||||
;
|
|
||||||
SUBS pc, lr, #4
|
SUBS pc, lr, #4
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_swi:
|
__mbed_swi:
|
||||||
;
|
|
||||||
;
|
|
||||||
STMFD sp!, {a4, r4, ip, lr}
|
STMFD sp!, {a4, r4, ip, lr}
|
||||||
|
|
||||||
;
|
|
||||||
LDR r4, =0x40000040
|
LDR r4, =0x40000040
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
LDR a4, =0x00940000
|
LDR a4, =0x00940000
|
||||||
LDR PC, =0x7ffff820
|
LDR PC, =0x7ffff820
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_dcc_irq:
|
__mbed_dcc_irq:
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
;
|
|
||||||
LDMFD sp!,{r0-r3,r12,lr}
|
LDMFD sp!,{r0-r3,r12,lr}
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x12|0x80|0x40
|
MSR CPSR_c, #0x12|0x80|0x40
|
||||||
|
|
||||||
;
|
SUB lr, lr, #4
|
||||||
|
STMFD sp!, {ip,lr}
|
||||||
|
|
||||||
;
|
|
||||||
SUB lr, lr, #4 ;
|
|
||||||
STMFD sp!, {ip,lr} ;
|
|
||||||
|
|
||||||
;
|
|
||||||
LDR LR, =0xfffff000
|
LDR LR, =0xfffff000
|
||||||
STR LR, [LR, #0xf00]
|
STR LR, [LR, #0xf00]
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
;
|
|
||||||
LDR PC, =0x7fffffe0
|
LDR PC, =0x7fffffe0
|
||||||
|
/*
|
||||||
|
__mbed_reset is called after reset
|
||||||
|
we setup the stacks and realmonitor, then call Reset_Handler like on M3
|
||||||
|
*/
|
||||||
|
|
||||||
|
.section .text, "ax"
|
||||||
|
.arm
|
||||||
|
.global Reset_handler
|
||||||
|
Reset_Handler:
|
||||||
|
.extern __libc_init_array
|
||||||
|
.extern SystemInit
|
||||||
|
.extern __wrap_main
|
||||||
|
LDR R0, =SystemInit
|
||||||
|
MOV LR, PC
|
||||||
|
BX R0
|
||||||
|
|
||||||
|
LDR R0, =__libc_init_array
|
||||||
|
MOV LR, PC
|
||||||
|
BX R0
|
||||||
|
|
||||||
|
LDR R0, =__wrap_main
|
||||||
|
BX R0
|
||||||
|
|
||||||
;
|
|
||||||
;
|
|
||||||
__mbed_reset:
|
__mbed_reset:
|
||||||
|
LDR R0, =( __SRAM_segment_end__ )
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
LDR R0, =(0x40000000 + 0x8000)
|
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x1B|0x80|0x40
|
MSR CPSR_c, #0x1B|0x80|0x40
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
SUB R0, R0, #0x00000040
|
SUB R0, R0, #0x00000040
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x17|0x80|0x40
|
MSR CPSR_c, #0x17|0x80|0x40
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
SUB R0, R0, #0x00000040
|
SUB R0, R0, #0x00000040
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x11|0x80|0x40
|
MSR CPSR_c, #0x11|0x80|0x40
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
SUB R0, R0, #0x00000000
|
SUB R0, R0, #0x00000000
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x12|0x80|0x40
|
MSR CPSR_c, #0x12|0x80|0x40
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
SUB R0, R0, #0x00000040
|
SUB R0, R0, #0x00000040
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x13|0x80|0x40
|
MSR CPSR_c, #0x13|0x80|0x40
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
SUB R0, R0, #0x00000040
|
SUB R0, R0, #0x00000040
|
||||||
|
|
||||||
;
|
|
||||||
MSR CPSR_c, #0x10
|
MSR CPSR_c, #0x10
|
||||||
MOV SP, R0
|
MOV SP, R0
|
||||||
|
|
||||||
;
|
/* Relocate .data section (Copy from ROM to RAM) */
|
||||||
|
LDR R1, =__text_end__ /* _etext */
|
||||||
|
LDR R2, =__data_start__ /* _data */
|
||||||
|
LDR R3, =__data_end__ /* _edata */
|
||||||
|
CMP R2, R3
|
||||||
|
BEQ DataIsEmpty
|
||||||
|
LoopRel: CMP R2, R3
|
||||||
|
LDRLO R0, [R1], #4
|
||||||
|
STRLO R0, [R2], #4
|
||||||
|
BLO LoopRel
|
||||||
|
DataIsEmpty:
|
||||||
|
|
||||||
|
/* Clear .bss section (Zero init) */
|
||||||
|
MOV R0, #0
|
||||||
|
LDR R1, =__bss_start__
|
||||||
|
LDR R2, =__bss_end__
|
||||||
|
CMP R1,R2
|
||||||
|
BEQ BSSIsEmpty
|
||||||
|
LoopZI: CMP R1, R2
|
||||||
|
STRLO R0, [R1], #4
|
||||||
|
BLO LoopZI
|
||||||
|
BSSIsEmpty:
|
||||||
|
|
||||||
|
|
||||||
|
/* Init realmonitor */
|
||||||
LDR R0, =__mbed_init_realmonitor
|
LDR R0, =__mbed_init_realmonitor
|
||||||
MOV LR, PC
|
MOV LR, PC
|
||||||
BX R0
|
BX R0
|
||||||
|
|
||||||
;
|
/* Go to Reset_Handler */
|
||||||
LDR R0, =__mbed_init
|
LDR R0, =Reset_Handler
|
||||||
BX R0
|
BX R0
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.section VECTOR_TABLE, "ax"
|
.section .vectors, "ax"
|
||||||
.arm
|
.arm
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
__main:
|
_start:
|
||||||
LDR PC, =__mbed_reset
|
LDR PC, =__mbed_reset
|
||||||
LDR PC, =__mbed_undef
|
LDR PC, =__mbed_undef
|
||||||
LDR PC, =__mbed_swi
|
LDR PC, =__mbed_swi
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
; *************************************************************
|
||||||
|
; *** Scatter-Loading Description File generated by uVision ***
|
||||||
|
; *************************************************************
|
||||||
|
|
||||||
|
LR_IROM1 0x00000000 0x00080000 { ; load region size_region
|
||||||
|
ER_IROM1 0x00000000 0x00080000 { ; load address = execution address
|
||||||
|
*.o (RESET, +First)
|
||||||
|
*(InRoot$$Sections)
|
||||||
|
.ANY (+RO)
|
||||||
|
}
|
||||||
|
RW_IRAM1 0x100000E8 0x0000FF18 { ; RW data
|
||||||
|
.ANY (+RW +ZI)
|
||||||
|
}
|
||||||
|
RW_IRAM2 0x20000000 0x00008000 {
|
||||||
|
.ANY (AHBSRAM1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LR_IROM2 0x28000000 0x01000000 {
|
||||||
|
ER_IROM2 0x28000000 0x01000000 { ; load address = execution address
|
||||||
|
.ANY (+RO)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -88,6 +88,10 @@
|
||||||
*/
|
*/
|
||||||
#define TXINTGROUP (EMAC_INT_TX_UNDERRUN | EMAC_INT_TX_ERR | EMAC_INT_TX_DONE)
|
#define TXINTGROUP (EMAC_INT_TX_UNDERRUN | EMAC_INT_TX_ERR | EMAC_INT_TX_DONE)
|
||||||
|
|
||||||
|
/** \brief Signal used for ethernet ISR to signal packet_rx() thread.
|
||||||
|
*/
|
||||||
|
#define RX_SIGNAL 1
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define RXINTGROUP 0
|
#define RXINTGROUP 0
|
||||||
#define TXINTGROUP 0
|
#define TXINTGROUP 0
|
||||||
|
@ -123,7 +127,7 @@ struct lpc_enetdata {
|
||||||
struct pbuf *txb[LPC_NUM_BUFF_TXDESCS]; /**< TX pbuf pointer list, zero-copy mode */
|
struct pbuf *txb[LPC_NUM_BUFF_TXDESCS]; /**< TX pbuf pointer list, zero-copy mode */
|
||||||
u32_t lpc_last_tx_idx; /**< TX last descriptor index, zero-copy mode */
|
u32_t lpc_last_tx_idx; /**< TX last descriptor index, zero-copy mode */
|
||||||
#if NO_SYS == 0
|
#if NO_SYS == 0
|
||||||
sys_sem_t RxSem; /**< RX receive thread wakeup semaphore */
|
sys_thread_t RxThread; /**< RX receive thread data object pointer */
|
||||||
sys_sem_t TxCleanSem; /**< TX cleanup thread wakeup semaphore */
|
sys_sem_t TxCleanSem; /**< TX cleanup thread wakeup semaphore */
|
||||||
sys_mutex_t TXLockMutex; /**< TX critical section mutex */
|
sys_mutex_t TXLockMutex; /**< TX critical section mutex */
|
||||||
sys_sem_t xTXDCountSem; /**< TX free buffer counting semaphore */
|
sys_sem_t xTXDCountSem; /**< TX free buffer counting semaphore */
|
||||||
|
@ -346,6 +350,7 @@ static struct pbuf *lpc_low_level_input(struct netif *netif)
|
||||||
struct lpc_enetdata *lpc_enetif = netif->state;
|
struct lpc_enetdata *lpc_enetif = netif->state;
|
||||||
struct pbuf *p = NULL;
|
struct pbuf *p = NULL;
|
||||||
u32_t idx, length;
|
u32_t idx, length;
|
||||||
|
u16_t origLength;
|
||||||
|
|
||||||
#ifdef LOCK_RX_THREAD
|
#ifdef LOCK_RX_THREAD
|
||||||
#if NO_SYS == 0
|
#if NO_SYS == 0
|
||||||
|
@ -428,6 +433,7 @@ static struct pbuf *lpc_low_level_input(struct netif *netif)
|
||||||
|
|
||||||
/* Zero-copy */
|
/* Zero-copy */
|
||||||
p = lpc_enetif->rxb[idx];
|
p = lpc_enetif->rxb[idx];
|
||||||
|
origLength = p->len;
|
||||||
p->len = (u16_t) length;
|
p->len = (u16_t) length;
|
||||||
|
|
||||||
/* Free pbuf from descriptor */
|
/* Free pbuf from descriptor */
|
||||||
|
@ -440,6 +446,7 @@ static struct pbuf *lpc_low_level_input(struct netif *netif)
|
||||||
LINK_STATS_INC(link.drop);
|
LINK_STATS_INC(link.drop);
|
||||||
|
|
||||||
/* Re-queue the pbuf for receive */
|
/* Re-queue the pbuf for receive */
|
||||||
|
p->len = origLength;
|
||||||
lpc_rxqueue_pbuf(lpc_enetif, p);
|
lpc_rxqueue_pbuf(lpc_enetif, p);
|
||||||
|
|
||||||
LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
|
LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
|
||||||
|
@ -780,8 +787,8 @@ void ENET_IRQHandler(void)
|
||||||
ints = LPC_EMAC->IntStatus;
|
ints = LPC_EMAC->IntStatus;
|
||||||
|
|
||||||
if (ints & RXINTGROUP) {
|
if (ints & RXINTGROUP) {
|
||||||
/* RX group interrupt(s): Give semaphore to wakeup RX receive task.*/
|
/* RX group interrupt(s): Give signal to wakeup RX receive task.*/
|
||||||
sys_sem_signal(&lpc_enetdata.RxSem);
|
osSignalSet(lpc_enetdata.RxThread->id, RX_SIGNAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ints & TXINTGROUP) {
|
if (ints & TXINTGROUP) {
|
||||||
|
@ -807,7 +814,7 @@ static void packet_rx(void* pvParameters) {
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Wait for receive task to wakeup */
|
/* Wait for receive task to wakeup */
|
||||||
sys_arch_sem_wait(&lpc_enetif->RxSem, 0);
|
osSignalWait(RX_SIGNAL, osWaitForever);
|
||||||
|
|
||||||
/* Process packets until all empty */
|
/* Process packets until all empty */
|
||||||
while (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex)
|
while (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex)
|
||||||
|
@ -1093,9 +1100,8 @@ err_t lpc_enetif_init(struct netif *netif)
|
||||||
LWIP_ASSERT("TXLockMutex creation error", (err == ERR_OK));
|
LWIP_ASSERT("TXLockMutex creation error", (err == ERR_OK));
|
||||||
|
|
||||||
/* Packet receive task */
|
/* Packet receive task */
|
||||||
err = sys_sem_new(&lpc_enetdata.RxSem, 0);
|
lpc_enetdata.RxThread = sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY);
|
||||||
LWIP_ASSERT("RxSem creation error", (err == ERR_OK));
|
LWIP_ASSERT("RxThread creation error", (lpc_enetdata.RxThread));
|
||||||
sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY);
|
|
||||||
|
|
||||||
/* Transmit cleanup task */
|
/* Transmit cleanup task */
|
||||||
err = sys_sem_new(&lpc_enetdata.TxCleanSem, 0);
|
err = sys_sem_new(&lpc_enetdata.TxCleanSem, 0);
|
||||||
|
|
|
@ -82,8 +82,21 @@ typedef uintptr_t mem_ptr_t;
|
||||||
#define ALIGNED(n) __attribute__((aligned (n)))
|
#define ALIGNED(n) __attribute__((aligned (n)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Used with IP headers only */
|
/* Provide Thumb-2 routines for GCC to improve performance */
|
||||||
#define LWIP_CHKSUM_ALGORITHM 1
|
#if defined(TOOLCHAIN_GCC) && defined(__thumb2__)
|
||||||
|
#define MEMCPY(dst,src,len) thumb2_memcpy(dst,src,len)
|
||||||
|
#define LWIP_CHKSUM thumb2_checksum
|
||||||
|
/* Set algorithm to 0 so that unused lwip_standard_chksum function
|
||||||
|
doesn't generate compiler warning */
|
||||||
|
#define LWIP_CHKSUM_ALGORITHM 0
|
||||||
|
|
||||||
|
void* thumb2_memcpy(void* pDest, const void* pSource, size_t length);
|
||||||
|
u16_t thumb2_checksum(void* pData, int length);
|
||||||
|
#else
|
||||||
|
/* Used with IP headers only */
|
||||||
|
#define LWIP_CHKSUM_ALGORITHM 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef LWIP_DEBUG
|
#ifdef LWIP_DEBUG
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
/* Copyright (C) 2013 - Adam Green (https://github.com/adamgreen)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
#if defined(TOOLCHAIN_GCC) && defined(__thumb2__)
|
||||||
|
|
||||||
|
|
||||||
|
/* This is a hand written Thumb-2 assembly language version of the
|
||||||
|
algorithm 3 version of lwip_standard_chksum in lwIP's inet_chksum.c. It
|
||||||
|
performs the checksumming 32-bits at a time and even unrolls the loop to
|
||||||
|
perform two of these 32-bit adds per loop iteration.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
16-bit 1's complement summation (not inversed).
|
||||||
|
|
||||||
|
NOTE: This function does return a uint16_t from the assembly language code
|
||||||
|
but is marked as void so that GCC doesn't issue warning because it
|
||||||
|
doesn't know about this low level return.
|
||||||
|
*/
|
||||||
|
__attribute__((naked)) void /*uint16_t*/ thumb2_checksum(const void* pData, int length)
|
||||||
|
{
|
||||||
|
__asm (
|
||||||
|
".syntax unified\n"
|
||||||
|
".thumb\n"
|
||||||
|
|
||||||
|
// Push non-volatile registers we use on stack. Push link register too to
|
||||||
|
// keep stack 8-byte aligned and allow single pop to restore and return.
|
||||||
|
" push {r4, lr}\n"
|
||||||
|
// Initialize sum, r2, to 0.
|
||||||
|
" movs r2, #0\n"
|
||||||
|
// Remember whether pData was at odd address in r3. This is used later to
|
||||||
|
// know if it needs to swap the result since the summation will be done at
|
||||||
|
// an offset of 1, rather than 0.
|
||||||
|
" ands r3, r0, #1\n"
|
||||||
|
// Need to 2-byte align? If not skip ahead.
|
||||||
|
" beq 1$\n"
|
||||||
|
// We can return if there are no bytes to sum.
|
||||||
|
" cbz r1, 9$\n"
|
||||||
|
|
||||||
|
// 2-byte align.
|
||||||
|
// Place the first data byte in odd summation location since it needs to be
|
||||||
|
// swapped later. It's ok to overwrite r2 here as it only had a value of 0
|
||||||
|
// up until now. Advance r0 pointer and decrement r1 length as we go.
|
||||||
|
" ldrb r2, [r0], #1\n"
|
||||||
|
" lsls r2, r2, #8\n"
|
||||||
|
" subs r1, r1, #1\n"
|
||||||
|
|
||||||
|
// Need to 4-byte align? If not skip ahead.
|
||||||
|
"1$:\n"
|
||||||
|
" ands r4, r0, #3\n"
|
||||||
|
" beq 2$\n"
|
||||||
|
// Have more than 1 byte left to align? If not skip ahead to take care of
|
||||||
|
// trailing byte.
|
||||||
|
" cmp r1, #2\n"
|
||||||
|
" blt 7$\n"
|
||||||
|
|
||||||
|
// 4-byte align.
|
||||||
|
" ldrh r4, [r0], #2\n"
|
||||||
|
" adds r2, r2, r4\n"
|
||||||
|
" subs r1, r1, #2\n"
|
||||||
|
|
||||||
|
// Main summing loop which sums up data 2 words at a time.
|
||||||
|
// Make sure that we have more than 7 bytes left to sum.
|
||||||
|
"2$:\n"
|
||||||
|
" cmp r1, #8\n"
|
||||||
|
" blt 3$\n"
|
||||||
|
// Sum next two words. Applying previous upper 16-bit carry to
|
||||||
|
// lower 16-bits.
|
||||||
|
" ldr r4, [r0], #4\n"
|
||||||
|
" adds r2, r4\n"
|
||||||
|
" adc r2, r2, #0\n"
|
||||||
|
" ldr r4, [r0], #4\n"
|
||||||
|
" adds r2, r4\n"
|
||||||
|
" adc r2, r2, #0\n"
|
||||||
|
" subs r1, r1, #8\n"
|
||||||
|
" b 2$\n"
|
||||||
|
|
||||||
|
// Sum up any remaining half-words.
|
||||||
|
"3$:\n"
|
||||||
|
// Make sure that we have more than 1 byte left to sum.
|
||||||
|
" cmp r1, #2\n"
|
||||||
|
" blt 7$\n"
|
||||||
|
// Sum up next half word, continue to apply carry.
|
||||||
|
" ldrh r4, [r0], #2\n"
|
||||||
|
" adds r2, r4\n"
|
||||||
|
" adc r2, r2, #0\n"
|
||||||
|
" subs r1, r1, #2\n"
|
||||||
|
" b 3$\n"
|
||||||
|
|
||||||
|
// Handle trailing byte, if it exists
|
||||||
|
"7$:\n"
|
||||||
|
" cbz r1, 8$\n"
|
||||||
|
" ldrb r4, [r0]\n"
|
||||||
|
" adds r2, r4\n"
|
||||||
|
" adc r2, r2, #0\n"
|
||||||
|
|
||||||
|
// Fold 32-bit checksum into 16-bit checksum.
|
||||||
|
"8$:\n"
|
||||||
|
" ubfx r4, r2, #16, #16\n"
|
||||||
|
" ubfx r2, r2, #0, #16\n"
|
||||||
|
" adds r2, r4\n"
|
||||||
|
" ubfx r4, r2, #16, #16\n"
|
||||||
|
" ubfx r2, r2, #0, #16\n"
|
||||||
|
" adds r2, r4\n"
|
||||||
|
|
||||||
|
// Swap bytes if started at odd address
|
||||||
|
" cbz r3, 9$\n"
|
||||||
|
" rev16 r2, r2\n"
|
||||||
|
|
||||||
|
// Return final sum.
|
||||||
|
"9$: mov r0, r2\n"
|
||||||
|
" pop {r4, pc}\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* Copyright (C) 2013 - Adam Green (https://github.com/adamgreen)
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
#if defined(TOOLCHAIN_GCC) && defined(__thumb2__)
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* This is a hand written Thumb-2 assembly language version of the
|
||||||
|
standard C memcpy() function that can be used by the lwIP networking
|
||||||
|
stack to improve its performance. It copies 4 bytes at a time and
|
||||||
|
unrolls the loop to perform 4 of these copies per loop iteration.
|
||||||
|
*/
|
||||||
|
__attribute__((naked)) void thumb2_memcpy(void* pDest, const void* pSource, size_t length)
|
||||||
|
{
|
||||||
|
__asm (
|
||||||
|
".syntax unified\n"
|
||||||
|
".thumb\n"
|
||||||
|
|
||||||
|
// Copy 16 bytes at a time first.
|
||||||
|
" lsrs r3, r2, #4\n"
|
||||||
|
" beq.n 2$\n"
|
||||||
|
"1$: ldr r12, [r1], #4\n"
|
||||||
|
" str r12, [r0], #4\n"
|
||||||
|
" ldr r12, [r1], #4\n"
|
||||||
|
" str r12, [r0], #4\n"
|
||||||
|
" ldr r12, [r1], #4\n"
|
||||||
|
" str r12, [r0], #4\n"
|
||||||
|
" ldr r12, [r1], #4\n"
|
||||||
|
" str r12, [r0], #4\n"
|
||||||
|
" subs r3, #1\n"
|
||||||
|
" bne 1$\n"
|
||||||
|
|
||||||
|
// Copy byte by byte for what is left.
|
||||||
|
"2$:\n"
|
||||||
|
" ands r3, r2, #0xf\n"
|
||||||
|
" beq.n 4$\n"
|
||||||
|
"3$: ldrb r12, [r1], #1\n"
|
||||||
|
" strb r12, [r0], #1\n"
|
||||||
|
" subs r3, #1\n"
|
||||||
|
" bne 3$\n"
|
||||||
|
|
||||||
|
// Return to caller.
|
||||||
|
"4$: bx lr\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -998,6 +998,8 @@ pbuf_coalesce(struct pbuf *p, pbuf_layer layer)
|
||||||
}
|
}
|
||||||
err = pbuf_copy(q, p);
|
err = pbuf_copy(q, p);
|
||||||
LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
|
LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
|
||||||
|
/* next line references err variable even if LWIP_ASSERT is ignored. */
|
||||||
|
(void)err;
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#if NO_SYS == 0
|
#if NO_SYS == 0
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
|
|
||||||
|
#define SYS_LIGHTWEIGHT_PROT 1
|
||||||
|
|
||||||
#define LWIP_RAW 0
|
#define LWIP_RAW 0
|
||||||
|
|
||||||
#define TCPIP_MBOX_SIZE 8
|
#define TCPIP_MBOX_SIZE 8
|
||||||
|
@ -99,6 +101,7 @@
|
||||||
#define MEMP_OVERFLOW_CHECK 1
|
#define MEMP_OVERFLOW_CHECK 1
|
||||||
#define MEMP_SANITY_CHECK 1
|
#define MEMP_SANITY_CHECK 1
|
||||||
#else
|
#else
|
||||||
|
#define LWIP_NOASSERT 1
|
||||||
#define LWIP_STATS 0
|
#define LWIP_STATS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ void flip_1() {
|
||||||
|
|
||||||
Ticker flipper_2;
|
Ticker flipper_2;
|
||||||
|
|
||||||
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088) || defined(TARGET_LPC1114)
|
#if defined(TARGET_LPC1768) || defined(TARGET_LPC11U24) || defined(TARGET_LPC4088) || defined(TARGET_LPC1114) || defined(TARGET_LPC2368)
|
||||||
# define LED_NAME LED2
|
# define LED_NAME LED2
|
||||||
#elif defined(TARGET_KL05Z)
|
#elif defined(TARGET_KL05Z)
|
||||||
# define LED_NAME LED2
|
# define LED_NAME LED2
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
# Configurable hooks in the build system. Can be used by various platforms
|
||||||
|
# to customize the build process.
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Hooks for the various parts of the build process
|
||||||
|
|
||||||
|
# Internal mapping of hooks per tool
|
||||||
|
_hooks = {}
|
||||||
|
|
||||||
|
# Internal mapping of running hooks
|
||||||
|
_running_hooks = {}
|
||||||
|
|
||||||
|
# Available hook types
|
||||||
|
_hook_types = ["binary"]
|
||||||
|
|
||||||
|
# Available hook steps
|
||||||
|
_hook_steps = ["pre", "replace", "post"]
|
||||||
|
|
||||||
|
# Hook the given function. Use this function as a decorator
|
||||||
|
def hook_tool(function):
|
||||||
|
tool = function.__name__
|
||||||
|
tool_flag = "_" + tool + "_done"
|
||||||
|
def wrapper(t_self, *args, **kwargs):
|
||||||
|
# if a hook for this tool is already running, it's most likely
|
||||||
|
# coming from a derived class, so don't hook the super class version
|
||||||
|
if _running_hooks.get(tool, False):
|
||||||
|
return function(t_self, *args, **kwargs)
|
||||||
|
_running_hooks[tool] = True
|
||||||
|
# If this tool isn't hooked, return original function
|
||||||
|
if not _hooks.has_key(tool):
|
||||||
|
res = function(t_self, *args, **kwargs)
|
||||||
|
_running_hooks[tool] = False
|
||||||
|
return res
|
||||||
|
tooldesc = _hooks[tool]
|
||||||
|
setattr(t_self, tool_flag, False)
|
||||||
|
# If there is a replace hook, execute the replacement instead
|
||||||
|
if tooldesc.has_key("replace"):
|
||||||
|
res = tooldesc["replace"](t_self, *args, **kwargs)
|
||||||
|
# If the replacement has set the "done" flag, exit now
|
||||||
|
# Otherwise continue as usual
|
||||||
|
if getattr(t_self, tool_flag, False):
|
||||||
|
_running_hooks[tool] = False
|
||||||
|
return res
|
||||||
|
# Execute pre-function before main function if specified
|
||||||
|
if tooldesc.has_key("pre"):
|
||||||
|
tooldesc["pre"](t_self, *args, **kwargs)
|
||||||
|
# Execute the main function now
|
||||||
|
res = function(t_self, *args, **kwargs)
|
||||||
|
# Execute post-function after main function if specified
|
||||||
|
if tooldesc.has_key("post"):
|
||||||
|
post_res = tooldesc["post"](t_self, *args, **kwargs)
|
||||||
|
_running_hooks[tool] = False
|
||||||
|
return post_res or res
|
||||||
|
else:
|
||||||
|
_running_hooks[tool] = False
|
||||||
|
return res
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
class Hook:
|
||||||
|
def __init__(self, target, toolchain):
|
||||||
|
_hooks.clear()
|
||||||
|
self.toolchain = toolchain
|
||||||
|
target.init_hooks(self, toolchain.__class__.__name__)
|
||||||
|
|
||||||
|
def hook_add(self, hook_type, hook_step, function):
|
||||||
|
if not hook_type in _hook_types or not hook_step in _hook_steps:
|
||||||
|
return False
|
||||||
|
if not hook_type in _hooks:
|
||||||
|
_hooks[hook_type] = {}
|
||||||
|
_hooks[hook_type][hook_step] = function
|
||||||
|
return True
|
||||||
|
|
||||||
|
def hook_add_binary(self, hook_step, function):
|
||||||
|
return self.hook_add("binary", hook_step, function)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
|
@ -23,6 +23,8 @@ CORE_LABELS = {
|
||||||
"Cortex-M4" : "M4"
|
"Cortex-M4" : "M4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
|
||||||
class Target:
|
class Target:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -46,6 +48,8 @@ class Target:
|
||||||
def get_labels(self):
|
def get_labels(self):
|
||||||
return [self.name, CORE_LABELS[self.core]] + self.extra_labels
|
return [self.name, CORE_LABELS[self.core]] + self.extra_labels
|
||||||
|
|
||||||
|
def init_hooks(self, hook, toolchain_name):
|
||||||
|
pass
|
||||||
|
|
||||||
class LPC2368(Target):
|
class LPC2368(Target):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -55,7 +59,7 @@ class LPC2368(Target):
|
||||||
|
|
||||||
self.extra_labels = ['NXP', 'LPC23XX']
|
self.extra_labels = ['NXP', 'LPC23XX']
|
||||||
|
|
||||||
self.supported_toolchains = ["ARM"]
|
self.supported_toolchains = ["ARM","GCC_ARM","GCC_CR"]
|
||||||
|
|
||||||
|
|
||||||
class LPC1768(Target):
|
class LPC1768(Target):
|
||||||
|
@ -153,6 +157,42 @@ class LPC4088(Target):
|
||||||
|
|
||||||
self.supported_toolchains = ["ARM", "GCC_CR"]
|
self.supported_toolchains = ["ARM", "GCC_CR"]
|
||||||
|
|
||||||
|
# Use this target to generate the custom binary image for LPC4088 EA boards
|
||||||
|
class LPC4088_EA(LPC4088):
|
||||||
|
def __init__(self):
|
||||||
|
LPC4088.__init__(self)
|
||||||
|
|
||||||
|
def init_hooks(self, hook, toolchain_name):
|
||||||
|
if toolchain_name in ['ARM_STD', 'ARM_MICRO']:
|
||||||
|
hook.hook_add_binary("post", self.binary_hook)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def binary_hook(t_self, elf, binf):
|
||||||
|
if not os.path.isdir(binf):
|
||||||
|
# Regular binary file, nothing to do
|
||||||
|
return
|
||||||
|
outbin = open(binf + ".temp", "wb")
|
||||||
|
partf = open(os.path.join(binf, "ER_IROM1"), "rb")
|
||||||
|
# Pad the fist part (internal flash) with 0xFF to 512k
|
||||||
|
data = partf.read()
|
||||||
|
outbin.write(data)
|
||||||
|
outbin.write('\xFF' * (512*1024 - len(data)))
|
||||||
|
partf.close()
|
||||||
|
# Read and append the second part (external flash) in chunks of fixed size
|
||||||
|
chunksize = 128 * 1024
|
||||||
|
partf = open(os.path.join(binf, "ER_IROM2"), "rb")
|
||||||
|
while True:
|
||||||
|
data = partf.read(chunksize)
|
||||||
|
outbin.write(data)
|
||||||
|
if len(data) < chunksize:
|
||||||
|
break
|
||||||
|
partf.close()
|
||||||
|
outbin.close()
|
||||||
|
# Remove the directory with the binary parts and rename the temporary
|
||||||
|
# file to 'binf'
|
||||||
|
shutil.rmtree(binf, True)
|
||||||
|
os.rename(binf + '.temp', binf)
|
||||||
|
t_self.debug("Generated custom binary file (internal flash + SPIFI)")
|
||||||
|
|
||||||
class LPC4330_M4(Target):
|
class LPC4330_M4(Target):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -241,6 +281,15 @@ class LPC11C24(Target):
|
||||||
|
|
||||||
self.supported_toolchains = ["ARM", "uARM", "GCC_ARM"]
|
self.supported_toolchains = ["ARM", "uARM", "GCC_ARM"]
|
||||||
|
|
||||||
|
class LPC11U35_401(Target):
|
||||||
|
def __init__(self):
|
||||||
|
Target.__init__(self)
|
||||||
|
|
||||||
|
self.core = "Cortex-M0"
|
||||||
|
|
||||||
|
self.extra_labels = ['NXP', 'LPC11UXX']
|
||||||
|
|
||||||
|
self.supported_toolchains = ["ARM", "uARM", "GCC_ARM"]
|
||||||
|
|
||||||
# Get a single instance for each target
|
# Get a single instance for each target
|
||||||
TARGETS = [
|
TARGETS = [
|
||||||
|
@ -258,7 +307,9 @@ TARGETS = [
|
||||||
MBED_MCU(),
|
MBED_MCU(),
|
||||||
LPC1347(),
|
LPC1347(),
|
||||||
LPC1114(),
|
LPC1114(),
|
||||||
LPC11C24()
|
LPC11C24(),
|
||||||
|
LPC11U35_401(),
|
||||||
|
LPC4088_EA()
|
||||||
]
|
]
|
||||||
|
|
||||||
# Map each target name to its unique instance
|
# Map each target name to its unique instance
|
||||||
|
|
|
@ -25,6 +25,7 @@ from workspace_tools.utils import run_cmd, mkdir, rel_path, ToolException, split
|
||||||
from workspace_tools.patch import patch
|
from workspace_tools.patch import patch
|
||||||
from workspace_tools.settings import BUILD_OPTIONS
|
from workspace_tools.settings import BUILD_OPTIONS
|
||||||
|
|
||||||
|
import workspace_tools.hooks as hooks
|
||||||
|
|
||||||
def print_notify(event):
|
def print_notify(event):
|
||||||
# Default command line notification
|
# Default command line notification
|
||||||
|
@ -144,6 +145,7 @@ class mbedToolchain:
|
||||||
def __init__(self, target, options=None, notify=None):
|
def __init__(self, target, options=None, notify=None):
|
||||||
self.target = target
|
self.target = target
|
||||||
self.name = self.__class__.__name__
|
self.name = self.__class__.__name__
|
||||||
|
self.hook = hooks.Hook(target, self)
|
||||||
|
|
||||||
self.legacy_ignore_dirs = LEGACY_IGNORE_DIRS - set([target.name, LEGACY_TOOLCHAIN_NAMES[self.name]])
|
self.legacy_ignore_dirs = LEGACY_IGNORE_DIRS - set([target.name, LEGACY_TOOLCHAIN_NAMES[self.name]])
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ from os.path import join
|
||||||
|
|
||||||
from workspace_tools.toolchains import mbedToolchain
|
from workspace_tools.toolchains import mbedToolchain
|
||||||
from workspace_tools.settings import ARM_BIN, ARM_INC, ARM_LIB, MY_ARM_CLIB, ARM_CPPLIB
|
from workspace_tools.settings import ARM_BIN, ARM_INC, ARM_LIB, MY_ARM_CLIB, ARM_CPPLIB
|
||||||
|
from workspace_tools.hooks import hook_tool
|
||||||
|
|
||||||
class ARM(mbedToolchain):
|
class ARM(mbedToolchain):
|
||||||
LINKER_EXT = '.sct'
|
LINKER_EXT = '.sct'
|
||||||
|
@ -97,12 +97,13 @@ class ARM(mbedToolchain):
|
||||||
self.default_cmd([self.ar, '-r', lib_path] + objects)
|
self.default_cmd([self.ar, '-r', lib_path] + objects)
|
||||||
|
|
||||||
def link(self, output, objects, libraries, lib_dirs, mem_map):
|
def link(self, output, objects, libraries, lib_dirs, mem_map):
|
||||||
args = ["-o", output, "--userlibpath", ",".join(lib_dirs), "--info=totals", "--list=.link_totals.txt"]
|
args = ["-o", output, "--userlibpath", ",".join(lib_dirs), "--info=totals", "--list=.link_totals.txt", "--any_placement=first_fit"]
|
||||||
if mem_map:
|
if mem_map:
|
||||||
args.extend(["--scatter", mem_map])
|
args.extend(["--scatter", mem_map])
|
||||||
|
|
||||||
self.default_cmd(self.ld + args + objects + libraries + self.sys_libs)
|
self.default_cmd(self.ld + args + objects + libraries + self.sys_libs)
|
||||||
|
|
||||||
|
@hook_tool
|
||||||
def binary(self, elf, bin):
|
def binary(self, elf, bin):
|
||||||
self.default_cmd([self.elf2bin, '--bin', '-o', bin, elf])
|
self.default_cmd([self.elf2bin, '--bin', '-o', bin, elf])
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ class GCC_ARM(GCC):
|
||||||
|
|
||||||
# Use latest gcc nanolib
|
# Use latest gcc nanolib
|
||||||
self.ld.append("--specs=nano.specs")
|
self.ld.append("--specs=nano.specs")
|
||||||
if target in ["LPC1768"]:
|
if target.name in ["LPC1768"]:
|
||||||
self.ld.extend(["-u", "_printf_float", "-u", "_scanf_float"])
|
self.ld.extend(["-u", "_printf_float", "-u", "_scanf_float"])
|
||||||
|
|
||||||
self.sys_libs.append("nosys")
|
self.sys_libs.append("nosys")
|
||||||
|
|
Loading…
Reference in New Issue