Merge remote-tracking branch 'upstream/master'

pull/54/head
ytsuboi 2013-09-03 19:38:34 +09:00
commit 0718c7671a
28 changed files with 791 additions and 263 deletions

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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")
}

View File

@ -4,7 +4,7 @@
MEMORY
{
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
@ -40,6 +40,9 @@ SECTIONS
.text :
{
KEEP(*(.isr_vector))
*(.text.Reset_Handler)
*(.text.SystemInit)
. = 0x200;
*(.text*)
KEEP(*(.init))

View File

@ -142,6 +142,7 @@ SECTIONS
/* Heap starts here and grows up in memory */
. = ALIGN( 8 ) ;
__heap_start__ = . ;
end = . ;
.stab 0 (NOLOAD) : { *(.stab) }
.stabstr 0 (NOLOAD) : { *(.stabstr) }

View File

@ -1,180 +1,149 @@
# 1 "vector_functions.s"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "vector_functions.s"
;
;
;
/* .include "vector_defns.h" */
# 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:
B __mbed_fiq
;
;
__mbed_undef:
LDR PC, =0x7fffffa0
;
;
__mbed_prefetch_abort:
LDR PC, =0x7fffffb0
;
;
__mbed_data_abort:
LDR PC, =0x7fffffc0
;
;
;
;
;
;
;
;
;
__mbed_irq:
;
MSR CPSR_c, #0x1F|0x80|0x40
;
STMDB sp!, {r0-r3,r12,lr}
;
MOV r0, #0xFFFFFF00
LDR r0, [r0]
;
MOV lr, pc
BX r0
;
MOV r0, #0xFFFFFF00
STR r0, [r0] ;
;
STR r0, [r0]
LDMFD sp!,{r0-r3,r12,lr}
;
MSR CPSR_c, #0x12|0x80|0x40
;
SUBS pc, lr, #4
;
;
;
;
__mbed_swi:
;
;
STMFD sp!, {a4, r4, ip, lr}
;
LDR r4, =0x40000040
;
;
LDR a4, =0x00940000
LDR PC, =0x7ffff820
;
;
;
;
__mbed_dcc_irq:
;
;
LDMFD sp!,{r0-r3,r12,lr}
;
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
STR LR, [LR, #0xf00]
;
;
;
;
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:
;
LDR R0, =(0x40000000 + 0x8000)
;
LDR R0, =( __SRAM_segment_end__ )
MSR CPSR_c, #0x1B|0x80|0x40
MOV SP, R0
SUB R0, R0, #0x00000040
;
MSR CPSR_c, #0x17|0x80|0x40
MOV SP, R0
SUB R0, R0, #0x00000040
;
MSR CPSR_c, #0x11|0x80|0x40
MOV SP, R0
SUB R0, R0, #0x00000000
;
MSR CPSR_c, #0x12|0x80|0x40
MOV SP, R0
SUB R0, R0, #0x00000040
;
MSR CPSR_c, #0x13|0x80|0x40
MOV SP, R0
SUB R0, R0, #0x00000040
;
MSR CPSR_c, #0x10
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
MOV LR, PC
BX R0
;
LDR R0, =__mbed_init
/* Go to Reset_Handler */
LDR R0, =Reset_Handler
BX R0

View File

@ -18,7 +18,7 @@
.section VECTOR_TABLE, "ax"
.section .vectors, "ax"
.arm
@ -34,7 +34,7 @@
;
__main:
_start:
LDR PC, =__mbed_reset
LDR PC, =__mbed_undef
LDR PC, =__mbed_swi

View File

@ -2,7 +2,7 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
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
@ -144,6 +144,8 @@ SECTIONS
/* Heap starts here and grows up in memory */
. = ALIGN( 8 ) ;
__heap_start__ = . ;
_pvHeapStart = . ;
end = . ;
.stab 0 (NOLOAD) : { *(.stab) }
.stabstr 0 (NOLOAD) : { *(.stabstr) }

View File

@ -1,180 +1,149 @@
# 1 "vector_functions.s"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "vector_functions.s"
;
;
;
/* .include "vector_defns.h" */
# 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:
B __mbed_fiq
;
;
__mbed_undef:
LDR PC, =0x7fffffa0
;
;
__mbed_prefetch_abort:
LDR PC, =0x7fffffb0
;
;
__mbed_data_abort:
LDR PC, =0x7fffffc0
;
;
;
;
;
;
;
;
;
__mbed_irq:
;
MSR CPSR_c, #0x1F|0x80|0x40
;
STMDB sp!, {r0-r3,r12,lr}
;
MOV r0, #0xFFFFFF00
LDR r0, [r0]
;
MOV lr, pc
BX r0
;
MOV r0, #0xFFFFFF00
STR r0, [r0] ;
;
STR r0, [r0]
LDMFD sp!,{r0-r3,r12,lr}
;
MSR CPSR_c, #0x12|0x80|0x40
;
SUBS pc, lr, #4
;
;
;
;
__mbed_swi:
;
;
STMFD sp!, {a4, r4, ip, lr}
;
LDR r4, =0x40000040
;
;
LDR a4, =0x00940000
LDR PC, =0x7ffff820
;
;
;
;
__mbed_dcc_irq:
;
;
LDMFD sp!,{r0-r3,r12,lr}
;
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
STR LR, [LR, #0xf00]
;
;
;
;
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:
;
LDR R0, =(0x40000000 + 0x8000)
;
LDR R0, =( __SRAM_segment_end__ )
MSR CPSR_c, #0x1B|0x80|0x40
MOV SP, R0
SUB R0, R0, #0x00000040
;
MSR CPSR_c, #0x17|0x80|0x40
MOV SP, R0
SUB R0, R0, #0x00000040
;
MSR CPSR_c, #0x11|0x80|0x40
MOV SP, R0
SUB R0, R0, #0x00000000
;
MSR CPSR_c, #0x12|0x80|0x40
MOV SP, R0
SUB R0, R0, #0x00000040
;
MSR CPSR_c, #0x13|0x80|0x40
MOV SP, R0
SUB R0, R0, #0x00000040
;
MSR CPSR_c, #0x10
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
MOV LR, PC
BX R0
;
LDR R0, =__mbed_init
/* Go to Reset_Handler */
LDR R0, =Reset_Handler
BX R0

View File

@ -18,7 +18,7 @@
.section VECTOR_TABLE, "ax"
.section .vectors, "ax"
.arm
@ -34,7 +34,7 @@
;
__main:
_start:
LDR PC, =__mbed_reset
LDR PC, =__mbed_undef
LDR PC, =__mbed_swi

View File

@ -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)
}
}

View File

@ -88,6 +88,10 @@
*/
#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
#define RXINTGROUP 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 */
u32_t lpc_last_tx_idx; /**< TX last descriptor index, zero-copy mode */
#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_mutex_t TXLockMutex; /**< TX critical section mutex */
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 pbuf *p = NULL;
u32_t idx, length;
u16_t origLength;
#ifdef LOCK_RX_THREAD
#if NO_SYS == 0
@ -428,6 +433,7 @@ static struct pbuf *lpc_low_level_input(struct netif *netif)
/* Zero-copy */
p = lpc_enetif->rxb[idx];
origLength = p->len;
p->len = (u16_t) length;
/* Free pbuf from descriptor */
@ -440,6 +446,7 @@ static struct pbuf *lpc_low_level_input(struct netif *netif)
LINK_STATS_INC(link.drop);
/* Re-queue the pbuf for receive */
p->len = origLength;
lpc_rxqueue_pbuf(lpc_enetif, p);
LWIP_DEBUGF(UDP_LPC_EMAC | LWIP_DBG_TRACE,
@ -780,8 +787,8 @@ void ENET_IRQHandler(void)
ints = LPC_EMAC->IntStatus;
if (ints & RXINTGROUP) {
/* RX group interrupt(s): Give semaphore to wakeup RX receive task.*/
sys_sem_signal(&lpc_enetdata.RxSem);
/* RX group interrupt(s): Give signal to wakeup RX receive task.*/
osSignalSet(lpc_enetdata.RxThread->id, RX_SIGNAL);
}
if (ints & TXINTGROUP) {
@ -807,7 +814,7 @@ static void packet_rx(void* pvParameters) {
while (1) {
/* Wait for receive task to wakeup */
sys_arch_sem_wait(&lpc_enetif->RxSem, 0);
osSignalWait(RX_SIGNAL, osWaitForever);
/* Process packets until all empty */
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));
/* Packet receive task */
err = sys_sem_new(&lpc_enetdata.RxSem, 0);
LWIP_ASSERT("RxSem creation error", (err == ERR_OK));
sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY);
lpc_enetdata.RxThread = sys_thread_new("receive_thread", packet_rx, netif->state, DEFAULT_THREAD_STACKSIZE, RX_PRIORITY);
LWIP_ASSERT("RxThread creation error", (lpc_enetdata.RxThread));
/* Transmit cleanup task */
err = sys_sem_new(&lpc_enetdata.TxCleanSem, 0);

View File

@ -82,8 +82,21 @@ typedef uintptr_t mem_ptr_t;
#define ALIGNED(n) __attribute__((aligned (n)))
#endif
/* Used with IP headers only */
#define LWIP_CHKSUM_ALGORITHM 1
/* Provide Thumb-2 routines for GCC to improve performance */
#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

View File

@ -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

View File

@ -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

View File

@ -998,6 +998,8 @@ pbuf_coalesce(struct pbuf *p, pbuf_layer layer)
}
err = pbuf_copy(q, p);
LWIP_ASSERT("pbuf_copy failed", err == ERR_OK);
/* next line references err variable even if LWIP_ASSERT is ignored. */
(void)err;
pbuf_free(p);
return q;
}

