Merge pull request #409 from grissiom/lpc43xx

Lpc43xx
This commit is contained in:
Bernard Xiong committed 2015-01-09 10:00:25 +08:00
commit 56ab0995c1
49 files changed
+4103 -1179

No files matched your search

@@ -96,10 +96,10 @@ __Vectors DCD __initial_sp ; 0 Top of Stack
DCD ADC1_IRQHandler ; 37 ADC1
DCD SSP0_OR_SSP1_IRQHandler ; 38 SSP0 or SSP1
DCD EVENTROUTER_IRQHandler ; 39 Event router
DCD USART0_IRQHandler ; 40 USART0
DCD UART0_IRQHandler ; 40 USART0
DCD UART1_IRQHandler ; 41 UART1/Modem
DCD USART2_OR_C_CAN1_IRQHandler ; 42 USART2 or C CAN1
DCD USART3_IRQHandler ; 43 USART3
DCD UART2_OR_C_CAN1_IRQHandler ; 42 USART2 or C CAN1
DCD UART3_IRQHandler ; 43 USART3
DCD I2S0_OR_I2S1_OR_QEI_IRQHandler ; 44 I2S0 or I2S1 or QEI
DCD C_CAN0_IRQHandler ; 45 C CAN0
DCD 0 ; 46 Reserved
@@ -175,10 +175,10 @@ Default_Handler PROC
EXPORT ADC1_IRQHandler [WEAK]
EXPORT SSP0_OR_SSP1_IRQHandler [WEAK]
EXPORT EVENTROUTER_IRQHandler [WEAK]
EXPORT USART0_IRQHandler [WEAK]
EXPORT UART0_IRQHandler [WEAK]
EXPORT UART1_IRQHandler [WEAK]
EXPORT USART2_OR_C_CAN1_IRQHandler [WEAK]
EXPORT USART3_IRQHandler [WEAK]
EXPORT UART2_OR_C_CAN1_IRQHandler [WEAK]
EXPORT UART3_IRQHandler [WEAK]
EXPORT I2S0_OR_I2S1_OR_QEI_IRQHandler [WEAK]
EXPORT C_CAN0_IRQHandler [WEAK]
@@ -206,10 +206,10 @@ SPI_OR_DAC_IRQHandler
ADC1_IRQHandler
SSP0_OR_SSP1_IRQHandler
EVENTROUTER_IRQHandler
USART0_IRQHandler
UART0_IRQHandler
UART1_IRQHandler
USART2_OR_C_CAN1_IRQHandler
USART3_IRQHandler
UART2_OR_C_CAN1_IRQHandler
UART3_IRQHandler
I2S0_OR_I2S1_OR_QEI_IRQHandler
C_CAN0_IRQHandler
@@ -109,30 +109,56 @@ __interrupt_vector:
.type Reset_Handler, %function
Reset_Handler:
.fnstart
.ifdef RAM_MODE
/* 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
bhs BSSIsEmpty
str R0, [R1]
add R1, #4
blo LoopZI
BSSIsEmpty:
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* _sidata: LMA of start of the section to copy from. Usually end of text
* _sdata: VMA of start of the section to copy to
* _edata: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =_sidata
ldr r2, =_sdata
ldr r3, =_edata
subs r3, r2
ble .L_loop1_done
.L_loop1:
subs r3, #4
ldr r0, [r1,r3]
str r0, [r2,r3]
bgt .L_loop1
.L_loop1_done:
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start: start of the BSS section.
* __bss_end: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__bss_start
ldr r2, =__bss_end
movs r0, 0
subs r2, r1
ble .L_loop3_done
.L_loop3:
subs r2, #4
str r0, [r1, r2]
bgt .L_loop3
.L_loop3_done:
ldr R0, =SystemInit
blx R0
ldr R0,=main
bx R0
.else
ldr R0, =SystemInit
blx R0
ldr R0,=main
bx R0
.endif
.pool
.cantunwind
File diff suppressed because it is too large. Load diff
@@ -869,6 +869,7 @@ void SystemCoreClockUpdate (void) {
*----------------------------------------------------------------------------*/
void SystemInit (void) {
#ifdef BOOT_PROCESSOR
#if (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */
(3UL << 11*2) ); /* set CP11 Full Access */
@@ -880,9 +881,10 @@ void SystemInit (void) {
/* Configure PLL0 and PLL1, connect CPU clock to selected clock source */
SetClock();
/* Update SystemCoreClock variable */
SystemCoreClockUpdate();
/* Configure External Memory Controller */
SystemInit_ExtMemCtl ();
#endif
/* Update SystemCoreClock variable */
SystemCoreClockUpdate();
}
+10 -6
View File
@@ -2,12 +2,16 @@ from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(os.path.join(cwd, '..'))
for d in list:
if (d != 'M4' and d != 'M0'):
path = os.path.join(cwd, '..', d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(path, 'SConscript'))
for d in os.listdir(os.path.join(cwd, '..')):
if d not in ('M0', 'M4'):
path = os.path.join('..', d, 'SConscript')
if os.path.isfile(os.path.join(cwd, path)):
objs = objs + SConscript(os.path.join(cwd, path))
for d in os.listdir(cwd):
p = os.path.join(d, 'SConscript');
if os.path.isfile(os.path.join(cwd, p)):
objs = objs + SConscript(p)
Return('objs')
+19 -1
View File
@@ -5,7 +5,7 @@ import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.join(Dir('#').get_abspath(), '..', '..', 'rt-thread')
RTT_ROOT = os.path.join(Dir('#').get_abspath(), '..', '..', '..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
@@ -25,5 +25,23 @@ Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
if rtconfig.CROSS_TOOL == 'gcc':
import glob
# Remove the .o for M0 left on the drivers dir.
for i in glob.glob(GetCurrentDir() + '/../drivers/*.o'):
print 'RM %s' % i
os.unlink(i)
if sys.platform.startswith('linux'):
import glob
ocwd = os.getcwdu()
res = os.system('cd ../Libraries/; find -name \*.o -exec rm {} \;')
os.chdir(ocwd)
else:
# Assume Windows.
ocwd = os.getcwdu()
print 'TODO: remove the object files in ../Libraries'
os.chdir(ocwd)
# do building
DoBuilding(TARGET, objs)
File renamed without changes.
+121
View File
@@ -0,0 +1,121 @@
/*
* File : application.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2014, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2014-07-13 xiaonong port for lpc43xx
*/
#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>
#include "drv_led.h"
#ifdef RT_USING_FINSH
#include <finsh.h>
#include <shell.h>
#endif
#ifdef RT_USING_LOGTRACE
#include <log_trace.h>
#endif
#ifdef RT_USING_VBUS
#include <vbus.h>
#endif
/* thread phase init */
void rt_init_thread_entry(void *parameter)
{
#ifdef RT_USING_LOGTRACE
log_trace_init();
log_trace_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#ifdef RT_USING_FINSH
/* initialize finsh */
finsh_system_init();
finsh_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#ifdef RT_USING_VBUS
rt_vbus_do_init();
#endif
}
/*the led thread*/
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t led_stack[1024];
static struct rt_thread led_thread;
static void led_thread_entry(void *parameter)
{
rt_device_t led_dev;
rt_device_t vbus_dev;
rt_err_t err;
rt_led_hw_init();
led_dev = rt_device_find("led");
if (led_dev == RT_NULL)
{
rt_kprintf("can not find the led device\n");
return;
}
vbus_dev = rt_device_find("vecho");
if (vbus_dev == RT_NULL)
{
rt_kprintf("can not find the vbus device\n");
return;
}
err = rt_device_open(vbus_dev, RT_DEVICE_OFLAG_RDWR);
if (err != RT_EOK)
{
rt_kprintf("open vbus failed: %d\n", err);
return;
}
while (1)
{
rt_uint8_t led_value;
int len;
len = rt_device_read(vbus_dev, 0, &led_value, sizeof(led_value));
if (len <= 0)
{
rt_kprintf("vbus read err: %d, %d\n", len, rt_get_errno());
}
led_dev->write(led_dev, 1, &led_value, sizeof(led_value));
}
}
int rt_application_init(void)
{
rt_thread_t tid;
rt_err_t result;
tid = rt_thread_create("init",
rt_init_thread_entry, RT_NULL,
2048, 3, 20);
if (tid != RT_NULL)
rt_thread_startup(tid);
/* init led thread */
result = rt_thread_init(&led_thread, "led",
led_thread_entry, RT_NULL,
(rt_uint8_t *)&led_stack[0], sizeof(led_stack),
20, 5);
if (result == RT_EOK)
{
rt_thread_startup(&led_thread);
}
return 0;
}
+67
View File
@@ -0,0 +1,67 @@
/*
* File : board.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2014 RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard first implementation
* 2014-06-20 xiaonong ported to LPC43xx
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include "drv_uart.h"
/** M0 does not have SysTick so we have to use RIT timer for it... */
void RIT_OR_WWDT_IRQHandler(void)
{
/* enter interrupt */
rt_interrupt_enter();
if (LPC_RITIMER->CTRL & 0x01)
{
rt_tick_increase();
LPC_RITIMER->CTRL |= 0x01;
}
/* leave interrupt */
rt_interrupt_leave();
}
extern void SystemCoreClockUpdate(void);
/**
* This function will initial LPC43xx board.
*/
void rt_hw_board_init()
{
SystemCoreClockUpdate();
/* Setup RIT timer. */
LPC_RITIMER->MASK = 0;
LPC_RITIMER->COMPVAL = SystemCoreClock / RT_TICK_PER_SECOND;
/* Enable auto-clear. */
LPC_RITIMER->CTRL |= 1 << 1;
/* Reset the counter as the counter is enabled after reset. */
LPC_RITIMER->COUNTER = 0;
NVIC_SetPriority(M0_RITIMER_OR_WWDT_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
NVIC_EnableIRQ(M0_RITIMER_OR_WWDT_IRQn);
/* set pend exception priority */
NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
/* init uart device */
rt_hw_uart_init();
/* setup the console device */
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
}
+59
View File
@@ -0,0 +1,59 @@
/*
* File : board.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-09-22 Bernard add board.h to this bsp
* 2010-02-04 Magicoe add board.h to LPC176x bsp
* 2013-12-18 Bernard porting to LPC4088 bsp
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include "LPC43xx.h"
#include <rtthread.h>
/* disable SDRAM in default */
#ifndef LPC_EXT_SDRAM
#define LPC_EXT_SDRAM 0
#endif
// <RDTConfigurator URL="http://www.rt-thread.com/eclipse">
// <integer name="LPC_EXT_SDRAM" description="Begin Address of External SDRAM" default="0xA0000000" />
#define LPC_EXT_SDRAM_BEGIN 0xA0000000
// <integer name="LPC_EXT_SDRAM_END" description="End Address of External SDRAM" default="0xA2000000" />
#define LPC_EXT_SDRAM_END 0xA2000000
// <bool name="RT_USING_UART0" description="Using UART0" default="true" />
// <bool name="RT_USING_UART1" description="Using UART1" default="true" />
//#define RT_USING_UART1
// <bool name="RT_USING_UART2" description="Using UART2" default="true" />
//#define RT_USING_UART2
// </RDTConfigurator>
#ifdef __CC_ARM
extern int Image$$RW_IRAM2$$ZI$$Limit;
#define HEAP_BEGIN ((void *)&Image$$RW_IRAM2$$ZI$$Limit)
#elif __ICCARM__
#pragma section="HEAP"
#define HEAP_BEGIN (__segment_end("HEAP"))
#else
extern int __bss_end;
#define HEAP_BEGIN ((void *)&__bss_end)
#endif
#define HEAP_END (void*)(0x10080000 + 0x8000)
void rt_hw_board_init(void);
int rt_hw_board_heap_init(void);
int rt_vbus_do_init(void);
#endif
File renamed without changes.
+13
View File
@@ -0,0 +1,13 @@
#ifndef __VBUS_CONF_H__
#define __VBUS_CONF_H__
/* Number of blocks in VBus. The total size of VBus is
* RT_VMM_RB_BLK_NR * 64byte * 2. */
#define RT_VMM_RB_BLK_NR 20
/* We don't use the IRQ number to trigger IRQ in this BSP. */
#define RT_VBUS_GUEST_VIRQ 0
#define RT_VBUS_HOST_VIRQ 0
#endif /* end of include guard: __VBUS_CONF_H__ */
+86
View File
@@ -0,0 +1,86 @@
/*
* VMM Bus Driver
*
* COPYRIGHT (C) 2015, Shanghai Real-Thread Technology Co., Ltd
* http://www.rt-thread.com
*
* This file is part of RT-Thread (http://www.rt-thread.org)
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2015-01-07 Grissiom add comment
*/
#include <rtthread.h>
#ifdef RT_USING_VBUS
#include <rtdevice.h>
#include <vbus.h>
#include <board.h>
struct rt_vbus_ring rt_vbus_rings[2] SECTION("vbus_ring");
int rt_vbus_do_init(void)
{
return rt_vbus_init(&rt_vbus_rings[1], &rt_vbus_rings[0]);
}
INIT_COMPONENT_EXPORT(rt_vbus_do_init);
int rt_vbus_hw_init(void)
{
NVIC_ClearPendingIRQ(M0_M4CORE_IRQn);
NVIC_EnableIRQ(M0_M4CORE_IRQn);
return 0;
}
void M4CORE_IRQHandler(void)
{
LPC_CREG->M4TXEVENT = 0;
rt_vbus_isr(M0_M4CORE_IRQn, RT_NULL);
}
int rt_vbus_hw_eoi(int irqnr, void *param)
{
/* Nothing to do here as we cleared the interrupt in IRQHandler. */
return 0;
}
struct rt_vbus_dev rt_vbus_chn_devx[] = {
{
.req =
{
.prio = 30,
.name = "vecho",
.is_server = 0,
.recv_wm.low = RT_VMM_RB_BLK_NR / 3,
.recv_wm.high = RT_VMM_RB_BLK_NR * 2 / 3,
.post_wm.low = RT_VMM_RB_BLK_NR / 3,
.post_wm.high = RT_VMM_RB_BLK_NR * 2 / 3,
}
},
{
.req =
{
.name = RT_NULL,
}
},
};
#endif /* RT_USING_VBUS */
+53
View File
@@ -0,0 +1,53 @@
/*
* VMM Bus
*
* COPYRIGHT (C) 2015, Shanghai Real-Thread Technology Co., Ltd
*
* This file is part of RT-Thread (http://www.rt-thread.org)
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2015-01-07 Grissiom init commit
*/
#include <rtthread.h>
#include <board.h>
rt_inline void rt_vbus_tick(unsigned int target_cpu, unsigned int irqnr)
{
__SEV();
}
/* Read memory barrier. */
rt_inline void rt_vbus_smp_rmb(void)
{
__DMB();
}
/* Write memory barrier. */
rt_inline void rt_vbus_smp_wmb(void)
{
__DSB();
}
/* General memory barrier. */
rt_inline void rt_vbus_smp_mb(void)
{
__DSB();
}
+5 -2
View File
@@ -24,6 +24,7 @@
#define RT_DEBUG
// <bool name="RT_DEBUG_INIT" description="debug init enable" default=0 />
#define RT_DEBUG_INIT 0
//#define RT_DEBUG_SCHEDULER 1
// <bool name="RT_THREAD_DEBUG" description="Thread debug enable" default="false" />
// #define RT_THREAD_DEBUG
// <bool name="RT_USING_OVERFLOW_CHECK" description="Thread stack over flow detect" default="true" />
@@ -33,7 +34,7 @@
// <bool name="RT_USING_HOOK" description="Using hook functions" default="true" />
#define RT_USING_HOOK
// <section name="RT_USING_TIMER_SOFT" description="Using software timer which will start a thread to handle soft-timer" default="true" >
#define RT_USING_TIMER_SOFT
//#define RT_USING_TIMER_SOFT
// <integer name="RT_TIMER_THREAD_PRIO" description="The priority level of timer thread" default="4" />
#define RT_TIMER_THREAD_PRIO 4
// <integer name="RT_TIMER_THREAD_STACK_SIZE" description="The stack size of timer thread" default="512" />
@@ -96,6 +97,7 @@
#define RT_CONSOLEBUF_SIZE 128
// <string name="RT_CONSOLE_DEVICE_NAME" description="The device name for console" default="uart" />
#define RT_CONSOLE_DEVICE_NAME "uart0"
#define RT_USING_UART0
// </section>
// <bool name="RT_USING_COMPONENTS_INIT" description="Using RT-Thread components initialization" default="true" />
@@ -222,7 +224,8 @@
#define RT_LWIP_MSKADDR3 0
// </section>
#define RT_USING_VBUS
#define RT_USING_LOGTRACE
// </RDTConfigurator>
+11 -14
View File
@@ -2,15 +2,11 @@ import os
# core to be use
USE_CORE = 'CORE_M0'
#USE_CORE = 'CORE_M4'
# toolchains options
ARCH='arm'
if USE_CORE == 'CORE_M4':
CPU = 'cortex-m4'
else:
CPU = 'cortex-m0'
CPU = 'cortex-m0'
CROSS_TOOL='keil'
@@ -35,7 +31,7 @@ if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
#
BUILD = 'release'
BUILD = 'debug'
if PLATFORM == 'gcc':
# toolchains
@@ -48,23 +44,24 @@ if PLATFORM == 'gcc':
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcpu=' + CPU + ' -mthumb -ffunction-sections -fdata-sections'
if USE_CORE == 'CORE_M4':
DEVICE += ' -mfpu=fpv4-sp-d16 -mfloat-abi=softfp'
CFLAGS = DEVICE
DEVICE = ' -mthumb -mcpu=cortex-m0 -ffunction-sections -fdata-sections -Wall'
CFLAGS = DEVICE
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb '
LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-lpc43xx.map,-cref,-u,Reset_Handler -T rtthread-lpc43xx_spifi.ld'
LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-lpc43xx.map,-cref,-u,Reset_Handler -T rtthread-lpc43xx.ld'
CPATH = ''
LPATH = ''
CFLAGS += ' -gdwarf-2'
AFLAGS += ' -gdwarf-2'
if BUILD == 'debug':
CFLAGS += ' -O0 -gdwarf-2'
AFLAGS += ' -gdwarf-2'
CFLAGS += ' -O0'
else:
CFLAGS += ' -O2'
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' +\
SIZE + ' $TARGET \n' +\
'../bin2C.py rtthread.bin ../M4/applications/M0_CODE.h'
elif PLATFORM == 'armcc':
# toolchains
+139
View File
@@ -0,0 +1,139 @@
/*
* linker script for LPC43xx SPIFI (4Mb NorFlash, 32kB SRAM ) with GNU ld
* yiyue.fang 2012-04-14
*/
/* Program Entry, set to mark it as "used" and avoid gc */
MEMORY
{
CODE (rx) : ORIGIN = 0x1B000000, LENGTH = 0x00080000
DATA (rw) : ORIGIN = 0x10080000, LENGTH = 0x00008000
AHBRAM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000
}
ENTRY(Reset_Handler)
_system_stack_size = 0x200;
SECTIONS
{
.text :
{
. = ALIGN(4);
KEEP(*(.interrupt_vector)) /* Startup code */
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t*)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
. = ALIGN(4);
_etext = .;
} > CODE = 0
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
/* This is used by the startup in order to initialize the .data secion */
_sidata = .;
} > CODE
__exidx_end = .;
/* .data section which is used for initialized data */
.data : AT (_sidata)
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_sdata = . ;
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_edata = . ;
} >DATA
.stack :
{
. = . + _system_stack_size;
. = ALIGN(4);
_estack = .;
} >DATA
__bss_start = .;
.bss :
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_ebss = . ;
*(.bss.init)
} > DATA
__bss_end = .;
.vbus_ring (NOLOAD) :
{
*(vbus_ring)
} > AHBRAM
_end = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
+18
View File
@@ -0,0 +1,18 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM2 0x1B000000 0x00080000 { ; load region size_region
ER_IROM2 0x1B000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM2 0x10080000 0x00008000 { ; RW data
.ANY (+RW +ZI)
}
RW_AHBRAM 0x20000000 0x00010000 { ; RW data
* (vbus_ring)
}
}
File diff suppressed because it is too large. Load diff
+8
View File
@@ -0,0 +1,8 @@
#ifndef __VBUS_LOCAL_CONF_H__
#define __VBUS_LOCAL_CONF_H__
#define RT_VBUS_USING_FLOW_CONTROL
#define RT_VBUS_USING_TESTS
#endif /* end of include guard: __VBUS_LOCAL_CONF_H__ */
+10 -6
View File
@@ -2,12 +2,16 @@ from building import *
cwd = GetCurrentDir()
objs = []
list = os.listdir(os.path.join(cwd, '..'))
for d in list:
if (d != 'M4' and d != 'M0'):
path = os.path.join(cwd, '..', d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(path, 'SConscript'))
for d in os.listdir(os.path.join(cwd, '..')):
if d not in ('M0', 'M4'):
path = os.path.join('..', d, 'SConscript')
if os.path.isfile(os.path.join(cwd, path)):
objs = objs + SConscript(os.path.join(cwd, path))
for d in os.listdir(cwd):
p = os.path.join(d, 'SConscript');
if os.path.isfile(os.path.join(cwd, p)):
objs = objs + SConscript(p)
Return('objs')
+27 -2
View File
@@ -5,12 +5,12 @@ import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.join(Dir('#').get_abspath(), '..', '..', 'rt-thread')
RTT_ROOT = os.path.join(Dir('#').get_abspath(), '..', '..', '..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = 'rtthread-lpc40xx.' + rtconfig.TARGET_EXT
TARGET = 'build/rtthread_lpc43xx.' + rtconfig.TARGET_EXT
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
@@ -25,5 +25,30 @@ Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False)
if rtconfig.CROSS_TOOL == 'gcc':
print 'build M0 code first'
if sys.platform.startswith('linux'):
import glob
ocwd = os.getcwdu()
os.chdir('../M0')
res = os.system('scons')
if res:
print 'build M0 exit with code %d\n' % res
sys.exit(res)
os.chdir(ocwd)
res = os.system('cd ../Libraries/; find -name \*.o -exec rm {} \;')
os.chdir(ocwd)
else:
# Assume Windows.
ocwd = os.getcwdu()
os.chdir('..\M0')
os.system('scons.bat')
os.chdir(ocwd)
# Remove the .o for M0 left on the drivers dir.
for i in glob.glob(GetCurrentDir() + '/../drivers/*.o'):
print 'RM %s' % i
os.unlink(i)
# do building
DoBuilding(TARGET, objs)
+13
View File
@@ -0,0 +1,13 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = os.path.join(str(Dir('#')), 'applications')
src = Glob('*.c')
CPPPATH = [cwd, str(Dir('#'))]
group = DefineGroup('Applications', src,
depend = [''], CPPPATH = CPPPATH,
CPPDEFINES = ['BOOT_PROCESSOR'])
Return('group')
+156
View File
@@ -0,0 +1,156 @@
/*
* File : application.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2014, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2014-07-13 xiaonong port for lpc43xx
*/
#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>
#include "drv_led.h"
#ifdef RT_USING_FINSH
#include <finsh.h>
#include <shell.h>
#endif
#ifdef RT_USING_LOGTRACE
#include <log_trace.h>
#endif
#ifdef RT_USING_VBUS
#include <vbus.h>
#endif
static const unsigned char _M0_CODE[] SECTION("M0_CODE") = {
#include "M0_CODE.h"
};
static void _boot_M0(void)
{
volatile uint32_t u32REG, u32Val;
LPC_CREG->M0APPMEMMAP = (uint32_t)&_M0_CODE[0];
// Release Slave from reset, first read status
u32REG = LPC_RGU->RESET_ACTIVE_STATUS1;
// If the M0 is being held in reset, release it...
// 1 = no reset, 0 = reset
while(!(u32REG & (1u << 24)))
{
u32Val = (~(u32REG) & (~(1 << 24)));
LPC_RGU->RESET_CTRL1 = u32Val;
u32REG = LPC_RGU->RESET_ACTIVE_STATUS1;
}
rt_kprintf("M0 boot to %p\n", &_M0_CODE[0]);
}
/* thread phase init */
void rt_init_thread_entry(void *parameter)
{
/*
*register unsigned int _msp __asm("msp");
*register unsigned int _psp __asm("psp");
*rt_kprintf("msp@ %p, psp@ %p\n", _msp, _psp);
*/
#ifdef RT_USING_LOGTRACE
log_trace_init();
log_trace_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#ifdef RT_USING_FINSH
/* initialize finsh */
finsh_system_init();
finsh_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#ifdef RT_USING_VBUS
rt_vbus_do_init();
#endif
_boot_M0();
}
/*the led thread*/
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t led_stack[ 512 ];
static struct rt_thread led_thread;
static void led_thread_entry(void *parameter)
{
rt_uint8_t led_value;
rt_device_t led_dev;
rt_device_t vbus_dev;
rt_err_t err;
rt_led_hw_init();
led_dev = rt_device_find("led");
if (led_dev == RT_NULL)
{
rt_kprintf("can not find the led device\n");
return;
}
vbus_dev = rt_device_find("vecho");
if (vbus_dev == RT_NULL)
{
rt_kprintf("can not find the vbus device\n");
return;
}
err = rt_device_open(vbus_dev, RT_DEVICE_OFLAG_RDWR);
if (err != RT_EOK)
{
rt_kprintf("open vbus failed: %d\n", err);
return;
}
led_value = 0;
while (1)
{
int len;
led_dev->write(led_dev, 0, &led_value, sizeof(led_value));
led_value = !led_value;
len = rt_device_write(vbus_dev, 0, &led_value, sizeof(led_value));
if (len <= 0)
{
rt_kprintf("vbus write err: %d, %d\n", len, rt_get_errno());
}
rt_thread_delay(1000);
}
}
int rt_application_init(void)
{
rt_thread_t tid;
rt_err_t result;
tid = rt_thread_create("init",
rt_init_thread_entry, RT_NULL,
2048, 3, 20);
if (tid != RT_NULL)
rt_thread_startup(tid);
/* init led thread */
result = rt_thread_init(&led_thread, "led",
led_thread_entry, RT_NULL,
(rt_uint8_t *)&led_stack[0], sizeof(led_stack),
20, 5);
if (result == RT_EOK)
{
rt_thread_startup(&led_thread);
}
return 0;
}
@@ -43,20 +43,19 @@ void rt_hw_board_init()
{
#ifdef CORE_M4
/* NVIC Configuration */
#define NVIC_VTOR_MASK 0x3FFFFF80
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x10000000 */
SCB->VTOR = (0x10000000 & NVIC_VTOR_MASK);
SCB->VTOR = 0x10000000;
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x00000000 */
SCB->VTOR = (0x00000000 & NVIC_VTOR_MASK);
SCB->VTOR = 0x1A000000;
#endif
#endif
/* update the core clock */
SystemCoreClockUpdate();
/* init systick */
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND - 1);
SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
/* set pend exception priority */
NVIC_SetPriority(PendSV_IRQn, (1 << __NVIC_PRIO_BITS) - 1);
@@ -33,7 +33,6 @@
#define LPC_EXT_SDRAM_END 0xA2000000
// <bool name="RT_USING_UART0" description="Using UART0" default="true" />
#define RT_USING_UART0
// <bool name="RT_USING_UART1" description="Using UART1" default="true" />
//#define RT_USING_UART1
// <bool name="RT_USING_UART2" description="Using UART2" default="true" />
@@ -55,6 +54,6 @@ extern int __bss_end;
void rt_hw_board_init(void);
int rt_hw_board_heap_init(void);
int rt_vbus_do_init(void);
#endif
+74
View File
@@ -0,0 +1,74 @@
/*
* File : startup.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2009, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2009-01-05 Bernard first implementation
* 2014-07-13 xiaonong for LPC43xx
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
extern int rt_application_init(void);
/**
* This function will startup RT-Thread RTOS.
*/
void rtthread_startup(void)
{
/* initialize board */
rt_hw_board_init();
/* show version */
rt_show_version();
#ifdef RT_USING_HEAP
#if LPC_EXT_SDRAM
rt_system_heap_init((void *)LPC_EXT_SDRAM_BEGIN, (void *)LPC_EXT_SDRAM_END);
sram_init();
#else
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
#endif
/* initialize scheduler system */
rt_system_scheduler_init();
/* initialize system timer*/
rt_system_timer_init();
/* initialize application */
rt_application_init();
/* initialize timer thread */
rt_system_timer_thread_init();
/* initialize idle thread */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return ;
}
int main(void)
{
/* disable interrupt first */
rt_hw_interrupt_disable();
/* startup RT-Thread RTOS */
rtthread_startup();
return 0;
}
+13
View File
@@ -0,0 +1,13 @@
#ifndef __VBUS_CONF_H__
#define __VBUS_CONF_H__
/* Number of blocks in VBus. The total size of VBus is
* RT_VMM_RB_BLK_NR * 64byte * 2. */
#define RT_VMM_RB_BLK_NR 20
/* We don't use the IRQ number to trigger IRQ in this BSP. */
#define RT_VBUS_GUEST_VIRQ 0
#define RT_VBUS_HOST_VIRQ 0
#endif /* end of include guard: __VBUS_CONF_H__ */
+86
View File
@@ -0,0 +1,86 @@
/*
* VMM Bus Driver
*
* COPYRIGHT (C) 2015, Shanghai Real-Thread Technology Co., Ltd
* http://www.rt-thread.com
*
* This file is part of RT-Thread (http://www.rt-thread.org)
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2015-01-07 Grissiom add comment
*/
#include <rtthread.h>
#ifdef RT_USING_VBUS
#include <rtdevice.h>
#include <vbus.h>
#include <board.h>
struct rt_vbus_ring rt_vbus_rings[2] SECTION("vbus_ring");
int rt_vbus_do_init(void)
{
return rt_vbus_init(&rt_vbus_rings[0], &rt_vbus_rings[1]);
}
INIT_COMPONENT_EXPORT(rt_vbus_do_init);
int rt_vbus_hw_init(void)
{
NVIC_ClearPendingIRQ(M0CORE_IRQn);
NVIC_EnableIRQ(M0CORE_IRQn);
return 0;
}
void M0CORE_IRQHandler(void)
{
LPC_CREG->M0TXEVENT = 0;
rt_vbus_isr(M0CORE_IRQn, RT_NULL);
}
int rt_vbus_hw_eoi(int irqnr, void *param)
{
/* Nothing to do here as we cleared the interrupt in IRQHandler. */
return 0;
}
struct rt_vbus_dev rt_vbus_chn_devx[] = {
{
.req =
{
.prio = 30,
.name = "vecho",
.is_server = 1,
.recv_wm.low = RT_VMM_RB_BLK_NR / 3,
.recv_wm.high = RT_VMM_RB_BLK_NR * 2 / 3,
.post_wm.low = RT_VMM_RB_BLK_NR / 3,
.post_wm.high = RT_VMM_RB_BLK_NR * 2 / 3,
}
},
{
.req =
{
.name = RT_NULL,
}
},
};
#endif /* RT_USING_VBUS */
+53
View File
@@ -0,0 +1,53 @@
/*
* VMM Bus
*
* COPYRIGHT (C) 2015, Shanghai Real-Thread Technology Co., Ltd
*
* This file is part of RT-Thread (http://www.rt-thread.org)
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2015-01-07 Grissiom init commit
*/
#include <rtthread.h>
#include <board.h>
rt_inline void rt_vbus_tick(unsigned int target_cpu, unsigned int irqnr)
{
__SEV();
}
/* Read memory barrier. */
rt_inline void rt_vbus_smp_rmb(void)
{
__DMB();
}
/* Write memory barrier. */
rt_inline void rt_vbus_smp_wmb(void)
{
__DSB();
}
/* General memory barrier. */
rt_inline void rt_vbus_smp_mb(void)
{
__DSB();
}
+4 -2
View File
@@ -95,7 +95,8 @@
// <integer name="RT_CONSOLEBUF_SIZE" description="The buffer size for console output" default="128" />
#define RT_CONSOLEBUF_SIZE 128
// <string name="RT_CONSOLE_DEVICE_NAME" description="The device name for console" default="uart" />
#define RT_CONSOLE_DEVICE_NAME "uart0"
#define RT_CONSOLE_DEVICE_NAME "uart3"
#define RT_USING_UART3
// </section>
// <bool name="RT_USING_COMPONENTS_INIT" description="Using RT-Thread components initialization" default="true" />
@@ -222,7 +223,8 @@
#define RT_LWIP_MSKADDR3 0
// </section>
#define RT_USING_VBUS
#define RT_USING_LOGTRACE
// </RDTConfigurator>
+7 -6
View File
@@ -35,7 +35,7 @@ if os.getenv('RTT_EXEC_PATH'):
EXEC_PATH = os.getenv('RTT_EXEC_PATH')
#
BUILD = 'release'
BUILD = 'debug'
if PLATFORM == 'gcc':
# toolchains
@@ -44,23 +44,24 @@ if PLATFORM == 'gcc':
AS = PREFIX + 'gcc'
AR = PREFIX + 'ar'
LINK = PREFIX + 'gcc'
TARGET_EXT = 'elf'
TARGET_EXT = 'axf'
SIZE = PREFIX + 'size'
OBJDUMP = PREFIX + 'objdump'
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -mcpu=' + CPU + ' -mthumb -ffunction-sections -fdata-sections'
DEVICE = ' -mcpu=' + CPU + ' -mthumb -ffunction-sections -fdata-sections -Wall'
if USE_CORE == 'CORE_M4':
DEVICE += ' -mfpu=fpv4-sp-d16 -mfloat-abi=softfp'
CFLAGS = DEVICE
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -Wa,-mimplicit-it=thumb '
LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-lpc43xx.map,-cref,-u,Reset_Handler -T rtthread-lpc43xx_spifi.ld'
LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rtthread-lpc43xx.map,-cref,-u,Reset_Handler -T rtthread-lpc43xx.ld'
CPATH = ''
LPATH = ''
CFLAGS += ' -gdwarf-2'
AFLAGS += ' -gdwarf-2'
if BUILD == 'debug':
CFLAGS += ' -O0 -gdwarf-2'
AFLAGS += ' -gdwarf-2'
CFLAGS += ' -O0'
else:
CFLAGS += ' -O2'
+147
View File
@@ -0,0 +1,147 @@
/*
* linker script for LPC43xx SPIFI (4Mb NorFlash, 32kB SRAM ) with GNU ld
* yiyue.fang 2012-04-14
*/
/* Program Entry, set to mark it as "used" and avoid gc */
MEMORY
{
CODE (rx) : ORIGIN = 0x1A000000, LENGTH = 0x00080000
M0CODE (rx) : ORIGIN = 0x1B000000, LENGTH = 0x00080000
DATA (rw) : ORIGIN = 0x10000000, LENGTH = 0x00008000
AHBRAM (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000
}
ENTRY(Reset_Handler)
_system_stack_size = 0x200;
SECTIONS
{
.text :
{
. = ALIGN(4);
KEEP(*(.interrupt_vector)) /* Startup code */
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t*)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
. = ALIGN(4);
_etext = .;
} > CODE = 0
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
/* This is used by the startup in order to initialize the .data secion */
_sidata = .;
} > CODE
__exidx_end = .;
/* .data section which is used for initialized data */
.data : AT (_sidata)
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_sdata = . ;
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .data secion */
_edata = . ;
} >DATA
. = _edata ;
.stack :
{
. = . + _system_stack_size;
. = ALIGN(4);
_estack = .;
} >DATA
__bss_start = .;
.bss :
{
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .;
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
/* This is used by the startup in order to initialize the .bss secion */
_ebss = . ;
*(.bss.init)
} > DATA
__bss_end = .;
.vbus_ring (NOLOAD) :
{
*(vbus_ring)
} > AHBRAM
.text.M0CODE :
{
*(M0_CODE)
} > M0CODE = 0
_end = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}
+23
View File
@@ -0,0 +1,23 @@
; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************
LR_IROM1 0x1A000000 0x00080000 { ; load region size_region
ER_IROM1 0x1A000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x10000000 0x00008000 { ; RW data
.ANY (+RW +ZI)
}
RW_AHBRAM 0x20000000 0x00010000 { ; RW data
* (vbus_ring)
}
}
LR_IROM2 0x1B000000 0x00080000 {
ER_IROM2 0x1B000000 0x00080000 { ; load address = execution address
* (M0_CODE)
}
}
File diff suppressed because it is too large. Load diff
+8
View File
@@ -0,0 +1,8 @@
#ifndef __VBUS_LOCAL_CONF_H__
#define __VBUS_LOCAL_CONF_H__
#define RT_VBUS_USING_FLOW_CONTROL
#define RT_VBUS_USING_TESTS
#endif /* end of include guard: __VBUS_LOCAL_CONF_H__ */
-84
View File
@@ -1,84 +0,0 @@
/*
* File : application.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2014, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2014-07-13 xiaonong port for lpc43xx
*/
#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>
#include "drv_led.h"
#ifdef RT_USING_FINSH
#include <finsh.h>
#include <shell.h>
#endif
/* thread phase init */
void rt_init_thread_entry(void *parameter)
{
#ifdef RT_USING_FINSH
/* initialize finsh */
finsh_system_init();
finsh_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
}
/*the led thread*/
ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t led_stack[ 512 ];
static struct rt_thread led_thread;
static void led_thread_entry(void *parameter)
{
rt_uint8_t led_value = 0;
rt_device_t led_dev;
rt_led_hw_init();
led_dev = rt_device_find("led");
if (led_dev == RT_NULL)
{
rt_kprintf("can not find the led device!\n");
return;
}
while (1)
{
/* led0 on */
led_value = 1;
led_dev->write(led_dev, 0, &led_value, 1);
rt_thread_delay(RT_TICK_PER_SECOND / 2); /* sleep 0.5 second and switch to other thread */
/* led0 off */
led_value = 0;
led_dev->write(led_dev, 0, &led_value, 1);
rt_thread_delay(RT_TICK_PER_SECOND / 2);
}
}
int rt_application_init(void)
{
rt_thread_t tid;
rt_err_t result;
tid = rt_thread_create("init",
rt_init_thread_entry, RT_NULL,
2048, RT_THREAD_PRIORITY_MAX / 3, 20);
if (tid != RT_NULL) rt_thread_startup(tid);
/* init led thread */
result = rt_thread_init(&led_thread,
"led",
led_thread_entry,
RT_NULL,
(rt_uint8_t *)&led_stack[0],
sizeof(led_stack),
20,
5);
if (result == RT_EOK)
{
rt_thread_startup(&led_thread);
}
return 0;
}
+14
View File
@@ -0,0 +1,14 @@
#!/bin/env python
import sys
fi = open(sys.argv[1], 'rb')
fo = open(sys.argv[2], 'wb')
idx = 0
for i in fi.read():
idx += 1
fo.write('0x%02x, ' % ord(i))
if idx % 16 == 0:
fo.write('\n')
fo.write('\n')
File diff suppressed because it is too large. Load diff
+4
View File
@@ -0,0 +1,4 @@
1. M4 run on flash bank A. M0 run on flash bank B and the binary code of M0 is
embedded into the code of M4.
3. Compile the project in M0/ first and then compile the project in M4/. Then
flash it into the chip with JLink.
+29
View File
@@ -0,0 +1,29 @@
# RT-Thread building script for component
import SCons, os
from building import *
group = []
if not GetDepend(['RT_USING_VBUS']):
Return('group')
cwd = GetCurrentDir()
src = Glob('*.c')
for c, f in [['RT_USING_VBUS_RFS', 'utilities/rfs.c'],
['RT_USING_VBUS_RSHELL', 'utilities/rshell.c'],
]:
if GetDepend(c):
src += Glob(f)
with open(os.path.join(Dir('#').get_abspath(), 'vbus_local_conf.h'), 'r') as f:
cpp = SCons.cpp.PreProcessor()
cpp.process_contents(f.read())
if 'RT_VBUS_USING_TESTS' in cpp.cpp_namespace:
src += Glob('tests/*.c')
CPPPATH = [cwd, os.path.join(cwd, 'share_hdr')]
group = DefineGroup('VBus', src, depend = ['RT_USING_VBUS'], CPPPATH = CPPPATH)
Return('group')
File diff suppressed because it is too large. Load diff
+73
View File
@@ -0,0 +1,73 @@
/*
* Priority Queue
*
* COPYRIGHT (C) 2013-2015, Shanghai Real-Thread Technology Co., Ltd
* http://www.rt-thread.com
*
* This file is part of RT-Thread (http://www.rt-thread.org)
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2013-11-04 Grissiom add comment
*/
#ifndef __PRIO_QUEUE_H__
#define __PRIO_QUEUE_H__
#include <rtthread.h>
#define RT_PRIO_QUEUE_PRIO_MAX 32
struct rt_prio_queue_item;
struct rt_prio_queue {
rt_uint32_t bitmap;
struct rt_prio_queue_item *head[RT_PRIO_QUEUE_PRIO_MAX];
struct rt_prio_queue_item *tail[RT_PRIO_QUEUE_PRIO_MAX];
/* push thread suspend on the mempool, not queue */
rt_list_t suspended_pop_list;
rt_size_t item_sz;
struct rt_mempool pool;
};
rt_err_t rt_prio_queue_init(struct rt_prio_queue *que,
const char *name,
void *buf,
rt_size_t bufsz,
rt_size_t itemsz);
void rt_prio_queue_detach(struct rt_prio_queue *que);
rt_err_t rt_prio_queue_push(struct rt_prio_queue *que,
rt_uint8_t prio,
void *data,
rt_int32_t timeout);
rt_err_t rt_prio_queue_pop(struct rt_prio_queue *que,
void *data,
rt_int32_t timeout);
#ifdef RT_USING_HEAP
struct rt_prio_queue* rt_prio_queue_create(const char *name,
rt_size_t item_nr,
rt_size_t item_sz);
void rt_prio_queue_delete(struct rt_prio_queue *que);
#endif
void rt_prio_queue_dump(struct rt_prio_queue *que);
#endif /* end of include guard: __PRIO_QUEUE_H__ */
+71
View File
@@ -0,0 +1,71 @@
/*
* Water Gauge
*
* COPYRIGHT (C) 2014-2015, Shanghai Real-Thread Technology Co., Ltd
* http://www.rt-thread.com
*
* This file is part of RT-Thread (http://www.rt-thread.org)
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2014-04-16 Grissiom first version
*/
#include <rthw.h>
#include <rtthread.h>
#include "rt_watermark_queue.h"
void rt_wm_que_set_mark(struct rt_watermark_queue *wg,
unsigned int low, unsigned int high)
{
RT_ASSERT(low <= high);
wg->high_mark = high;
wg->low_mark = low;
}
void rt_wm_que_init(struct rt_watermark_queue *wg,
unsigned int low, unsigned int high)
{
rt_wm_que_set_mark(wg, low, high);
rt_list_init(&wg->suspended_threads);
wg->level = 0;
}
void rt_wm_que_dump(struct rt_watermark_queue *wg)
{
struct rt_list_node *node;
rt_kprintf("wg %p: low: %d, high: %d, cur: %d\n",
wg, wg->low_mark, wg->high_mark, wg->level);
rt_kprintf("thread suspend:");
for (node = wg->suspended_threads.next;
node != &wg->suspended_threads;
node = node->next)
{
rt_thread_t thread;
thread = rt_list_entry(wg->suspended_threads.next,
struct rt_thread,
tlist);
rt_kprintf(" %.*s", RT_NAME_MAX, thread->name);
}
rt_kprintf("\n");
}
+149
View File
@@ -0,0 +1,149 @@
/*
* Thread queue with water mark
*
* COPYRIGHT (C) 2014-2015, Shanghai Real-Thread Technology Co., Ltd
* http://www.rt-thread.com
*
* This file is part of RT-Thread (http://www.rt-thread.org)
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2014-04-16 Grissiom first version
*/
struct rt_watermark_queue
{
/* Current water level. */
unsigned int level;
unsigned int high_mark;
unsigned int low_mark;
rt_list_t suspended_threads;
};
/** Init the struct rt_watermark_queue.
*/
void rt_wm_que_init(struct rt_watermark_queue *wg,
unsigned int low, unsigned int high);
void rt_wm_que_set_mark(struct rt_watermark_queue *wg,
unsigned int low, unsigned int high);
void rt_wm_que_dump(struct rt_watermark_queue *wg);
/* Water marks are often used in performance critical places. Benchmark shows
* inlining functions will have 10% performance gain in some situation(for
* example, VBus). So keep the inc/dec compact and inline. */
/** Increase the water level.
*
* It should be called in the thread that want to raise the water level. If the
* current level is above the high mark, the thread will be suspended up to
* @timeout ticks.
*
* @return RT_EOK if water level increased successfully. -RT_EFULL on @timeout
* is zero and the level is above water mark. -RT_ETIMEOUT if timeout occurred.
*/
rt_inline rt_err_t rt_wm_que_inc(struct rt_watermark_queue *wg,
int timeout)
{
rt_base_t ilvl;
/* Assert as early as possible. */
if (timeout != 0)
{
RT_DEBUG_IN_THREAD_CONTEXT;
}
ilvl = rt_hw_interrupt_disable();
while (wg->level > wg->high_mark)
{
rt_thread_t thread;
if (timeout == 0)
{
rt_hw_interrupt_enable(ilvl);
return -RT_EFULL;
}
thread = rt_thread_self();
thread->error = RT_EOK;
rt_thread_suspend(thread);
rt_list_insert_after(&wg->suspended_threads, &thread->tlist);
if (timeout > 0)
{
rt_timer_control(&(thread->thread_timer),
RT_TIMER_CTRL_SET_TIME,
&timeout);
rt_timer_start(&(thread->thread_timer));
}
rt_hw_interrupt_enable(ilvl);
rt_schedule();
if (thread->error != RT_EOK)
return thread->error;
ilvl = rt_hw_interrupt_disable();
}
wg->level++;
if (wg->level == 0)
{
wg->level = ~0;
}
rt_hw_interrupt_enable(ilvl);
return RT_EOK;
}
/** Decrease the water level.
*
* It should be called by the consumer that drain the water out. If the water
* level reached low mark, all the thread suspended in this queue will be waken
* up. It's safe to call this function in interrupt context.
*/
rt_inline void rt_wm_que_dec(struct rt_watermark_queue *wg)
{
int need_sched = 0;
rt_base_t ilvl;
if (wg->level == 0)
return;
ilvl = rt_hw_interrupt_disable();
wg->level--;
if (wg->level == wg->low_mark)
{
/* There should be spaces between the low mark and high mark, so it's
* safe to resume all the threads. */
while (!rt_list_isempty(&wg->suspended_threads))
{
rt_thread_t thread;
thread = rt_list_entry(wg->suspended_threads.next,
struct rt_thread,
tlist);
rt_thread_resume(thread);
need_sched = 1;
}
}
rt_hw_interrupt_enable(ilvl);
if (need_sched)
rt_schedule();
}
+79
View File
@@ -0,0 +1,79 @@
#ifndef __VBUS_API_H__
#define __VBUS_API_H__
#include "vbus_conf.h"
#define RT_VBUS_CHANNEL_NR 32
#define RT_VBUS_BLK_HEAD_SZ 4
#define RT_VBUS_MAX_PKT_SZ (256 - RT_VBUS_BLK_HEAD_SZ)
#ifndef __ASSEMBLY__
#include <stddef.h> /* For size_t */
struct rt_vbus_blk
{
unsigned char id;
unsigned char qos;
unsigned char len;
unsigned char reserved;
unsigned char data[60];
} __attribute__((packed));
struct rt_vbus_ring
{
volatile size_t put_idx;
volatile size_t get_idx;
/* whether the writer is blocked on this ring. For RTT, it means the
* central writer thread is waiting. For Linux, it means there are some
* threads waiting for space to write.
*
* Note that we don't record whether there are reading thread blocked. When
* there is new data, the other side will always be waked up. */
volatile unsigned int blocked;
struct rt_vbus_blk blks[RT_VMM_RB_BLK_NR];
};
enum
{
RT_VBUS_CHN0_CMD_ENABLE,
RT_VBUS_CHN0_CMD_DISABLE,
RT_VBUS_CHN0_CMD_SET,
RT_VBUS_CHN0_CMD_ACK,
RT_VBUS_CHN0_CMD_NAK,
/* If the recieving side reached high water mark. It has the right to
* suspend the channel. All the server/client should know about this
* command but the one that does not implement flow control could ignore
* this command. */
RT_VBUS_CHN0_CMD_SUSPEND,
RT_VBUS_CHN0_CMD_RESUME,
RT_VBUS_CHN0_CMD_MAX,
};
enum rt_vbus_chn_status
{
/* initial state, available for reuse */
RT_VBUS_CHN_ST_AVAILABLE,
/* ACK DISABLE send(CS) or received(CS), but not ready for reuse.(the
* channel is not closed by this end) */
RT_VBUS_CHN_ST_CLOSED,
/* ENABLE send(client) or received(server) */
RT_VBUS_CHN_ST_ESTABLISHING,
/* ACK SET send(C) or received(S) */
RT_VBUS_CHN_ST_ESTABLISHED,
/* Channel suspended by flow control. */
RT_VBUS_CHN_ST_SUSPEND,
/* DISABLE received(CS) */
RT_VBUS_CHN_ST_CLOSING,
};
#endif
#undef BUILD_ASSERT
/* borrowed from http://lxr.linux.no/linux+v2.6.26.5/include/linux/kernel.h#L494 */
#define BUILD_ASSERT(condition) ((void)sizeof(char[1 - 2*!(condition)]))
/* max length of a channel name, including the \0 */
#define RT_VBUS_CHN_NAME_MAX 16
#endif /* end of include guard: __VBUS_API_H__ */
File diff suppressed because it is too large. Load diff
+197
View File
@@ -0,0 +1,197 @@
#ifndef __VBUS_H__
#define __VBUS_H__
/*
* VBus
*
* COPYRIGHT (C) 2013-2015, Shanghai Real-Thread Technology Co., Ltd
* http://www.rt-thread.com
*
* This file is part of RT-Thread (http://www.rt-thread.org)
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2014-06-09 Grissiom version 2.0.2; add comment
* 2015-01-06 Grissiom version 2.0.3; API change, no functional changes
*/
#include "vbus_local_conf.h"
#include <vbus_api.h>
int rt_vbus_init(void *outr, void *inr);
void rt_vbus_resume_out_thread(void);
/** Post data on channel.
*
* @param chnr the channel number
* @param prio the priority of the data
* @param datap pointer to the actual data
* @param size number of byte of the data
* @param timeout the value used in the blocking API
*
* Note: rt_vbus_post is an asynchronous function that when it returns, the
* @datap and @size is recorded in the post queue at least but there is no
* guarantee that the data is copied into the ring buffer. To avoid data
* corruption, you need to wait on the RT_VBUS_EVENT_ID_TX event.
*
* However, if you just post static data such as static string, there is no
* need to wait.
*
* @sa rt_vbus_register_listener .
*/
rt_err_t rt_vbus_post(rt_uint8_t chnr,
rt_uint8_t prio,
const void *datap,
rt_size_t size,
rt_int32_t timeout);
struct rt_vbus_data {
/* Number of bytes in current data package. */
unsigned char size;
/* Used internally in VBus. Don't modify this field as it may corrupt the
* receive queue. */
struct rt_vbus_data *next;
/* Data follows the struct */
};
struct rt_vbus_wm_cfg {
unsigned int low, high;
};
struct rt_vbus_request {
unsigned char prio;
const char *name;
int is_server;
struct rt_vbus_wm_cfg recv_wm, post_wm;
};
/** Request a channel.
*
* @return channel number. Negative if error happened.
*/
int rt_vbus_request_chn(struct rt_vbus_request *req, int timeout);
/** Close channel @chnr */
void rt_vbus_close_chn(unsigned char chnr);
/** Set the water mark level for posting into the channel @chnr. */
void rt_vbus_set_post_wm(unsigned char chnr, unsigned int low, unsigned int high);
/** Set the water mark level for receiving from the channel @chnr. */
void rt_vbus_set_recv_wm(unsigned char chnr, unsigned int low, unsigned int high);
typedef void (*rt_vbus_event_listener)(void *ctx);
enum rt_vbus_event_id {
/* On a packet received in channel. */
RT_VBUS_EVENT_ID_RX,
/* On the data of rt_vbus_post has been written to the ring buffer. */
RT_VBUS_EVENT_ID_TX,
/* On the channel has been closed. */
RT_VBUS_EVENT_ID_DISCONN,
RT_VBUS_EVENT_ID_MAX,
};
/** Register callback @indi on the event @eve on the @chnr.
*
* @ctx will passed to @indi on calling the @indi.
*/
void rt_vbus_register_listener(unsigned char chnr,
enum rt_vbus_event_id eve,
rt_vbus_event_listener indi,
void *ctx);
/** Listen on any events happen on the @chnr for @timeout ticks.
*
* This function blocks until events occur or timeout happened.
*/
rt_err_t rt_vbus_listen_on(rt_uint8_t chnr,
rt_int32_t timeout);
/** Push a data package into the receive queue of the channel @chnr. */
void rt_vbus_data_push(unsigned int chnr,
struct rt_vbus_data *data);
/** Pop a data package from the receive queue of the channel @chnr.
*
* The actual data is following the struct rt_vbus_data. After using it, it
* should be freed by rt_free.
*/
struct rt_vbus_data* rt_vbus_data_pop(unsigned int chnr);
struct rt_vbus_dev
{
/* Runtime infomations. */
rt_uint8_t chnr;
struct rt_vbus_data *act;
rt_size_t pos;
/* There will be a request for each channel. So no need to seperate them so
* clearly. */
struct rt_vbus_request req;
};
rt_err_t rt_vbus_chnx_init(void);
/** Get the corresponding channel number from the VBus device @dev. */
rt_uint8_t rt_vbus_get_chnnr(rt_device_t dev);
/** Register a call back on the other side disconnect the channel.
*
* @sa rt_vbus_register_listener .
*/
void rt_vbus_chnx_register_disconn(rt_device_t dev,
rt_vbus_event_listener indi,
void *ctx);
/* Commands for the device control interface. */
#define VBUS_IOCRECV_WM 0xD1
#define VBUS_IOCPOST_WM 0xD2
/** Configure event listener */
#define VBUS_IOC_LISCFG 0xD3
struct rt_vbus_dev_liscfg
{
enum rt_vbus_event_id event;
rt_vbus_event_listener listener;
void *ctx;
};
int rt_vbus_shell_start(void);
#ifdef RT_USING_VBUS_RFS
int dfs_rfs_init(void);
#endif
/** VBus hardware init function.
*
* BSP should implement this function to initialize the interrupts etc.
*/
int rt_vbus_hw_init(void);
/** VBus ISR function.
*
* BSP should call this function when the interrupt from other core is
* triggered. @param is not used by VBus and will pass to rt_vbus_hw_eoi.
*/
void rt_vbus_isr(int irqnr, void *param);
/** VBus End Of Interrupt function.
*
* This function will be called when VBus finished the ISR handling. BSP should
* define this function to clear the interrupt flag etc.
*/
int rt_vbus_hw_eoi(int irqnr, void *param);
#endif /* end of include guard: __VBUS_H__ */
File diff suppressed because it is too large. Load diff