mirror of
https://github.com/elua/elua.git
synced 2025-01-25 01:02:54 +08:00
Now all eLua platforms compile using build_elua.lua; output compared with scons' output to verify that the same code is generated
This commit is contained in:
parent
cd3d721519
commit
1822ee1572
@ -358,7 +358,7 @@ end
|
||||
|
||||
-- CPU/allocator mapping (if allocator not specified)
|
||||
if comp.allocator == 'auto' then
|
||||
if utils.array_element_index( comp.board:upper(), { 'LPC-H2888', 'ATEVK1100', 'MBED' } ) then
|
||||
if utils.array_element_index( { 'LPC-H2888', 'ATEVK1100', 'MBED' }, comp.board:upper() ) then
|
||||
comp.allocator = 'multiple'
|
||||
else
|
||||
comp.allocator = 'newlib'
|
||||
@ -535,7 +535,7 @@ builder:default( builder:add_target( exetarget, 'build eLua executable' ) )
|
||||
-- Create 'prog' target
|
||||
progtarget = builder:target( "#phony:prog", { exetarget }, tools[ platform ].progfunc )
|
||||
builder:add_target( progtarget, "build eLua firmware image", { "prog" } )
|
||||
progtarget:set_explicit_deps( tools[ platform ].prog_flist )
|
||||
progtarget:set_explicit_targets( tools[ platform ].prog_flist )
|
||||
|
||||
-- If the backend needs to do more processing before the build starts, do it now
|
||||
if tools[ platform ].pre_build then
|
||||
|
@ -8,17 +8,24 @@
|
||||
#include "serial.h"
|
||||
|
||||
#define WIN_ERROR ( HANDLE )-1
|
||||
#define WIN_MAX_PORT_NAME 1024
|
||||
#define WIN_MAX_PORT_NAME MAX_PATH
|
||||
#define MAX_HANDLES 1024
|
||||
|
||||
static HANDLE sel_handlers[ MAX_HANDLES ];
|
||||
static int sel_handler_map[ MAX_HANDLES ];
|
||||
static HANDLE sel_handlers[ MAX_HANDLES ]; // XXX: consider making this an static variable of ser_select_byte
|
||||
static int sel_handler_map[ MAX_HANDLES ]; // XXX: consider making this an static variable of ser_select_byte
|
||||
|
||||
static void init_ov( OVERLAPPED* o )
|
||||
{
|
||||
HANDLE temp = o->hEvent;
|
||||
memset( o, 0, sizeof( OVERLAPPED ) );
|
||||
o->hEvent = temp;
|
||||
}
|
||||
|
||||
// Helper: set timeout
|
||||
static int ser_win32_set_timeouts( HANDLE hComm, DWORD ri, DWORD rtm, DWORD rtc, DWORD wtm, DWORD wtc )
|
||||
{
|
||||
{
|
||||
COMMTIMEOUTS timeouts;
|
||||
|
||||
|
||||
if( GetCommTimeouts( hComm, &timeouts ) == FALSE )
|
||||
{
|
||||
CloseHandle( hComm );
|
||||
@ -29,18 +36,18 @@ static int ser_win32_set_timeouts( HANDLE hComm, DWORD ri, DWORD rtm, DWORD rtc,
|
||||
timeouts.ReadTotalTimeoutMultiplier = rtc;
|
||||
timeouts.WriteTotalTimeoutConstant = wtm;
|
||||
timeouts.WriteTotalTimeoutMultiplier = wtc;
|
||||
if( SetCommTimeouts( hComm, &timeouts ) == FALSE )
|
||||
{
|
||||
CloseHandle( hComm );
|
||||
return SER_ERR;
|
||||
}
|
||||
|
||||
if( SetCommTimeouts( hComm, &timeouts ) == FALSE )
|
||||
{
|
||||
CloseHandle( hComm );
|
||||
return SER_ERR;
|
||||
}
|
||||
|
||||
return SER_OK;
|
||||
}
|
||||
|
||||
// Helper: set communication timeout
|
||||
static int ser_set_timeout_ms( HANDLE hComm, u32 timeout )
|
||||
{
|
||||
{
|
||||
if( timeout == SER_NO_TIMEOUT )
|
||||
return ser_win32_set_timeouts( hComm, MAXDWORD, 0, 0, 0, 0 );
|
||||
else if( timeout == SER_INF_TIMEOUT )
|
||||
@ -55,8 +62,8 @@ ser_handler ser_open( const char* sername )
|
||||
char portname[ WIN_MAX_PORT_NAME + 1 ];
|
||||
HANDLE hComm;
|
||||
ser_handler hnd;
|
||||
|
||||
portname[ 0 ] = portname[ WIN_MAX_PORT_NAME ] = '\0';
|
||||
|
||||
portname[ WIN_MAX_PORT_NAME ] = '\0';
|
||||
_snprintf( portname, WIN_MAX_PORT_NAME, "\\\\.\\%s", sername );
|
||||
hComm = CreateFile( portname, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 );
|
||||
if( hComm == INVALID_HANDLE_VALUE )
|
||||
@ -70,10 +77,15 @@ ser_handler ser_open( const char* sername )
|
||||
memset( hnd, 0, sizeof( SERIAL_DATA ) );
|
||||
hnd->hnd = hComm;
|
||||
hnd->fWaitingOnRead = FALSE;
|
||||
if( ( hnd->o.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) == NULL )
|
||||
if( ( hnd->o.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) == NULL ) {
|
||||
free( hnd );
|
||||
return SER_HANDLER_INVALID;
|
||||
if( ( hnd->o_wr.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) == NULL )
|
||||
return SER_HANDLER_INVALID;
|
||||
}
|
||||
if( ( hnd->o_wr.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL ) ) == NULL ) {
|
||||
free( hnd );
|
||||
CloseHandle( hnd->o.hEvent );
|
||||
return SER_HANDLER_INVALID;
|
||||
}
|
||||
return hnd;
|
||||
}
|
||||
|
||||
@ -81,7 +93,7 @@ ser_handler ser_open( const char* sername )
|
||||
void ser_close( ser_handler id )
|
||||
{
|
||||
CloseHandle( id->o.hEvent );
|
||||
CloseHandle( id->o_wr.hEvent );
|
||||
CloseHandle( id->o_wr.hEvent );
|
||||
CloseHandle( id->hnd );
|
||||
free( id );
|
||||
}
|
||||
@ -90,12 +102,13 @@ int ser_setup( ser_handler id, u32 baud, int databits, int parity, int stopbits,
|
||||
{
|
||||
HANDLE hComm = id->hnd;
|
||||
DCB dcb;
|
||||
|
||||
if( GetCommState( hComm, &dcb ) == FALSE )
|
||||
{
|
||||
CloseHandle( hComm );
|
||||
return SER_ERR;
|
||||
}
|
||||
dcb.DCBlength = sizeof(DCB);
|
||||
|
||||
if( GetCommState( hComm, &dcb ) == FALSE )
|
||||
{
|
||||
CloseHandle( hComm );
|
||||
return SER_ERR;
|
||||
}
|
||||
dcb.BaudRate = baud;
|
||||
dcb.ByteSize = databits;
|
||||
dcb.Parity = parity == SER_PARITY_NONE ? NOPARITY : ( parity == SER_PARITY_EVEN ? EVENPARITY : ODDPARITY );
|
||||
@ -120,59 +133,63 @@ int ser_setup( ser_handler id, u32 baud, int databits, int parity, int stopbits,
|
||||
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
|
||||
dcb.fOutxCtsFlow = TRUE;
|
||||
}
|
||||
if( SetCommState( hComm, &dcb ) == 0 )
|
||||
if( SetCommState( hComm, &dcb ) == FALSE )
|
||||
{
|
||||
CloseHandle( hComm );
|
||||
return SER_ERR;
|
||||
}
|
||||
|
||||
|
||||
if( ser_win32_set_timeouts( hComm, 0, 0, 0, 0, 0 ) == SER_ERR )
|
||||
{
|
||||
CloseHandle( hComm );
|
||||
return SER_ERR;
|
||||
}
|
||||
|
||||
|
||||
FlushFileBuffers( hComm );
|
||||
|
||||
return SER_OK;
|
||||
}
|
||||
|
||||
// Read up to the specified number of bytes, return bytes actually read
|
||||
u32 ser_read( ser_handler id, u8* dest, u32 maxsize, u32 timeout )
|
||||
static u32 ser_read_internal( ser_handler id, u32 timeout )
|
||||
{
|
||||
HANDLE hComm = id->hnd;
|
||||
DWORD readbytes = 0;
|
||||
|
||||
if( !id->fWaitingOnRead )
|
||||
DWORD dwRes = WaitForSingleObject( id->o.hEvent, timeout == SER_INF_TIMEOUT ? INFINITE : timeout );
|
||||
if( dwRes == WAIT_OBJECT_0 )
|
||||
{
|
||||
if( ReadFile( hComm, dest, maxsize, &readbytes, &id->o ) == FALSE )
|
||||
{
|
||||
if( GetLastError() != ERROR_IO_PENDING )
|
||||
return 0;
|
||||
else
|
||||
id->fWaitingOnRead = TRUE;
|
||||
}
|
||||
else
|
||||
return readbytes;
|
||||
if( !GetOverlappedResult( hComm, &id->o, &readbytes, TRUE ) )
|
||||
readbytes = 0;
|
||||
}
|
||||
|
||||
else if( dwRes == WAIT_TIMEOUT )
|
||||
{
|
||||
CancelIo( hComm );
|
||||
GetOverlappedResult( hComm, &id->o, &readbytes, TRUE );
|
||||
readbytes = 0;
|
||||
}
|
||||
ResetEvent( id->o.hEvent );
|
||||
return readbytes;
|
||||
}
|
||||
|
||||
// Read up to the specified number of bytes, return bytes actually read
|
||||
u32 ser_read( ser_handler id, u8* dest, u32 maxsize, u32 timeout )
|
||||
{
|
||||
DWORD readbytes = 0;
|
||||
if( id->fWaitingOnRead )
|
||||
{
|
||||
DWORD dwRes = WaitForSingleObject( id->o.hEvent, timeout == SER_INF_TIMEOUT ? INFINITE : timeout );
|
||||
if( dwRes == WAIT_OBJECT_0 )
|
||||
{
|
||||
if( !GetOverlappedResult( hComm, &id->o, &readbytes, TRUE ) )
|
||||
readbytes = 0;
|
||||
}
|
||||
else if( dwRes == WAIT_TIMEOUT )
|
||||
{
|
||||
CancelIo( hComm );
|
||||
GetOverlappedResult( hComm, &id->o, &readbytes, TRUE );
|
||||
readbytes = 0;
|
||||
}
|
||||
ResetEvent( id->o.hEvent );
|
||||
}
|
||||
id->fWaitingOnRead = FALSE;
|
||||
readbytes = ser_read_internal( id, timeout );
|
||||
dest[0] = id->databuf;
|
||||
}
|
||||
else
|
||||
{
|
||||
init_ov( &id->o );
|
||||
if( ReadFile( id->hnd, dest, maxsize, &readbytes, &id->o ) )
|
||||
return readbytes;
|
||||
if( GetLastError() != ERROR_IO_PENDING )
|
||||
return 0;
|
||||
id->fWaitingOnRead = TRUE; // XXX: consider removing statement
|
||||
readbytes = ser_read_internal( id, timeout );
|
||||
}
|
||||
id->fWaitingOnRead = FALSE;
|
||||
return readbytes;
|
||||
}
|
||||
|
||||
@ -180,41 +197,25 @@ u32 ser_read( ser_handler id, u8* dest, u32 maxsize, u32 timeout )
|
||||
int ser_read_byte( ser_handler id, u32 timeout )
|
||||
{
|
||||
u8 data;
|
||||
int res = ser_read( id, &data, 1, timeout );
|
||||
|
||||
return res == 1 ? data : -1;
|
||||
return ser_read( id, &data, 1, timeout ) == 1 ? data : -1;
|
||||
}
|
||||
|
||||
// Write up to the specified number of bytes, return bytes actually written
|
||||
u32 ser_write( ser_handler id, const u8 *src, u32 size )
|
||||
{
|
||||
HANDLE hComm = id->hnd;
|
||||
DWORD written = 0;
|
||||
BOOL fWaitingOnWrite = FALSE;
|
||||
HANDLE temp = id->o_wr.hEvent;
|
||||
|
||||
memset( &id->o_wr, 0, sizeof( OVERLAPPED ) );
|
||||
id->o_wr.hEvent = temp;
|
||||
if( WriteFile( hComm, src, size, &written, &id->o_wr ) == FALSE )
|
||||
{
|
||||
if( GetLastError() != ERROR_IO_PENDING )
|
||||
return 0;
|
||||
else
|
||||
fWaitingOnWrite = TRUE;
|
||||
}
|
||||
else
|
||||
DWORD written;
|
||||
|
||||
init_ov( &id->o_wr );
|
||||
if( WriteFile( hComm, src, size, &written, &id->o_wr ) )
|
||||
return written;
|
||||
if( GetLastError() != ERROR_IO_PENDING )
|
||||
return 0;
|
||||
if( !GetOverlappedResult( hComm, &id->o_wr, &written, TRUE ) )
|
||||
written = 0;
|
||||
ResetEvent( id->o_wr.hEvent );
|
||||
|
||||
if( fWaitingOnWrite )
|
||||
{
|
||||
DWORD dwRes = WaitForSingleObject( id->o_wr.hEvent, INFINITE );
|
||||
if( dwRes == WAIT_OBJECT_0 )
|
||||
if( !GetOverlappedResult( hComm, &id->o_wr, &written, FALSE ) )
|
||||
written = 0;
|
||||
ResetEvent( id->o_wr.hEvent );
|
||||
}
|
||||
|
||||
return written;
|
||||
return written;
|
||||
}
|
||||
|
||||
// Write a byte to the serial port
|
||||
@ -228,73 +229,57 @@ u32 ser_write_byte( ser_handler id, u8 data )
|
||||
// otherwise
|
||||
int ser_select_byte( ser_handler *pobjects, unsigned nobjects, int timeout )
|
||||
{
|
||||
int i, idx;
|
||||
int i;
|
||||
DWORD readbytes;
|
||||
int res = -1;
|
||||
unsigned num_wait = 0;
|
||||
ser_handler hnd;
|
||||
HANDLE temp;
|
||||
|
||||
|
||||
if( nobjects >= MAXIMUM_WAIT_OBJECTS )
|
||||
return -1;
|
||||
|
||||
// Try to read directly first
|
||||
for( i = 0; i < nobjects; i ++ )
|
||||
{
|
||||
temp = pobjects[ i ]->o.hEvent;
|
||||
memset( &pobjects[ i ]->o, 0, sizeof( OVERLAPPED ) );
|
||||
pobjects[ i ]->o.hEvent = temp;
|
||||
{
|
||||
if( !pobjects[ i ]->fWaitingOnRead )
|
||||
{
|
||||
if( ReadFile( pobjects[ i ]->hnd, &pobjects[ i ]->databuf, 1, &readbytes, &pobjects[ i ]->o ) == FALSE )
|
||||
{
|
||||
if( GetLastError() != ERROR_IO_PENDING )
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
pobjects[ i ]->fWaitingOnRead = TRUE;
|
||||
sel_handler_map[ num_wait ] = i;
|
||||
sel_handlers[ num_wait ++ ] = pobjects[ i ]->o.hEvent;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( readbytes == 1 )
|
||||
return pobjects[ i ]->databuf | ( i << 8 );
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sel_handler_map[ num_wait ] = i;
|
||||
sel_handlers[ num_wait ++ ] = pobjects[ i ]->o.hEvent;
|
||||
}
|
||||
init_ov( &pobjects[ i ]->o );
|
||||
if( ReadFile( pobjects[ i ]->hnd, &pobjects[ i ]->databuf, 1, &readbytes, &pobjects[ i ]->o ) )
|
||||
return readbytes != 1 ? -1 : pobjects[ i ]->databuf | ( i << 8 );
|
||||
if( GetLastError() != ERROR_IO_PENDING )
|
||||
return -1;
|
||||
pobjects[ i ]->fWaitingOnRead = TRUE;
|
||||
}
|
||||
sel_handler_map[ num_wait ] = i;
|
||||
sel_handlers[ num_wait ++ ] = pobjects[ i ]->o.hEvent;
|
||||
}
|
||||
|
||||
if( num_wait > 0 )
|
||||
|
||||
if( num_wait == 0 )
|
||||
return -1;
|
||||
|
||||
DWORD dwRes = WaitForMultipleObjects( num_wait, sel_handlers, FALSE, timeout == SER_INF_TIMEOUT ? INFINITE : timeout );
|
||||
if( dwRes >= WAIT_OBJECT_0 && dwRes < WAIT_OBJECT_0 + num_wait )
|
||||
{
|
||||
idx = -1;
|
||||
DWORD dwRes = WaitForMultipleObjects( num_wait, sel_handlers, FALSE, timeout == SER_INF_TIMEOUT ? INFINITE : timeout );
|
||||
if( dwRes >= WAIT_OBJECT_0 && dwRes < WAIT_OBJECT_0 + num_wait )
|
||||
i = dwRes - WAIT_OBJECT_0;
|
||||
hnd = pobjects[ sel_handler_map[ i ] ];
|
||||
hnd->fWaitingOnRead = FALSE;
|
||||
if( GetOverlappedResult( hnd->hnd, &hnd->o, &readbytes, TRUE ) && readbytes == 1 )
|
||||
res = hnd->databuf | ( sel_handler_map[ i ] << 8 );
|
||||
ResetEvent( hnd->o.hEvent );
|
||||
}
|
||||
else if( dwRes == WAIT_TIMEOUT )
|
||||
{
|
||||
for( i = 0; i < num_wait; i ++ )
|
||||
{
|
||||
i = idx = dwRes - WAIT_OBJECT_0;
|
||||
hnd = pobjects[ sel_handler_map[ i ] ];
|
||||
hnd->fWaitingOnRead = FALSE;
|
||||
if( GetOverlappedResult( hnd->hnd, &hnd->o, &readbytes, TRUE ) && readbytes == 1 )
|
||||
res = hnd->databuf | ( sel_handler_map[ i ] << 8 );
|
||||
ResetEvent( hnd->o.hEvent );
|
||||
CancelIo( hnd->hnd );
|
||||
}
|
||||
else if( dwRes == WAIT_TIMEOUT )
|
||||
{
|
||||
for( i = 0; i < num_wait; i ++ )
|
||||
{
|
||||
hnd = pobjects[ sel_handler_map[ i ] ];
|
||||
hnd->fWaitingOnRead = FALSE;
|
||||
CancelIo( hnd->hnd );
|
||||
GetOverlappedResult( hnd->hnd, &hnd->o, &readbytes, TRUE );
|
||||
ResetEvent( hnd->o.hEvent );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
WaitForMultipleObjects( num_wait, sel_handlers, TRUE, INFINITE );
|
||||
for( i = 0; i < num_wait; i ++ )
|
||||
ResetEvent( pobjects[ sel_handler_map[ i ] ]->o.hEvent );
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
52
src/platform/lpc24xx/conf.lua
Normal file
52
src/platform/lpc24xx/conf.lua
Normal file
@ -0,0 +1,52 @@
|
||||
-- Configuration file for the LPC24xx backend
|
||||
|
||||
local cpumode = ( builder:get_option( 'cpumode' ) or 'arm' ):lower()
|
||||
|
||||
specific_files = "startup.s irq.c target.c platform.c platform_int.c"
|
||||
|
||||
local ldscript = "lpc2468.lds"
|
||||
|
||||
-- Prepend with path
|
||||
specific_files = utils.prepend_path( specific_files, sf( "src/platform/%s", platform ) )
|
||||
specific_files = specific_files .. " src/platform/arm_utils.s src/platform/arm_cortex_interrupts.c"
|
||||
ldscript = sf( "src/platform/%s/%s", platform, ldscript )
|
||||
|
||||
addm{ "FOR" .. comp.cpu:upper(), 'gcc' }
|
||||
|
||||
-- Standard GCC Flags
|
||||
addcf{ '-ffunction-sections', '-fdata-sections', '-fno-strict-aliasing', '-Wall' }
|
||||
addlf{ '-nostartfiles', '-nostdlib', '-T', ldscript, '-Wl,--gc-sections', '-Wl,--allow-multiple-definition' }
|
||||
addaf{ '-x', 'assembler-with-cpp', '-Wall' }
|
||||
addlib{ 'c','gcc','m' }
|
||||
|
||||
-- Specific target configuration
|
||||
local target_flags = '-mcpu=arm7tdmi'
|
||||
if cpumode == 'thumb' then
|
||||
target_flags = { target_flags, '-mthumb' }
|
||||
addm( 'CPUMODE_THUMB' )
|
||||
else
|
||||
addm( 'CPUMODE_ARM' )
|
||||
end
|
||||
|
||||
addcf( target_flags )
|
||||
addlf{ target_flags, '-Wl,-e,entry' }
|
||||
addaf{ target_flags, '-D___ASSEMBLY__' }
|
||||
|
||||
-- Toolset data
|
||||
tools.lpc24xx = {}
|
||||
|
||||
-- Programming function
|
||||
tools.lpc24xx.progfunc = function( target, deps )
|
||||
local outname = deps[ 1 ]:target_name()
|
||||
os.execute( sf( "%s %s", toolset.size, outname ) )
|
||||
print "Generating binary image..."
|
||||
os.execute( sf( "%s -O ihex %s %s.hex", toolset.bin, outname, output ) )
|
||||
return 0
|
||||
end
|
||||
|
||||
-- Array of file names that will be checked against the 'prog' target; their absence will force a rebuild
|
||||
tools.lpc24xx.prog_flist = { output .. ".hex" }
|
||||
|
||||
-- We use 'gcc' as the assembler
|
||||
toolset.asm = toolset.compile
|
||||
|
53
src/platform/lpc288x/conf.lua
Normal file
53
src/platform/lpc288x/conf.lua
Normal file
@ -0,0 +1,53 @@
|
||||
-- Configuration file for the LPC288x backend
|
||||
|
||||
local cpumode = ( builder:get_option( 'cpumode' ) or 'arm' ):lower()
|
||||
|
||||
specific_files = "lpc28xx.s platform.c target.c uart.c"
|
||||
|
||||
local ldscript = "lpc2888.lds"
|
||||
|
||||
if cpumode == 'thumb' then
|
||||
print "ERROR: due to a hardware limitation, it is not possible to run Thumb code from the LPC2888 internal flash."
|
||||
print "Compile again, this time with cpumode=arm (or without specifying 'cpumode')"
|
||||
os.exit( -1 )
|
||||
end
|
||||
|
||||
-- Prepend with path
|
||||
specific_files = utils.prepend_path( specific_files, sf( "src/platform/%s", platform ) )
|
||||
specific_files = specific_files .. " src/platform/arm_utils.s src/platform/arm_cortex_interrupts.c"
|
||||
ldscript = sf( "src/platform/%s/%s", platform, ldscript )
|
||||
|
||||
addm{ "FOR" .. comp.cpu:upper(), 'gcc' }
|
||||
|
||||
-- Standard GCC flags
|
||||
addcf{ '-ffunction-sections', '-fdata-sections', '-fno-strict-aliasing', '-Wall' }
|
||||
addlf{ '-nostartfiles', '-nostdlib', '-T', ldscript, '-Wl,--gc-sections', '-Wl,--allow-multiple-definition' }
|
||||
addaf{ '-x', 'assembler-with-cpp', '-Wall' }
|
||||
addlib{ 'c','gcc','m' }
|
||||
|
||||
-- Special target configuration
|
||||
local target_flags = { '-mcpu=arm7tdmi' }
|
||||
addm( 'CPUMODE_ARM' )
|
||||
|
||||
addcf( target_flags )
|
||||
addlf{ target_flags, '-Wl,-e,HardReset' }
|
||||
addaf{ target_flags,'-D__ASSEMBLY__' }
|
||||
|
||||
-- Toolset data
|
||||
tools.lpc288x = {}
|
||||
|
||||
-- Programming function for AT91SAM7X
|
||||
tools.lpc288x.progfunc = function( target, deps )
|
||||
local outname = deps[ 1 ]:target_name()
|
||||
os.execute( sf( "%s %s", toolset.size, outname ) )
|
||||
print "Generating binary image..."
|
||||
os.execute( sf( "%s -O binary %s %s.bin", toolset.bin, outname, output ) )
|
||||
return 0
|
||||
end
|
||||
|
||||
-- Array of file names that will be checked against the 'prog' target; their absence will force a rebuild
|
||||
tools.lpc288x.prog_flist = { output .. ".bin" }
|
||||
|
||||
-- We use 'gcc' as the assembler
|
||||
toolset.asm = toolset.compile
|
||||
|
50
src/platform/str7/conf.lua
Normal file
50
src/platform/str7/conf.lua
Normal file
@ -0,0 +1,50 @@
|
||||
-- Configuration file for the STR7 backend
|
||||
|
||||
local cpumode = ( builder:get_option( 'cpumode' ) or 'thumb' ):lower()
|
||||
specific_files = "platform.c crt0.s 71x_rccu.c 71x_uart.c 71x_apb.c 71x_gpio.c 71x_tim.c"
|
||||
local ldscript = 'str711fr2.lds'
|
||||
|
||||
-- Prepend with path
|
||||
specific_files = utils.prepend_path( specific_files, sf( "src/platform/%s", platform ) )
|
||||
specific_files = specific_files .. " src/platform/arm_utils.s src/platform/arm_cortex_interrupts.c"
|
||||
ldscript = sf( "src/platform/%s/%s", platform, ldscript )
|
||||
|
||||
addm{ "FOR" .. comp.cpu:upper(), 'gcc' }
|
||||
|
||||
-- Standard GCC flags
|
||||
addcf{ '-ffunction-sections', '-fdata-sections', '-fno-strict-aliasing','-Wall' }
|
||||
addlf{ '-nostartfiles', '-nostdlib', '-T', ldscript, '-Wl,--gc-sections', '-Wl,--allow-multiple-definition' }
|
||||
addaf{ '-x', 'assembler-with-cpp', '-Wall' }
|
||||
addlib{ 'c','gcc','m' }
|
||||
|
||||
-- Special target configuration
|
||||
local target_flasg = '-mcpu=arm7tdmi'
|
||||
if cpumode == 'thumb' then
|
||||
target_flags = { target_flags, '-mthumb' }
|
||||
addm( 'CPUMODE_THUMB' )
|
||||
else
|
||||
addm( 'CPUMODE_ARM' )
|
||||
end
|
||||
|
||||
addcf( target_flags )
|
||||
addlf{ target_flags, '-Wl,-e,entry' }
|
||||
addaf( target_flags )
|
||||
|
||||
-- Toolset data
|
||||
tools.str7 = {}
|
||||
|
||||
-- Programming function for AT91SAM7X
|
||||
tools.str7.progfunc = function( target, deps )
|
||||
local outname = deps[ 1 ]:target_name()
|
||||
os.execute( sf( "%s %s", toolset.size, outname ) )
|
||||
print "Generating binary image..."
|
||||
os.execute( sf( "%s -O binary %s %s.bin", toolset.bin, outname, output ) )
|
||||
return 0
|
||||
end
|
||||
|
||||
-- Array of file names that will be checked against the 'prog' target; their absence will force a rebuild
|
||||
tools.str7.prog_flist = { output .. ".bin" }
|
||||
|
||||
-- We use 'gcc' as the assembler
|
||||
toolset.asm = toolset.compile
|
||||
|
57
src/platform/str9/conf.lua
Normal file
57
src/platform/str9/conf.lua
Normal file
@ -0,0 +1,57 @@
|
||||
-- Configuration file for the STR9 backend
|
||||
|
||||
local cpumode = ( builder:get_option( 'cpumode' ) or 'arm' ):lower()
|
||||
|
||||
specific_files = "startup912.s startup_generic.s platform.c 91x_scu.c 91x_fmi.c 91x_gpio.c 91x_uart.c 91x_tim.c 91x_vic.c interrupt.c str9_pio.c 91x_i2c.c 91x_wiu.c 91x_adc.c platform_int.c"
|
||||
|
||||
local ldscript = "str912fw44.lds"
|
||||
|
||||
-- Prepend with path
|
||||
specific_files = utils.prepend_path( specific_files, sf( "src/platform/%s", platform ) )
|
||||
specific_files = specific_files .. " src/platform/arm_utils.s src/platform/arm_cortex_interrupts.c"
|
||||
ldscript = sf( "src/platform/%s/%s", platform, ldscript )
|
||||
|
||||
addm{ "FOR" .. comp.cpu:upper(), 'gcc' }
|
||||
|
||||
-- Standard GCC Flags
|
||||
addcf{ '-ffunction-sections', '-fdata-sections', '-fno-strict-aliasing', '-Wall' }
|
||||
addlf{ '-nostartfiles', '-nostdlib', '-T', ldscript, '-Wl,--gc-sections', '-Wl,--allow-multiple-definition' }
|
||||
addaf{ '-x', 'assembler-with-cpp', '-Wall' }
|
||||
addlib{ 'c','gcc','m' }
|
||||
|
||||
-- Special target configuration
|
||||
local target_flags = '-mcpu=arm966e-s'
|
||||
if cpumode == 'thumb' then
|
||||
target_flags = { target_flags, '-mthumb' }
|
||||
addm( 'CPUMODE_THUMB' )
|
||||
else
|
||||
addm( 'CPUMODE_ARM' )
|
||||
end
|
||||
|
||||
-- Toolchain 'arm-gcc' requires '-mfpu=fpa' for some reason
|
||||
if comp.toolchain:lower() == 'arm-gcc' then
|
||||
target_flags = { target_flags, '-mfpu=fpa' }
|
||||
end
|
||||
|
||||
addcf( target_flags )
|
||||
addlf{ target_flags, '-Wl,-e,_startup' }
|
||||
addaf( target_flags )
|
||||
|
||||
-- Toolset data
|
||||
tools.str9 = {}
|
||||
|
||||
-- Programming function for AT91SAM7X
|
||||
tools.str9.progfunc = function( target, deps )
|
||||
local outname = deps[ 1 ]:target_name()
|
||||
os.execute( sf( "%s %s", toolset.size, outname ) )
|
||||
print "Generating binary image..."
|
||||
os.execute( sf( "%s -O binary %s %s.bin", toolset.bin, outname, output ) )
|
||||
return 0
|
||||
end
|
||||
|
||||
-- Array of file names that will be checked against the 'prog' target; their absence will force a rebuild
|
||||
tools.str9.prog_flist = { output .. ".bin" }
|
||||
|
||||
-- We use 'gcc' as the assembler
|
||||
toolset.asm = toolset.compile
|
||||
|
@ -244,23 +244,27 @@ _target.set_target_args = function( self, args )
|
||||
end
|
||||
|
||||
-- Function to execute in clean mode
|
||||
_target._cleaner = function( target, deps )
|
||||
if is_phony( target ) then return 0 end
|
||||
io.write( sf( "Removing %s ... ", target ) )
|
||||
if os.remove( target ) then
|
||||
print "done."
|
||||
else
|
||||
print "failed!"
|
||||
_target._cleaner = function( target, deps, dummy, explicit_targets )
|
||||
local cleaner = function( fname )
|
||||
io.write( sf( "Removing %s ... ", fname ) )
|
||||
if os.remove( fname ) then print "done." else print "failed!" end
|
||||
end
|
||||
-- Clean explicit targets
|
||||
if type( explicit_targets ) == "table" then
|
||||
for _, v in pairs( explicit_targets ) do cleaner( v ) end
|
||||
end
|
||||
-- Clean the main target if it is not a phony target
|
||||
if is_phony( target ) then return 0 end
|
||||
cleaner( target )
|
||||
return 0
|
||||
end
|
||||
|
||||
-- Build the given target
|
||||
_target.build = function( self )
|
||||
local docmd = self:target_name() and lfs.attributes( self:target_name(), "mode" ) ~= "file"
|
||||
-- Check explicit dependencies
|
||||
if type( self._explicit_deps ) == "table" then
|
||||
for _, v in pairs( self._explicit_deps ) do
|
||||
-- Check explicit targets
|
||||
if type( self._explicit_targets ) == "table" then
|
||||
for _, v in pairs( self._explicit_targets ) do
|
||||
if not utils.is_file( v ) then docmd = true end
|
||||
end
|
||||
end
|
||||
@ -284,7 +288,7 @@ _target.build = function( self )
|
||||
print( cmd )
|
||||
code = os.execute( cmd )
|
||||
else
|
||||
code = cmd( self.target, self.dep, self._target_args )
|
||||
code = cmd( self.target, self.dep, self._target_args, self._explicit_targets )
|
||||
if code == 1 then -- this means 'mark target as 'not executed'
|
||||
keep_flag = false
|
||||
code = 0
|
||||
@ -303,10 +307,10 @@ _target.target_name = function( self )
|
||||
return get_target_name( self.target )
|
||||
end
|
||||
|
||||
-- Set 'explicit dependencies' for this target
|
||||
-- Set 'explicit targets'
|
||||
-- The target will rebuild itself if these don't exist
|
||||
_target.set_explicit_deps = function( self, deps )
|
||||
self._explicit_deps = deps
|
||||
_target.set_explicit_targets = function( self, targets )
|
||||
self._explicit_targets = targets
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@ -579,6 +583,12 @@ builder.set_asm_dep_cmd = function( self, asm_dep_cmd )
|
||||
self.asm_dep_cmd = asm_dep_cmd
|
||||
end
|
||||
|
||||
-- Set a specific dependency generation command for the compiler
|
||||
-- Pass 'false' to skip dependency generation for C files
|
||||
builder.set_c_dep_cmd = function( self, c_dep_cmd )
|
||||
self.c_dep_cmd = c_dep_cmd
|
||||
end
|
||||
|
||||
---------------------------------------
|
||||
-- Command line builders
|
||||
|
||||
@ -707,10 +717,14 @@ builder.make_depends = function( self, ftable, deptargets )
|
||||
for i = 1, #ftable do
|
||||
local isasm = ftable[ i ]:find( "%.c$" ) == nil
|
||||
-- Skip assembler targets if 'asm_dep_cmd' is set to 'false'
|
||||
if not isasm or self.asm_dep_cmd ~= false then
|
||||
-- Skip C targets if 'c_dep_cmd' is set to 'false'
|
||||
local skip = isasm and self.asm_dep_cmd == false
|
||||
skip = skip or ( not isasm and self.c_dep_cmd == false )
|
||||
if not skip then
|
||||
local cmd = isasm and self.asm_cmd or self.comp_cmd
|
||||
local depcmd = cmd:gsub( "-c ", "-E -MM " )
|
||||
if isasm and self.asm_dep_cmd then depcmd = self.asm_dep_cmd end
|
||||
if not isasm and self.c_dep_cmd then depcmd = self.c_dep_cmd end
|
||||
local target = self:dep_target( ftable[ i ], initdep[ ftable[ i ] ], depcmd )
|
||||
table.insert( deptargets, target )
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user