View File

@ -27,6 +27,8 @@
#if NO_SYS == 0
#include "cmsis_os.h"
#define SYS_LIGHTWEIGHT_PROT 1
#define LWIP_RAW 0
#define TCPIP_MBOX_SIZE 8
@ -99,6 +101,7 @@
#define MEMP_OVERFLOW_CHECK 1
#define MEMP_SANITY_CHECK 1
#else
#define LWIP_NOASSERT 1
#define LWIP_STATS 0
#endif

View File

@ -13,7 +13,7 @@ void flip_1() {
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
#elif defined(TARGET_KL05Z)
# define LED_NAME LED2

77
workspace_tools/hooks.py Normal file
View File

@ -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)
################################################################################

View File

@ -23,6 +23,8 @@ CORE_LABELS = {
"Cortex-M4" : "M4"
}
import os
import shutil
class Target:
def __init__(self):
@ -46,6 +48,8 @@ class Target:
def get_labels(self):
return [self.name, CORE_LABELS[self.core]] + self.extra_labels
def init_hooks(self, hook, toolchain_name):
pass
class LPC2368(Target):
def __init__(self):
@ -55,7 +59,7 @@ class LPC2368(Target):
self.extra_labels = ['NXP', 'LPC23XX']
self.supported_toolchains = ["ARM"]
self.supported_toolchains = ["ARM","GCC_ARM","GCC_CR"]
class LPC1768(Target):
@ -153,6 +157,42 @@ class LPC4088(Target):
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):
def __init__(self):
@ -241,6 +281,15 @@ class LPC11C24(Target):
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
TARGETS = [
@ -258,7 +307,9 @@ TARGETS = [
MBED_MCU(),
LPC1347(),
LPC1114(),
LPC11C24()
LPC11C24(),
LPC11U35_401(),
LPC4088_EA()
]
# Map each target name to its unique instance

View File

@ -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.settings import BUILD_OPTIONS
import workspace_tools.hooks as hooks
def print_notify(event):
# Default command line notification
@ -144,6 +145,7 @@ class mbedToolchain:
def __init__(self, target, options=None, notify=None):
self.target = target
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]])

View File

@ -19,7 +19,7 @@ from os.path import join
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.hooks import hook_tool
class ARM(mbedToolchain):
LINKER_EXT = '.sct'
@ -97,12 +97,13 @@ class ARM(mbedToolchain):
self.default_cmd([self.ar, '-r', lib_path] + objects)
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:
args.extend(["--scatter", mem_map])
self.default_cmd(self.ld + args + objects + libraries + self.sys_libs)
@hook_tool
def binary(self, elf, bin):
self.default_cmd([self.elf2bin, '--bin', '-o', bin, elf])

View File

@ -140,7 +140,7 @@ class GCC_ARM(GCC):
# Use latest gcc nanolib
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.sys_libs.append("nosys")