mirror of
https://github.com/elua/elua.git
synced 2025-01-25 01:02:54 +08:00
Merge branch 'luabuild' of vps.eluaproject.net:elua into luabuild
This commit is contained in:
commit
97d9cac313
2
.gitignore
vendored
2
.gitignore
vendored
@ -19,3 +19,5 @@ inc/git_version.h
|
||||
*~
|
||||
*.*~
|
||||
luac.cross*
|
||||
boards/*.h
|
||||
|
||||
|
3
boards/custom/.gitignore
vendored
Normal file
3
boards/custom/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*
|
||||
!.gitignore
|
||||
|
3
boards/headers/.gitignore
vendored
Normal file
3
boards/headers/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*
|
||||
!.gitignore
|
||||
|
26
boards/known/elua-puc.lua
Normal file
26
boards/known/elua-puc.lua
Normal file
@ -0,0 +1,26 @@
|
||||
-- eLua-PUC board build configuration
|
||||
|
||||
return {
|
||||
cpu = 'lpc2468',
|
||||
components = {
|
||||
sercon = { uart = 0, speed = 115200, buf_size = 128 },
|
||||
romfs = true,
|
||||
shell = true,
|
||||
term = { lines = 25, cols = 80 },
|
||||
cints = true,
|
||||
luaints = true,
|
||||
linenoise = { shell_lines = 10, lua_lines = 50 },
|
||||
rpc = { uart = 0, speed = 115200 },
|
||||
adc = { buf_size = 4, first_timer = 0, num_timers = 4 },
|
||||
xmodem = true
|
||||
},
|
||||
config = {
|
||||
vtmr = { num = 4, freq = 4 },
|
||||
extmem = { start = { 0xA0000000 }, size = { 8 * 1048576 } }
|
||||
},
|
||||
modules = {
|
||||
generic = 'all',
|
||||
exclude_generic = { "i2c", "net", "spi", "can" },
|
||||
}
|
||||
}
|
||||
|
29
boards/known/et-stm32.lua
Normal file
29
boards/known/et-stm32.lua
Normal file
@ -0,0 +1,29 @@
|
||||
-- ET-STM32 build configuration
|
||||
|
||||
return {
|
||||
cpu = 'stm32f103re',
|
||||
components = {
|
||||
sercon = { uart = 0, speed = 115200, buf_size = 128 },
|
||||
wofs = true,
|
||||
romfs = true,
|
||||
shell = true,
|
||||
term = { lines = 25, cols = 80 },
|
||||
cints = true,
|
||||
luaints = true,
|
||||
linenoise = { shell_lines = 10, lua_lines = 50 },
|
||||
stm32_enc = true,
|
||||
rpc = { uart = 0, speed = 115200 },
|
||||
adc = { buf_size = 4 },
|
||||
xmodem = true
|
||||
},
|
||||
config = {
|
||||
egc = { mode = "alloc" },
|
||||
vtmr = { num = 4, freq = 10 },
|
||||
},
|
||||
modules = {
|
||||
generic = 'all',
|
||||
exclude_generic = { "i2c", "net" },
|
||||
platform = 'all',
|
||||
}
|
||||
}
|
||||
|
16
boards/known/mod711.lua
Normal file
16
boards/known/mod711.lua
Normal file
@ -0,0 +1,16 @@
|
||||
-- MOD711 build configuration
|
||||
|
||||
return {
|
||||
cpu = 'str711fr2',
|
||||
components = {
|
||||
sercon = { uart = 1, speed = 38400, timer = 0 },
|
||||
romfs = true,
|
||||
shell = true,
|
||||
term = { lines = 25, cols = 80 },
|
||||
xmodem = true
|
||||
},
|
||||
modules = {
|
||||
generic = { 'pio', 'tmr', 'pd', 'pwm', 'uart', 'term', 'pack', 'bit', 'elua', 'cpu', 'math' }
|
||||
}
|
||||
}
|
||||
|
16
boards/known/sim.lua
Normal file
16
boards/known/sim.lua
Normal file
@ -0,0 +1,16 @@
|
||||
-- eLua simulator running on linux
|
||||
|
||||
return {
|
||||
cpu = 'linux',
|
||||
components = {
|
||||
sercon = { uart = 0, speed = 0 },
|
||||
wofs = true,
|
||||
romfs = true,
|
||||
shell = true,
|
||||
term = { lines = 25, cols = 80 },
|
||||
},
|
||||
modules = {
|
||||
generic = { 'pd', 'math', 'term', 'elua' }
|
||||
}
|
||||
}
|
||||
|
30
boards/known/stm3210e-eval.lua
Normal file
30
boards/known/stm3210e-eval.lua
Normal file
@ -0,0 +1,30 @@
|
||||
-- STM3210E-EVAL build configuration
|
||||
|
||||
return {
|
||||
cpu = 'stm32f103ze',
|
||||
components = {
|
||||
sercon = { uart = 0, speed = 115200, buf_size = 128 },
|
||||
wofs = true,
|
||||
romfs = true,
|
||||
shell = true,
|
||||
term = { lines = 25, cols = 80 },
|
||||
cints = true,
|
||||
luaints = true,
|
||||
linenoise = { shell_lines = 10, lua_lines = 50 },
|
||||
stm32_enc = true,
|
||||
rpc = { uart = 0, speed = 115200 },
|
||||
adc = { buf_size = 4 },
|
||||
xmodem = true,
|
||||
mmcfs = { cs_port = 0, cs_pin = 8, spi = 0 }
|
||||
},
|
||||
config = {
|
||||
egc = { mode = "alloc" },
|
||||
vtmr = { num = 4, freq = 10 },
|
||||
},
|
||||
modules = {
|
||||
generic = 'all',
|
||||
exclude_generic = { "i2c", "net" },
|
||||
platform = 'all',
|
||||
}
|
||||
}
|
||||
|
163
build_data.lua
Normal file
163
build_data.lua
Normal file
@ -0,0 +1,163 @@
|
||||
-- eLua build data
|
||||
-- This contains various build time information:
|
||||
-- supported toolchains
|
||||
-- supported platforms and CPUs
|
||||
|
||||
module( ..., package.seeall )
|
||||
local utils = require "utils"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Build data
|
||||
|
||||
-- List of toolchains
|
||||
local toolchain_list =
|
||||
{
|
||||
[ 'arm-gcc' ] = {
|
||||
compile = 'arm-elf-gcc',
|
||||
link = 'arm-elf-ld',
|
||||
asm = 'arm-elf-as',
|
||||
bin = 'arm-elf-objcopy',
|
||||
size = 'arm-elf-size',
|
||||
cross_cpumode = 'little',
|
||||
cross_lua = 'float_arm 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
},
|
||||
[ 'arm-eabi-gcc' ] = {
|
||||
compile = 'arm-eabi-gcc',
|
||||
link = 'arm-eabi-ld',
|
||||
asm = 'arm-eabi-as',
|
||||
bin = 'arm-eabi-objcopy',
|
||||
size = 'arm-eabi-size',
|
||||
cross_cpumode = 'little',
|
||||
cross_lua = 'float 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
},
|
||||
codesourcery = {
|
||||
compile = 'arm-none-eabi-gcc',
|
||||
link = 'arm-none-eabi-ld',
|
||||
asm = 'arm-none-eabi-as',
|
||||
bin = 'arm-none-eabi-objcopy',
|
||||
size = 'arm-none-eabi-size',
|
||||
cross_cpumode = 'little',
|
||||
cross_lua = 'float 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
},
|
||||
[ 'avr32-gcc' ] = {
|
||||
compile = 'avr32-gcc',
|
||||
link = 'avr32-ld',
|
||||
asm = 'avr32-as',
|
||||
bin = 'avr32-objcopy',
|
||||
size = 'avr32-size',
|
||||
cross_cpumode = 'big',
|
||||
cross_lua = 'float 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
},
|
||||
[ 'avr32-unknown-none-gcc' ] = {
|
||||
compile = 'avr32-unknown-none-gcc',
|
||||
link = 'avr32-unknown-none-ld',
|
||||
asm = 'avr32-unknown-none-as',
|
||||
bin = 'avr32-unknown-none-objcopy',
|
||||
size = 'avr32-unknown-none-size',
|
||||
cross_cpumode = 'big',
|
||||
cross_lua = 'float 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
},
|
||||
[ 'i686-gcc' ] = {
|
||||
compile = 'i686-elf-gcc',
|
||||
link = 'i686-elf-ld',
|
||||
asm = 'nasm',
|
||||
bin = 'i686-elf-objcopy',
|
||||
size = 'i686-elf-size',
|
||||
cross_cpumode = 'little',
|
||||
cross_lua = 'float 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
}
|
||||
}
|
||||
|
||||
-- Toolchain Aliases
|
||||
toolchain_list[ 'devkitarm' ] = toolchain_list[ 'arm-eabi-gcc' ]
|
||||
|
||||
-- List of acrhitectures and their endianness
|
||||
local arch_data = {
|
||||
arm = 'little',
|
||||
cortexm3 = 'little',
|
||||
cortexm4 = 'little',
|
||||
avr32 = 'big',
|
||||
i386 = 'little'
|
||||
}
|
||||
|
||||
-- Toolchain to arch mapping
|
||||
local toolchain_map = {
|
||||
arm = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' },
|
||||
cortexm3 = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' },
|
||||
cortexm4 = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' },
|
||||
avr32 = { 'avr32-gcc', 'avr32-unknown-none-gcc' },
|
||||
i386 = { 'i686-gcc' }
|
||||
}
|
||||
|
||||
-- List of platform/CPU combinations
|
||||
local platform_list =
|
||||
{
|
||||
at91sam7x = { cpus = { 'AT91SAM7X256', 'AT91SAM7X512' }, arch = 'arm' },
|
||||
lm3s = { cpus = { 'LM3S1968', 'LM3S8962', 'LM3S6965', 'LM3S6918', 'LM3S9B92', 'LM3S9D92' }, arch = 'cortexm3' },
|
||||
str9 = { cpus = { 'STR912FAW44' }, arch = 'arm' },
|
||||
i386 = { cpus = { 'I386' }, arch = 'i386' },
|
||||
sim = { cpus = { 'LINUX' }, arch = 'i386' },
|
||||
lpc288x = { cpus = { 'LPC2888' }, arch = 'arm' },
|
||||
str7 = { cpus = { 'STR711FR2' }, arch = 'arm' },
|
||||
stm32 = { cpus = { 'STM32F103ZE', 'STM32F103RE' }, arch = 'cortexm3' },
|
||||
avr32 = { cpus = { 'AT32UC3A0128', 'AT32UC3A0256', 'AT32UC3A0512', 'AT32UC3B0256' }, arch = 'avr32' },
|
||||
lpc24xx = { cpus = { 'LPC2468' }, arch = 'arm' },
|
||||
lpc17xx = { cpus = { 'LPC1768' }, arch = 'cortexm3' }
|
||||
}
|
||||
|
||||
-- Returns the platform of a given CPU
|
||||
function get_platform_of_cpu( cpu )
|
||||
for p, v in pairs( platform_list ) do
|
||||
if utils.array_element_index( v.cpus, cpu:upper() ) then return p end
|
||||
end
|
||||
end
|
||||
|
||||
-- Return all the CPUs in the 'platform_list' table
|
||||
function get_all_cpus()
|
||||
local t = {}
|
||||
for pl, desc in pairs( platform_list ) do
|
||||
for _, cpu in pairs( desc.cpus ) do
|
||||
if not utils.array_element_index( t, cpu ) then t[ #t + 1 ] = cpu end
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
-- Returns the complete list of toolchains
|
||||
function get_all_toolchains()
|
||||
local t = {}
|
||||
for arch, chains in pairs( toolchain_map ) do
|
||||
for _, cname in pairs( chains ) do
|
||||
if not utils.array_element_index( t, cname ) then t[ #t + 1 ] = cname end
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
-- Returns the list of toolchains for a given platform
|
||||
function get_toolchains_of_platform( platform )
|
||||
return toolchain_map[ platform_list[ platform ].arch ]
|
||||
end
|
||||
|
||||
-- Returns the data of the given toolchain
|
||||
function get_toolchain_data( name )
|
||||
return toolchain_list[ name ]
|
||||
end
|
||||
|
||||
-- Returns the endianness of the given platform
|
||||
function get_endianness_of_platform( platform )
|
||||
return arch_data[ platform_list[ platform ].arch ]
|
||||
end
|
||||
|
290
build_elua.lua
290
build_elua.lua
@ -20,6 +20,10 @@
|
||||
local args = { ... }
|
||||
local b = require "utils.build"
|
||||
local mkfs = require "utils.mkfs"
|
||||
local bconf = require "config.config"
|
||||
local board_base_dir = "boards"
|
||||
local bd = require "build_data"
|
||||
|
||||
builder = b.new_builder()
|
||||
utils = b.utils
|
||||
sf = string.format
|
||||
@ -75,143 +79,30 @@ function addlib( data )
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Build data
|
||||
|
||||
-- List of toolchains
|
||||
local toolchain_list =
|
||||
{
|
||||
[ 'arm-gcc' ] = {
|
||||
compile = 'arm-elf-gcc',
|
||||
link = 'arm-elf-ld',
|
||||
asm = 'arm-elf-as',
|
||||
bin = 'arm-elf-objcopy',
|
||||
size = 'arm-elf-size',
|
||||
cross_cpumode = 'little',
|
||||
cross_lua = 'float_arm 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
},
|
||||
[ 'arm-eabi-gcc' ] = {
|
||||
compile = 'arm-eabi-gcc',
|
||||
link = 'arm-eabi-ld',
|
||||
asm = 'arm-eabi-as',
|
||||
bin = 'arm-eabi-objcopy',
|
||||
size = 'arm-eabi-size',
|
||||
cross_cpumode = 'little',
|
||||
cross_lua = 'float 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
},
|
||||
codesourcery = {
|
||||
compile = 'arm-none-eabi-gcc',
|
||||
link = 'arm-none-eabi-ld',
|
||||
asm = 'arm-none-eabi-as',
|
||||
bin = 'arm-none-eabi-objcopy',
|
||||
size = 'arm-none-eabi-size',
|
||||
cross_cpumode = 'little',
|
||||
cross_lua = 'float 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
},
|
||||
[ 'avr32-gcc' ] = {
|
||||
compile = 'avr32-gcc',
|
||||
link = 'avr32-ld',
|
||||
asm = 'avr32-as',
|
||||
bin = 'avr32-objcopy',
|
||||
size = 'avr32-size',
|
||||
cross_cpumode = 'big',
|
||||
cross_lua = 'float 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
},
|
||||
[ 'avr32-unknown-none-gcc' ] = {
|
||||
compile = 'avr32-unknown-none-gcc',
|
||||
link = 'avr32-unknown-none-ld',
|
||||
asm = 'avr32-unknown-none-as',
|
||||
bin = 'avr32-unknown-none-objcopy',
|
||||
size = 'avr32-unknown-none-size',
|
||||
cross_cpumode = 'big',
|
||||
cross_lua = 'float 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
},
|
||||
[ 'i686-gcc' ] = {
|
||||
compile = 'i686-elf-gcc',
|
||||
link = 'i686-elf-ld',
|
||||
asm = 'nasm',
|
||||
bin = 'i686-elf-objcopy',
|
||||
size = 'i686-elf-size',
|
||||
cross_cpumode = 'little',
|
||||
cross_lua = 'float 64',
|
||||
cross_lualong = 'int 32',
|
||||
version = '--version'
|
||||
}
|
||||
}
|
||||
-- Return the full path of a board configuration file
|
||||
local function get_conf_file_path( bname )
|
||||
local known_board_name = utils.concat_path( { board_base_dir, "known", bname .. ".lua" } )
|
||||
local custom_board_name = utils.concat_path( { board_base_dir, "custom", bname .. ".lua" } )
|
||||
if utils.is_file( custom_board_name ) then return custom_board_name end
|
||||
if utils.is_file( known_board_name ) then return known_board_name end
|
||||
assert( sf( "board configuration file for board '%s' not found!", bname ) )
|
||||
end
|
||||
|
||||
-- Toolchain Aliases
|
||||
toolchain_list[ 'devkitarm' ] = toolchain_list[ 'arm-eabi-gcc' ]
|
||||
|
||||
-- List of platform/CPU/toolchains combinations
|
||||
-- The first toolchain in the toolchains list is the default one
|
||||
-- (the one that will be used if none is specified)
|
||||
local platform_list =
|
||||
{
|
||||
at91sam7x = { cpus = { 'AT91SAM7X256', 'AT91SAM7X512' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' }, big_endian = false },
|
||||
lm3s = { cpus = { 'LM3S1968', 'LM3S8962', 'LM3S6965', 'LM3S6918', 'LM3S9B92', 'LM3S9D92' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' }, big_endian = false },
|
||||
str9 = { cpus = { 'STR912FAW44' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' }, big_endian = false },
|
||||
i386 = { cpus = { 'I386' }, toolchains = { 'i686-gcc' }, big_endian = false },
|
||||
sim = { cpus = { 'LINUX' }, toolchains = { 'i686-gcc' }, big_endian = false },
|
||||
lpc288x = { cpus = { 'LPC2888' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' }, big_endian = false },
|
||||
str7 = { cpus = { 'STR711FR2' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' }, big_endian = false },
|
||||
stm32 = { cpus = { 'STM32F103ZE', 'STM32F103RE' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' }, big_endian = false },
|
||||
avr32 = { cpus = { 'AT32UC3A0128', 'AT32UC3A0256', 'AT32UC3A0512', 'AT32UC3B0256' }, toolchains = { 'avr32-gcc', 'avr32-unknown-none-gcc' }, big_endian = true },
|
||||
lpc24xx = { cpus = { 'LPC2468' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' }, big_endian = false },
|
||||
lpc17xx = { cpus = { 'LPC1768' }, toolchains = { 'arm-gcc', 'codesourcery', 'devkitarm', 'arm-eabi-gcc' }, big_endian = false }
|
||||
}
|
||||
|
||||
-- List of board/CPU combinations
|
||||
local board_list =
|
||||
{
|
||||
[ 'SAM7-EX256' ] = { 'AT91SAM7X256', 'AT91SAM7X512' },
|
||||
[ 'EK-LM3S1968' ] = { 'LM3S1968' },
|
||||
[ 'EK-LM3S8962' ] = { 'LM3S8962' },
|
||||
[ 'EK-LM3S6965' ] = { 'LM3S6965' },
|
||||
[ 'EK-LM3S9B92' ] = { 'LM3S9B92' },
|
||||
[ 'SOLDERCORE' ] = { 'LM3S9D92' },
|
||||
[ 'STR9-COMSTICK' ] = { 'STR912FAW44' },
|
||||
[ 'STR-E912' ] = { 'STR912FAW44' },
|
||||
[ 'PC' ] = { 'I386' },
|
||||
[ 'SIM' ] = { 'LINUX' },
|
||||
[ 'LPC-H2888' ] = { 'LPC2888' },
|
||||
[ 'MOD711' ] = { 'STR711FR2' },
|
||||
[ 'STM3210E-EVAL' ] = { 'STM32F103ZE' },
|
||||
[ 'ATEVK1100' ] = { 'AT32UC3A0512' },
|
||||
[ 'ATEVK1101' ] = { 'AT32UC3B0256' },
|
||||
[ 'ET-STM32' ] = { 'STM32F103RE' },
|
||||
[ 'EAGLE-100' ] = { 'LM3S6918' },
|
||||
[ 'ELUA-PUC' ] = { 'LPC2468' },
|
||||
[ 'MBED' ] = { 'LPC1768' },
|
||||
[ 'MIZAR32' ] = { 'AT32UC3A0256', 'AT32UC3A0512', 'AT32UC3A0128' },
|
||||
[ 'NETDUINO' ] = { 'AT91SAM7X512' },
|
||||
[ 'EK-LM3S9D92' ] = { 'LM3S9D92' }
|
||||
}
|
||||
|
||||
-- Build the CPU list starting from the above list
|
||||
local cpu_list = {}
|
||||
for k, v in pairs( board_list ) do
|
||||
local clist = v
|
||||
for i = 1, #clist do
|
||||
if not utils.array_element_index( cpu_list, clist[ i ] ) then
|
||||
table.insert( cpu_list, clist[ i ] )
|
||||
end
|
||||
end
|
||||
-- Automatically build the list of available boards by scanning the board_base_dir directory
|
||||
local board_flist = utils.linearize_array( utils.string_to_table( utils.get_files( board_base_dir, "%.lua$" ) ) )
|
||||
local board_list = {}
|
||||
for k, v in pairs( board_flist ) do
|
||||
local temp = utils.replace_extension( v, '' )
|
||||
temp = utils.string_to_table( temp, utils.dir_sep )
|
||||
temp = temp[ #temp ] -- now 'temp' contains the actual name of the board
|
||||
if not utils.array_element_index( board_list, temp ) then board_list[ #board_list + 1 ] = temp end
|
||||
end
|
||||
|
||||
builder:add_option( 'target', 'build "regular" float lua, 32 bit integer-only "lualong" or 64-bit integer only lua "lualonglong"', 'lua', { 'lua', 'lualong', 'lualonglong' } )
|
||||
builder:add_option( 'cpu', 'build for the specified CPU (board will be inferred, if possible)', 'auto', { cpu_list, 'auto' } )
|
||||
builder:add_option( 'allocator', 'select memory allocator', 'auto', { 'newlib', 'multiple', 'simple', 'auto' } )
|
||||
builder:add_option( 'board', 'selects board for target (cpu will be inferred)', 'auto', { utils.table_keys( board_list ), 'auto' } )
|
||||
builder:add_option( 'toolchain', 'specifies toolchain to use (auto=search for usable toolchain)', 'auto', { utils.table_keys( toolchain_list ), 'auto' } )
|
||||
builder:add_option( 'board', 'selects board for target (cpu will be inferred)', nil, board_list )
|
||||
builder:add_option( 'toolchain', 'specifies toolchain to use (auto=search for usable toolchain)', 'auto', { bd.get_all_toolchains(), 'auto' } )
|
||||
builder:add_option( 'optram', 'enables Lua Tiny RAM enhancements', true )
|
||||
builder:add_option( 'boot', 'boot mode, standard will boot to shell, luarpc boots to an rpc server', 'standard', { 'standard' , 'luarpc' } )
|
||||
builder:add_option( 'romfs', 'ROMFS compilation mode', 'verbatim', { 'verbatim' , 'compress', 'compile' } )
|
||||
@ -225,83 +116,111 @@ builder:set_build_mode( builder.BUILD_DIR_LINEARIZED )
|
||||
comp = {}
|
||||
setmetatable( comp, { __index = function( t, key ) return builder:get_option( key ) end } )
|
||||
|
||||
-- Variants: board = <board>
|
||||
-- cpu = <cpuname>
|
||||
-- board = <board> cpu=<cpuname>
|
||||
if comp.board == 'auto' and comp.cpu == 'auto' then
|
||||
print "You must specify board, cpu, or both"
|
||||
if not comp.board then
|
||||
print "You must specify the board"
|
||||
os.exit( -1 )
|
||||
elseif comp.board ~= 'auto' and comp.cpu ~= 'auto' then
|
||||
-- Check if the board, cpu pair is correct
|
||||
if utils.array_element_index( board_list[ comp.board:upper() ], comp.cpu:upper() ) == nil then
|
||||
print( sf( "Invalid CPU '%s' for board '%s'" , comp.cpu, comp.board ) )
|
||||
os.exit( -1 )
|
||||
end
|
||||
elseif comp.board ~= 'auto' then
|
||||
-- Find CPU
|
||||
comp.cpu = board_list[ comp.board:upper() ][ 1 ]
|
||||
else
|
||||
-- cpu = <cputype>
|
||||
-- Find board name
|
||||
for b, v in pairs( board_list ) do
|
||||
if utils.array_element_index( v, comp.cpu:upper() ) then
|
||||
comp.board = b
|
||||
break
|
||||
end
|
||||
end
|
||||
if comp.board == 'auto' then
|
||||
print( sf( "CPU '%s' not found", comp.cpu ) )
|
||||
os.exit( -1 )
|
||||
end
|
||||
end
|
||||
|
||||
-- Look for the given CPU in the list of platforms
|
||||
for p, v in pairs( platform_list ) do
|
||||
if utils.array_element_index( v.cpus, comp.cpu:upper() ) then
|
||||
platform = p
|
||||
break
|
||||
-- Interpret the board definition file
|
||||
local bfname = get_conf_file_path( comp.board )
|
||||
if not bfname then
|
||||
io.write( utils.col_red( sf( "[CONFIG] Error: board configuration file for board '%s' not found in '%s'.", comp.board, board_base_dir ) ) )
|
||||
os.exit( -1 )
|
||||
end
|
||||
print( utils.col_blue( "[CONFIG] Found board description file at " .. bfname ) )
|
||||
local bdata, err = bconf.compile_board( bfname, comp.board )
|
||||
if not bdata then
|
||||
print( utils.col_red( "[CONFIG] Error compiling board description file: " .. err ) )
|
||||
do return end
|
||||
end
|
||||
-- Check if the file has changed. If not, do not rewrite it. This keeps the compilation time sane.
|
||||
local bhname = utils.concat_path( { board_base_dir, "headers", "board_" .. comp.board:lower() .. ".h" } )
|
||||
if utils.get_hash_of_string( bdata.header ) ~= utils.get_hash_of_file( bhname ) or not utils.is_file( bhname ) then
|
||||
-- Save the header file
|
||||
local f = assert( io.open( bhname, "wb" ) )
|
||||
f:write( bdata.header )
|
||||
f:close()
|
||||
print( utils.col_blue( "[CONFIG] Generated board header file at " .. bhname ) )
|
||||
else
|
||||
print( utils.col_blue( "[CONFIG] Board header file is unchanged." ) )
|
||||
end
|
||||
-- Define the correct CPU header for inclusion in the platform_conf.h file
|
||||
addm( 'ELUA_CPU_HEADER="\\"cpu_' .. bdata.cpu:lower() .. '.h\\""' )
|
||||
-- Define the correct board header for inclusion in the platform_conf.h file
|
||||
addm( 'ELUA_BOARD_HEADER="\\"board_' .. comp.board:lower() .. '.h\\""' )
|
||||
-- Make available the board directory for the generated header files
|
||||
addi( utils.concat_path{ board_base_dir, "headers" } )
|
||||
-- Force target if needed
|
||||
if bdata.target and bdata.target ~= comp.target then
|
||||
if builder:is_user_option( 'target' ) then
|
||||
print( utils.col_yellow( sf( "[CONFIG] WARNING: changing the target from '%s' to '%s' as specified in the command line", bdata.target, comp.target ) ) )
|
||||
else
|
||||
comp.target = bdata.target
|
||||
end
|
||||
end
|
||||
-- Force allocator if needed
|
||||
if bdata.allocator then
|
||||
if comp.allocator == "auto" then
|
||||
comp.allocator = bdata.allocator
|
||||
elseif bdata.allocator ~= comp.allocator then
|
||||
if builder:is_user_option( 'allocator' ) then
|
||||
print( utils.col_yellow( sf( "[CONFIG] WARNING: changing the allocator from '%s' to '%s' as specified in the command line", bdata.allocator, comp.allocator ) ) )
|
||||
else
|
||||
comp.allocator = bdata.allocator
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Automatically set the allocator to 'multiple' if needed
|
||||
if bdata.multi_alloc and comp.allocator == "newlib" then
|
||||
io.write( utils.col_yellow( "[CONFIG] WARNING: your board has non-contigous RAM areas, but you specified an allocator ('newlib') that can't handle this configuration." ) )
|
||||
print( utils.col_yellow( "Rebuild with another allocator ('multiple' or 'simple')" ) )
|
||||
end
|
||||
if comp.allocator == "auto" and bdata.multi_alloc then comp.allocator = "multiple" end
|
||||
comp.cpu = bdata.cpu:upper()
|
||||
|
||||
platform = bd.get_platform_of_cpu( comp.cpu )
|
||||
if not platform then
|
||||
print( "Unable to find platform (this shouldn't happen, check the build script for errors)" )
|
||||
os.exit( -1 )
|
||||
end
|
||||
|
||||
-- Check the toolchain
|
||||
local usable_chains = bd.get_toolchains_of_platform( platform )
|
||||
if comp.toolchain ~= 'auto' then
|
||||
if utils.array_element_index( platform_list[ platform ].toolchains, comp.toolchain ) == nil then
|
||||
if utils.array_element_index( usable_chains, comp.toolchain ) == nil then
|
||||
print( sf( "Invalid toolchain '%s' for CPU '%s'", comp.toolchain, comp.cpu ) )
|
||||
print( sf( "List of accepted toolchains (for %s): %s", comp.cpu, table.concat( usable_chains, "," ) ) )
|
||||
os.exit( -1 )
|
||||
end
|
||||
toolset = toolchain_list[ comp.toolchain ]
|
||||
toolset = bd.get_toolchain_data( comp.toolchain )
|
||||
comp.CC = toolset.compile
|
||||
comp.AS = toolset.compile
|
||||
else
|
||||
-- If 'auto' try to match a working toolchain with target
|
||||
local usable_chains = platform_list[ platform ].toolchains
|
||||
-- Try to execute all compilers, exit when one found
|
||||
local chain
|
||||
for i = 1, #usable_chains do
|
||||
local c = usable_chains[ i ]
|
||||
local t = toolchain_list[ c ]
|
||||
local t = bd.get_toolchain_data( c )
|
||||
local res = utils.check_command( t.compile .. " " .. t.version )
|
||||
if res == 0 then chain = c break end
|
||||
end
|
||||
if chain then
|
||||
comp.toolchain = chain
|
||||
comp.CC = toolchain_list[ chain ].compile
|
||||
toolset = bd.get_toolchain_data( chain )
|
||||
comp.CC = toolset.compile
|
||||
comp.AS = comp.CC
|
||||
toolset = toolchain_list[ chain ]
|
||||
else
|
||||
print "Unable to find an usable toolchain in your path."
|
||||
print( sf( "List of accepted toolchains (for %s): %s", comp.cpu, table.concat( usable_chains ) ) )
|
||||
print( sf( "List of accepted toolchains (for %s): %s", comp.cpu, table.concat( usable_chains, "," ) ) )
|
||||
os.exit( -1 )
|
||||
end
|
||||
end
|
||||
|
||||
-- CPU/allocator mapping (if allocator not specified)
|
||||
-- TODO: this needs to go away too, since the allocator is now automatically inferred
|
||||
if comp.allocator == 'auto' then
|
||||
if comp.board:upper() == 'MIZAR32' and comp.cpu:upper() == 'AT32UC3A0128' then
|
||||
if comp.board:upper() == 'MIZAR32' or comp.cpu:upper() == 'AT32UC3A0128' then
|
||||
comp.allocator = 'simple'
|
||||
elseif utils.array_element_index( { 'LPC-H2888', 'ATEVK1100', 'MIZAR32', 'MBED' }, comp.board:upper() ) then
|
||||
comp.allocator = 'multiple'
|
||||
@ -314,7 +233,7 @@ end
|
||||
local fscompcmd = ''
|
||||
if comp.romfs == 'compile' then
|
||||
if comp.target == 'lualonglong' then
|
||||
print "Cross-compilation is not yet supported for 64-bit integer only Lua (lualonglong)."
|
||||
print "Cross-compilation is not yet supported for 64-bit integer-only Lua (lualonglong)."
|
||||
os.exit( -1 )
|
||||
end
|
||||
local suffix = ''
|
||||
@ -341,18 +260,19 @@ if utils.check_command('git describe --always') == 0 then
|
||||
if string.find(elua_vers, "^[+-]?%x+$") then
|
||||
elua_vers = 'dev-' .. elua_vers
|
||||
end
|
||||
utils.gen_header('git_version',{elua_version=elua_vers, elua_str_version=("\"" .. elua_vers .. "\"")})
|
||||
local sver = utils.gen_header_string( 'git_version', { elua_version = elua_vers, elua_str_version = ("\"" .. elua_vers .. "\"" ) } )
|
||||
if utils.get_hash_of_string( sver ) ~= utils.get_hash_of_file( utils.concat_path{ 'inc', 'git_version.h' } ) then
|
||||
utils.gen_header_file( 'git_version', { elua_version = elua_vers, elua_str_version = ("\"" .. elua_vers .. "\"" ) } )
|
||||
end
|
||||
else
|
||||
print "WARNING: unable to determine version from repository"
|
||||
elua_vers = "unknown"
|
||||
end
|
||||
|
||||
|
||||
-- Output file
|
||||
output = 'elua_' .. comp.target .. '_' .. comp.cpu:lower()
|
||||
output = 'elua_' .. comp.target .. '_' .. comp.board:lower()
|
||||
builder:set_output_dir( ".build" .. utils.dir_sep .. comp.board:lower() )
|
||||
|
||||
|
||||
-- User report
|
||||
print ""
|
||||
print "*********************************"
|
||||
@ -389,9 +309,9 @@ if comp.boot == 'luarpc' then addm( "ELUA_BOOT_RPC" ) end
|
||||
if comp.target == 'lualong' or comp.target == 'lualonglong' then addm( "LUA_NUMBER_INTEGRAL" ) end
|
||||
if comp.target == 'lualonglong' then addm( "LUA_INTEGRAL_LONGLONG" ) end
|
||||
if comp.target ~= 'lualong' and comp.target ~= "lualonglong" then addm( "LUA_PACK_VALUE" ) end
|
||||
if platform_list[ platform ].big_endian then addm( "ELUA_ENDIAN_BIG" ) else addm( "ELUA_ENDIAN_LITTLE" ) end
|
||||
if bd.get_endianness_of_platform( platform ) == "big" then addm( "ELUA_ENDIAN_BIG" ) else addm( "ELUA_ENDIAN_LITTLE" ) end
|
||||
|
||||
-- Special macro definitions for the SYM target
|
||||
-- Special macro definitions for the SIM target
|
||||
if platform == 'sim' then addm( { "ELUA_SIMULATOR", "ELUA_SIM_" .. cnorm( comp.cpu ) } ) end
|
||||
|
||||
-- Lua source files and include path
|
||||
@ -430,11 +350,11 @@ romfs_exclude_patterns = { '%.DS_Store', '%.gitignore' }
|
||||
|
||||
function match_pattern_list( item, list )
|
||||
for k, v in pairs( list ) do
|
||||
if item:find(v) then return true end
|
||||
if item:find(v) then return true end
|
||||
end
|
||||
end
|
||||
|
||||
local function make_romfs()
|
||||
local function make_romfs( target, deps )
|
||||
print "Building ROM file system ..."
|
||||
local flist = {}
|
||||
flist = utils.string_to_table( utils.get_files( 'romfs', function( fname ) return not match_pattern_list( fname, romfs_exclude_patterns ) end ) )
|
||||
@ -491,11 +411,13 @@ builder:set_link_cmd( linkcmd )
|
||||
builder:set_asm_cmd( ascmd )
|
||||
builder:set_exe_extension( ".elf" )
|
||||
|
||||
-- Create the ROM file system
|
||||
make_romfs()
|
||||
-- Creaate executable targets
|
||||
-- Create the ROMFS target
|
||||
local romfs_target = builder:target( "#phony:romfs", nil, make_romfs )
|
||||
romfs_target:force_rebuild( true )
|
||||
|
||||
-- Create executable targets
|
||||
odeps = builder:create_compile_targets( source_files )
|
||||
exetarget = builder:link_target( output, odeps )
|
||||
exetarget = builder:link_target( output, { romfs_target, odeps } )
|
||||
-- This is also the default target
|
||||
builder:default( builder:add_target( exetarget, 'build eLua executable' ) )
|
||||
|
||||
|
182
config/attributes.lua
Normal file
182
config/attributes.lua
Normal file
@ -0,0 +1,182 @@
|
||||
-- Attributes are used by various parts of the board description
|
||||
-- system (for example configs and components)
|
||||
|
||||
module( ..., package.seeall )
|
||||
local ct = require "constants"
|
||||
local sf = string.format
|
||||
|
||||
-- Validator for a 'choice' attribute
|
||||
-- Returns the value if OK, (false, errmsg) for error
|
||||
-- Needs: attrvals - list of permitted values for this attribute
|
||||
local function _validate_choice( adesc, aname, aval, elname, sectname )
|
||||
aval = tostring( aval ):lower()
|
||||
for k, v in pairs( adesc.attrvals ) do
|
||||
if v == aval then return v end
|
||||
end
|
||||
return false, sf( "invalid value '%s' for attribute '%s' of element '%s' in section '%s'", aval, aname, elname, sectname )
|
||||
end
|
||||
|
||||
-- Validator for a 'number' attribute
|
||||
-- Returns the value if OK, (false, errmsg) for error
|
||||
-- Needs: attrtype - the number type ('int' or 'float')
|
||||
-- attrmin - minimum value (no minimum check will be performed if not specified)
|
||||
-- attrmax - maximum value (no maximum check will be performed if not specified)
|
||||
local function _validate_number( adesc, aname, aval, elname, sectname )
|
||||
aval = tonumber( aval )
|
||||
if not aval then return false, sf( "value of attribute '%s' for element '%s' in section '%s' must be a number", aname, elname, sectname ) end
|
||||
if adesc.attrtype == 'int' and math.floor( aval ) ~= aval then
|
||||
return false, sf( "value of attribute '%s' for element '%s' in section '%s' must be an integer", aname, elname, sectname )
|
||||
end
|
||||
local minval = adesc.attrmin or aval
|
||||
local maxval = adesc.attrmax or aval
|
||||
if aval < minval then
|
||||
return false, sf( "value of attribute '%s' for element '%s' in section '%s' must be larger than '%s'", aname, elname, sectname, tostring( minval ) )
|
||||
end
|
||||
if aval > maxval then
|
||||
return false, sf( "value of attribute '%s' for element '%s' in section '%s' must be smaller than '%s'", aname, elname, sectname, tostring( maxval ) )
|
||||
end
|
||||
return aval
|
||||
end
|
||||
|
||||
-- Validator for a log2 number attribute
|
||||
-- Works like number, but additionaly checks that the value is a power of 2
|
||||
-- Also changes the attribute value to its log2
|
||||
local function _validate_log2( adesc, aname, aval, elname, sectname )
|
||||
local res, err = _validate_number( adesc, aname, aval, elname, sectname )
|
||||
if not res then return res, err end
|
||||
if aval <= 0 then
|
||||
return false, sf( "value of attribute '%s' for element '%s' in section '%s' must be larger than 0", aname, elname, sectname )
|
||||
end
|
||||
local thelog = math.log( res ) / math.log( 2 )
|
||||
if thelog ~= math.floor( thelog ) then
|
||||
return false, sf( "value of attribute '%s' for element '%s' in section '%s' must be a power of 2", aname, elname, sectname )
|
||||
end
|
||||
return thelog
|
||||
end
|
||||
|
||||
-- Validator for a string attribute
|
||||
-- Return the string if OK, (false, errmsg) for error
|
||||
-- Needs: attrmaxsize - maximum size of the string
|
||||
local function _validate_string( adesc, aname, aval, elname, sectname )
|
||||
aval = tostring( aval )
|
||||
if type( aval ) ~= "string" then
|
||||
return false, sf( "value of attribute '%s' for element '%s' in section '%s' must be a string", aname, elname, sectname )
|
||||
end
|
||||
maxsize = adesc.attrmaxsize or math.huge
|
||||
if #aval > maxsize then
|
||||
return false, sf( "value of attribute '%s' for element '%s' in section '%s' must be less than %d chars in length", aname, elname, sectname, maxsize )
|
||||
end
|
||||
return aval
|
||||
end
|
||||
|
||||
-- Validator for an IP attribute
|
||||
-- Return the IP as a table of numbers if OK, (false, errmsg) for error
|
||||
local function _validate_ip( adesc, aname, aval, elname, sectname )
|
||||
if type( aval ) == "string" then -- transform this to table
|
||||
if aval:sub( -1, -1 ) ~= "." then aval = aval .. "." end -- add a final dot to make parsing easier
|
||||
local t = {}
|
||||
for w in aval:gmatch( "(%w+)%." ) do t[ #t + 1 ] = tonumber( w ) end
|
||||
aval = t
|
||||
elseif type( aval ) ~= "table" then
|
||||
return false, sf( "attribute '%s' of element '%s' in section '%s' must be a string or a table", aname, elname, sectname )
|
||||
end
|
||||
if #aval ~= 4 then return false, sf( "invalid IP for attribute '%s' of element '%s' in section '%s'", aname, elname, sectname ) end
|
||||
for i = 1, 4 do
|
||||
local e = aval[ i ]
|
||||
if type( e ) ~= "number" or math.floor( e ) ~= e or e < 0 or e > 255 then
|
||||
return false, sf( "invalid IP for attribute '%s' of element '%s' in section '%s'", aname, elname, sectname )
|
||||
end
|
||||
end
|
||||
return aval
|
||||
end
|
||||
|
||||
-- Builds a validator with the given array element checker
|
||||
local function build_validator( realvname )
|
||||
return function( adesc, aname, aval, elname, sectname )
|
||||
if not adesc.is_array then return realvname( adesc, aname, aval, elname, sectname ) end
|
||||
if type( aval ) ~= "table" then return false, sf( "value of attribute '%s' for element '%s' in section '%s' must be an array", aname, elname, sectname ) end
|
||||
for i = 1, #aval do
|
||||
local res, err = realvname( adesc, aname, aval[ i ], elname, sectname )
|
||||
if not res then
|
||||
return false, sf( "error at index %d: %s", i, err )
|
||||
else
|
||||
aval[ i ] = res
|
||||
end
|
||||
end
|
||||
return aval
|
||||
end
|
||||
end
|
||||
|
||||
local validate_number = build_validator( _validate_number )
|
||||
local validate_choice = build_validator( _validate_choice )
|
||||
local validate_log2 = build_validator( _validate_log2 )
|
||||
local validate_string = build_validator( _validate_string )
|
||||
local validate_ip = build_validator( _validate_ip )
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Public interface
|
||||
|
||||
-- Returns a new choice attribute with the given possible values
|
||||
function choice_attr( macro, values, default )
|
||||
return { macro = macro, default = default, validator = validate_choice, attrvals = values }
|
||||
end
|
||||
|
||||
-- Returns a new timer attribute with the given macro and default (systmr if not specified)
|
||||
function timer_attr( macro, default )
|
||||
default = default or 'systmr'
|
||||
local t = choice_attr( macro, utils.table_keys( ct.timer_values ), default )
|
||||
t.is_timer, t.mapping = true, ct.timer_values
|
||||
return t
|
||||
end
|
||||
|
||||
-- Returns a new integer number attribute with the given limits
|
||||
function int_attr( macro, minv, maxv, default )
|
||||
return { macro = macro, default = default, validator = validate_number, attrtype = 'int', attrmin = minv, attrmax = maxv }
|
||||
end
|
||||
|
||||
-- Returns a new UART attribute
|
||||
function uart_attr( macro, default )
|
||||
local t = choice_attr( macro, utils.table_keys( ct.uart_values ), default )
|
||||
t.is_uart, t.mapping = true, ct.uart_values
|
||||
return t
|
||||
end
|
||||
|
||||
-- Returns a new integer number attribute with the given limits
|
||||
-- The generated value will be the integer's base 2 logarithm
|
||||
function int_log2_attr( macro, minv, maxv, default )
|
||||
local t = int_attr( macro, minv, maxv, default )
|
||||
t.validator = validate_log2
|
||||
return t
|
||||
end
|
||||
|
||||
-- Returns a new flow control attribute
|
||||
function flow_control_attr( macro, default )
|
||||
default = default or 'none'
|
||||
local t = choice_attr( macro, utils.table_keys( ct.uart_flow ), default )
|
||||
t.mapping = ct.uart_flow
|
||||
return t
|
||||
end
|
||||
|
||||
-- Returns a new string attribute
|
||||
function string_attr( macro, maxsize, default )
|
||||
return { macro = macro, default = default, validator = validate_string, attrmaxsize = maxsize }
|
||||
end
|
||||
|
||||
-- Returns a new IP attribute
|
||||
function ip_attr( macro, default )
|
||||
return { macro = macro, default = default, validator = validate_ip, is_ip = true }
|
||||
end
|
||||
|
||||
-- Make the given attribute optional
|
||||
function make_optional( attr )
|
||||
attr.optional = true
|
||||
return attr
|
||||
end
|
||||
|
||||
-- Mark the given attribute as an array of element of the same type
|
||||
function array_of( attr )
|
||||
attr.is_array = true
|
||||
return attr
|
||||
end
|
||||
|
||||
|
166
config/components.lua
Normal file
166
config/components.lua
Normal file
@ -0,0 +1,166 @@
|
||||
-- eLua components description
|
||||
|
||||
module( ..., package.seeall )
|
||||
local at = require "attributes"
|
||||
local gen = require "generators"
|
||||
local sf = string.format
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Sermux support
|
||||
|
||||
local function sermux_auxcheck( eldesc, data, enabled )
|
||||
local v = data.SERMUX_BUFFER_SIZES.value
|
||||
if #v < 2 then
|
||||
return false, sf( "array 'buf_sizes' of element 'sermux' in section 'components' must have at least 2 elements" )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function sermux_auxgen( eldesc, data, generated )
|
||||
local v = data.SERMUX_BUFFER_SIZES.value
|
||||
return gen.print_define( 'SERMUX_NUM_VUART', #v )
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Public interface
|
||||
|
||||
-- Build all components needed by eLua, save them in the "components" table
|
||||
function init()
|
||||
local components = {}
|
||||
|
||||
-- Serial console
|
||||
components.sercon = {
|
||||
macro = 'BUILD_CON_GENERIC',
|
||||
attrs = {
|
||||
uart = at.uart_attr( 'CON_UART_ID' ),
|
||||
speed = at.int_attr( 'CON_UART_SPEED' ),
|
||||
timer = at.timer_attr( 'CON_TIMER_ID' ),
|
||||
flow = at.flow_control_attr( 'CON_FLOW_TYPE' ),
|
||||
buf_size = at.make_optional( at.int_log2_attr( 'CON_BUF_SIZE' ) )
|
||||
}
|
||||
}
|
||||
-- TCP/IP console
|
||||
components.tcpipcon = { macro = 'BUILD_CON_TCP', needs = 'tcpip' }
|
||||
-- UART buffering
|
||||
-- Not really a component, not quite a config ... Implementation wise,
|
||||
-- it is easier to declare it as a component
|
||||
components.uart_buffers = { macro = 'BUF_ENABLE_UART' }
|
||||
-- XMODEM
|
||||
components.xmodem = {
|
||||
macro = 'BUILD_XMODEM',
|
||||
attrs = {
|
||||
uart = at.uart_attr( 'CON_UART_ID' ),
|
||||
speed = at.int_attr( 'CON_UART_SPEED' ),
|
||||
timer = at.timer_attr( 'CON_TIMER_ID' ),
|
||||
flow = at.flow_control_attr( 'CON_FLOW_TYPE'),
|
||||
buf_size = at.make_optional( at.int_log2_attr( 'CON_BUF_SIZE' ) )
|
||||
}
|
||||
}
|
||||
-- Shell
|
||||
components.shell = { macro = 'BUILD_SHELL' }
|
||||
-- Term
|
||||
components.term = {
|
||||
macro = 'BUILD_TERM',
|
||||
attrs = {
|
||||
uart = at.uart_attr( 'CON_UART_ID' ),
|
||||
speed = at.int_attr( 'CON_UART_SPEED' ),
|
||||
timer = at.timer_attr( 'CON_TIMER_ID' ),
|
||||
flow = at.flow_control_attr( 'CON_FLOW_TYPE' ),
|
||||
buf_size = at.make_optional( at.int_log2_attr( 'CON_BUF_SIZE' ) ),
|
||||
lines = at.int_attr( 'TERM_LINES' ),
|
||||
cols = at.int_attr( 'TERM_COLS' )
|
||||
}
|
||||
}
|
||||
-- C interrupt support
|
||||
components.cints = { macro = 'BUILD_C_INT_HANDLERS' }
|
||||
-- Lua interrupt support
|
||||
components.luaints = {
|
||||
macro = 'BUILD_LUA_INT_HANDLERS',
|
||||
attrs = {
|
||||
queue_size = at.int_log2_attr( 'PLATFORM_INT_QUEUE_LOG_SIZE', nil, nil, 5 )
|
||||
},
|
||||
needs = 'cints'
|
||||
}
|
||||
-- Linenoise
|
||||
components.linenoise = {
|
||||
macro = 'BUILD_LINENOISE',
|
||||
attrs = {
|
||||
shell_lines = at.int_attr( 'LINENOISE_HISTORY_SIZE_SHELL' ),
|
||||
lua_lines = at.int_attr( 'LINENOISE_HISTORY_SIZE_LUA' ),
|
||||
autosave_file = at.make_optional( at.string_attr( 'LINENOISE_AUTOSAVE_FNAME', 32 ) )
|
||||
}
|
||||
}
|
||||
-- RFS
|
||||
components.rfs = {
|
||||
macro = 'BUILD_RFS',
|
||||
attrs = {
|
||||
uart = at.uart_attr( 'RFS_UART_ID' ),
|
||||
speed = at.int_attr( 'RFS_UART_SPEED' ),
|
||||
timer = at.timer_attr( 'RFS_TIMER_ID' ),
|
||||
flow = at.flow_control_attr( 'RFS_FLOW_TYPE' ),
|
||||
buf_size = at.int_log2_attr( 'RFS_BUFFER_SIZE', nil, nil, 9 ),
|
||||
timeout = at.int_attr( 'RFS_TIMEOUT', nil, nil, 100000 )
|
||||
}
|
||||
}
|
||||
-- MMCFS
|
||||
components.mmcfs = {
|
||||
macro = 'BUILD_MMCFS',
|
||||
attrs = {
|
||||
cs_port = at.int_attr( 'MMCFS_CS_PORT' ),
|
||||
cs_pin = at.int_attr( 'MMCFS_CS_PIN' ),
|
||||
spi = at.int_attr( 'MMCFS_SPI_NUM' )
|
||||
}
|
||||
}
|
||||
-- RPC
|
||||
-- (values are optional, since they are required only if booting in RPC mode)
|
||||
components.rpc = {
|
||||
macro = 'BUILD_RPC',
|
||||
attrs = {
|
||||
uart = at.make_optional( at.uart_attr( 'RPC_UART_ID' ) ),
|
||||
speed = at.make_optional( at.int_attr( 'RPC_UART_SPEED' ) ),
|
||||
timer = at.make_optional( at.timer_attr( 'RPC_TIMER_ID' ) )
|
||||
}
|
||||
}
|
||||
-- TCP/IP
|
||||
components.tcpip = {
|
||||
macro = 'BUILD_UIP',
|
||||
attrs = {
|
||||
ip = at.ip_attr( 'ELUA_CONF_IPADDR' ),
|
||||
netmask = at.ip_attr( 'ELUA_CONF_NETMASK' ),
|
||||
gw = at.ip_attr( 'ELUA_CONF_DEFGW' ),
|
||||
dns = at.ip_attr( 'ELUA_CONF_DNS' )
|
||||
}
|
||||
}
|
||||
-- Serial multiplexer
|
||||
components.sermux = {
|
||||
macro = 'BUILD_SERMUX',
|
||||
auxgen = sermux_auxgen,
|
||||
auxcheck = sermux_auxcheck,
|
||||
attrs = {
|
||||
uart = at.uart_attr( 'SERMUX_PHYS_ID' ),
|
||||
speed = at.int_attr( 'SERMUX_PHYS_SPEED' ),
|
||||
flow = at.flow_control_attr( 'SERMUX_FLOW_TYPE' ),
|
||||
buf_sizes = at.array_of( at.int_log2_attr( 'SERMUX_BUFFER_SIZES' ) )
|
||||
}
|
||||
}
|
||||
-- ADC
|
||||
components.adc = {
|
||||
macro = 'BUILD_ADC',
|
||||
attrs = {
|
||||
buf_size = at.make_optional( at.int_log2_attr( 'ADC_BUF_SIZE' ) ),
|
||||
first_timer = at.make_optional( at.int_attr( 'ADC_TIMER_FIRST_ID' ) ),
|
||||
num_timers = at.make_optional( at.int_attr( 'ADC_NUM_TIMERS' ) )
|
||||
}
|
||||
}
|
||||
-- DNS client
|
||||
components.dns = { macro = 'BUILD_DNS', needs = 'tcpip' }
|
||||
-- DHCP client
|
||||
components.dhcp = { macro = 'BUILD_DHCPC', needs = 'tcpip' }
|
||||
-- ROMFS
|
||||
components.romfs = { macro = 'BUILD_ROMFS' }
|
||||
-- WOFS
|
||||
components.wofs = { macro = "BUILD_WOFS" }
|
||||
-- All done
|
||||
return components
|
||||
end
|
||||
|
304
config/config.lua
Normal file
304
config/config.lua
Normal file
@ -0,0 +1,304 @@
|
||||
-- Generate a C configuration starting from a Lua description file
|
||||
-- for an eLua board
|
||||
|
||||
module( ..., package.seeall )
|
||||
|
||||
package.path = package.path .. ";utils/?.lua;config/?.lua"
|
||||
|
||||
local comps = require "components"
|
||||
local cfgs = require "configurations"
|
||||
local gen = require "generators"
|
||||
local utils = require "utils"
|
||||
local bd = require "build_data"
|
||||
local mgen = require "modules"
|
||||
local cpuct = require "cpuconstants"
|
||||
local sects = require "sections"
|
||||
|
||||
local components, configs
|
||||
local glconf, glen
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Various helpers and internal functions
|
||||
|
||||
-- Generator for section 'components'
|
||||
local function generate_components( data, plconf )
|
||||
local compdata = data.components or {}
|
||||
|
||||
-- Prerequisites: check for keys that might be needed in components, but might not be there
|
||||
-- At the moment, we need to definer either BUILD_CON_GENERIC or BUILD_CON_TCP (but not both)
|
||||
if compdata.sercon and compdata.tcpipcon then
|
||||
return nil, "serial and TCP/IP console can't be enabled at the same time in section 'components'"
|
||||
elseif not compdata.sercon and not compdata.tcpipcon then
|
||||
return nil, "either serial (sercon) or TCP/IP (tcpipcon) console must be enabled in 'components'"
|
||||
end
|
||||
|
||||
-- Configure section first
|
||||
local res, err = sects.configure_section( components, 'components', compdata )
|
||||
if not res then return false, err end
|
||||
-- Let the backend do its validation
|
||||
if plconf.pre_generate_section then
|
||||
res, err = plconf.pre_generate_section( components, 'components', compdata, conf, enabled )
|
||||
if not res then return false, err end
|
||||
end
|
||||
|
||||
-- Generate all data for section 'components'
|
||||
return sects.generate_section( components, 'components', compdata )
|
||||
end
|
||||
|
||||
-- Generator for section 'config'
|
||||
local function generate_config( data, plconf )
|
||||
local confdata = data.config or {}
|
||||
|
||||
-- Configure section first
|
||||
local res, err = sects.configure_section( configs, 'config', confdata )
|
||||
if not res then return false, err end
|
||||
-- Let the backend do its validation
|
||||
if plconf.pre_generate_section then
|
||||
res, err = plconf.pre_generate_section( configs, 'config', confdata, conf, enabled )
|
||||
if not res then return false, err end
|
||||
end
|
||||
|
||||
return sects.generate_section( configs, 'config', confdata )
|
||||
end
|
||||
|
||||
-- Global sanity checks (data is in 'glconf' and 'glen'
|
||||
local function check_components_and_config()
|
||||
-- Check all uart IDs. If VUARTs are specified but sermux is not enabled, return with error
|
||||
if not glen.sermux then
|
||||
for _, attrdata in pairs( glconf ) do
|
||||
local attrval = attrdata.value
|
||||
if attrdata.desc.is_uart and type( attrval ) == "string" and attrval:find( "^vuart" ) then
|
||||
return false, sf( "attribute '%s' of element '%s' in section '%s' reffers to a virtual UART, but the serial multiplexer ('sermux') is not enabled",
|
||||
attrdata.name, attrdata.elname, attrdata.sectname )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check all timer IDs. If virtual timers are specified but vtmr is not enabled, return with error
|
||||
if not glen.vtmr or tostring( glconf.VTMR_NUM_TIMERS.value ) == "0" then
|
||||
for _, attrdata in pairs( glconf ) do
|
||||
local attrval = attrdata.value
|
||||
if attrdata.desc.is_timer and type( attrval ) == "string" and attrval:find( "^vtmr" ) then
|
||||
return false, sf( "attribute '%s' of element '%s' in section '%s' reffers to a virtual timer, but virtual timers ('vtmr') are not enabled",
|
||||
attrdata.name, attrdata.elname, attrdata.sectname )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check sermux/RFS+console proper UART assignment
|
||||
if glen.sermux and glen.sercon and glen.rfs then
|
||||
local rfs_uart_value = tostring( glconf.RFS_UART_ID.value )
|
||||
local con_uart_value = tostring( glconf.CON_UART_ID.value )
|
||||
if rfs_uart_value:find( "^vuart" ) and rfs_uart_value ~= "vuart0" then
|
||||
io.write( utils.col_yellow( "[CONFIG] WARNING: you have enabled the serial multiplexer and RFS over a virtual serial port which is not the first virtual serial port ('vuart0')" ) )
|
||||
print( utils.col_yellow( "In this configuration, the serial multiplexer will not work in 'rfsmux' mode. Check the serial multiplexer section of the eLua manual for more details." ) )
|
||||
elseif rfs_uart_value == "vuart0" and con_uart_value:find( "^vuart" ) and con_uart_value ~= "vuart1" then
|
||||
io.write( utils.col_yellow( "[CONFIG] WARNING: when using both RFS and the serial console with 'sermux', it's best to set the serial console uart ID to the second virtual serial port ('vuart1')" ) )
|
||||
print( utils.col_yellow( "In this configuration, the serial multiplexer will work directly in 'rfsmux' mode with a console. Check the serial multiplexer section of the eLua manual for more details." ) )
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Default table for backend configuration data
|
||||
-- If the platform doesn't have a boardconf.lua, this is what we're going to use
|
||||
local default_platform_conf = {
|
||||
add_platform_components = function() end,
|
||||
add_platform_configs = function() end,
|
||||
get_platform_modules = function() end,
|
||||
pre_generate_section = function() return true end,
|
||||
}
|
||||
|
||||
-- Sanity code
|
||||
-- These are more checks added to the generated header file
|
||||
-- Some of these are the result of pure paranoia. Nevertheless, they seem to work.
|
||||
|
||||
local sanity_code = [[
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Static sanity checks and additional defines
|
||||
|
||||
#if defined( ELUA_BOOT_RPC ) && !defined( BUILD_RPC )
|
||||
#define BUILD_RPC
|
||||
#endif
|
||||
|
||||
#if defined( BUILD_LUA_INT_HANDLERS ) || defined( BUILD_C_INT_HANDLERS )
|
||||
#define BUILD_INT_HANDLERS
|
||||
|
||||
#ifndef INT_TMR_MATCH
|
||||
#define INT_TMR_MATCH ELUA_INT_INVALID_INTERRUPT
|
||||
#endif
|
||||
#endif // #if defined( BUILD_LUA_INT_HANDLERS ) || defined( BUILD_C_INT_HANDLERS )
|
||||
|
||||
#ifndef VTMR_NUM_TIMERS
|
||||
#define VTMR_NUM_TIMERS 0
|
||||
#endif // #ifndef VTMR_NUM_TIMERS
|
||||
|
||||
#ifndef SERMUX_FLOW_TYPE
|
||||
#define SERMUX_FLOW_TYPE PLATFORM_UART_FLOW_NONE
|
||||
#endif
|
||||
|
||||
#ifndef CON_FLOW_TYPE
|
||||
#define CON_FLOW_TYPE PLATFORM_UART_FLOW_NONE
|
||||
#endif
|
||||
|
||||
#ifndef CON_TIMER_ID
|
||||
#define CON_TIMER_ID PLATFORM_TIMER_SYS_ID
|
||||
#endif
|
||||
|
||||
#ifdef ELUA_BOOT_RPC
|
||||
#ifndef RPC_UART_ID
|
||||
#define RPC_UART_ID CON_UART_ID
|
||||
#endif
|
||||
|
||||
#ifndef RPC_TIMER_ID
|
||||
#define RPC_TIMER_ID PLATFORM_TIMER_SYS_ID
|
||||
#endif
|
||||
|
||||
#ifndef RPC_UART_SPEED
|
||||
#define RPC_UART_SPEED CON_UART_SPEED
|
||||
#endif
|
||||
#endif // #ifdef ELUA_BOOT_RPC
|
||||
|
||||
#if ( defined( BUILD_RFS ) || defined( BUILD_SERMUX ) || defined( CON_BUF_SIZE ) ) && !defined( BUF_ENABLE_UART )
|
||||
#define BUF_ENABLE_UART
|
||||
#endif
|
||||
|
||||
#if defined( ADC_BUF_SIZE ) && !defined( BUF_ENABLE_ADC )
|
||||
#define BUF_ENABLE_ADC
|
||||
#endif
|
||||
|
||||
#ifndef CPU_FREQUENCY
|
||||
#define CPU_FREQUENCY 0
|
||||
#endif
|
||||
|
||||
]]
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Public interface
|
||||
|
||||
-- This code is executed an initialization time (the first 'require')
|
||||
components = comps.init()
|
||||
configs = cfgs.init()
|
||||
|
||||
-- Read the Lua description file of a board and return the corresponding header file
|
||||
-- as a string or (false, error) if an error occured
|
||||
function compile_board( fname, boardname )
|
||||
local cboardname = boardname:upper():gsub( "[%-%.%s]", "_" )
|
||||
local header = sf([[
|
||||
// Lua board configuration file, automatically generated
|
||||
|
||||
#ifndef __GENERATED_%s_H__
|
||||
#define __GENERATED_%s_H__
|
||||
|
||||
]], cboardname, cboardname )
|
||||
local desc, err = dofile( fname )
|
||||
if not desc then return false, err end
|
||||
if not desc.cpu then return false, "cpu not specified in board configuration file" end
|
||||
|
||||
-- Check the keys in 'desc'
|
||||
local known_keys = { 'cpu', 'components', 'config', 'headers', 'macros', 'modules', 'cpu_constants', 'allocator', 'target' }
|
||||
for k, _ in pairs( desc ) do
|
||||
if not utils.array_element_index( known_keys, k ) then return false, sf( "unknown key '%s'", k ) end
|
||||
end
|
||||
|
||||
-- Check CPU
|
||||
local cpulist = bd.get_all_cpus()
|
||||
if not utils.array_element_index( cpulist, desc.cpu:upper() ) then
|
||||
return false, sf( "unknown cpu '%s'", desc.cpu )
|
||||
end
|
||||
|
||||
-- Find and require the platform board configuration file
|
||||
local platform = bd.get_platform_of_cpu( desc.cpu )
|
||||
if not platform then return false, sf( "unable to find the platform of cpu '%s'", desc.cpu ) end
|
||||
local plconf = default_platform_conf
|
||||
if utils.is_file( utils.concat_path{ 'src', 'platform', platform, 'build_config.lua' } ) then
|
||||
plconf = require( "src.platform." .. platform .. ".build_config" )
|
||||
print( utils.col_blue( sf( "[CONFIG] Found a backend build configuration file for platform %s", platform ) ) )
|
||||
end
|
||||
|
||||
-- Read platform specific components/configs
|
||||
plconf.add_platform_components( components )
|
||||
plconf.add_platform_configs( configs )
|
||||
|
||||
-- Do we need to include any configured headers?
|
||||
if type( desc.headers ) == "table" and #desc.headers > 0 then
|
||||
for _, h in pairs( desc.headers ) do
|
||||
header = header .. "#include " .. h .. "\n"
|
||||
end
|
||||
header = header .. "\n"
|
||||
end
|
||||
|
||||
-- Do we need to add definitions for any configured macros?
|
||||
if type( desc.macros ) == "table" and #desc.macros > 0 then
|
||||
for _, m in pairs( desc.macros ) do
|
||||
if type( m ) == "string" then -- #define m
|
||||
header = header .. gen.print_define( m )
|
||||
elseif type( m ) == "table" then -- { macro, value } -> #define macro value
|
||||
header = header .. gen.print_define( m[ 1 ], m[ 2 ] )
|
||||
end
|
||||
end
|
||||
header = header .. "\n"
|
||||
end
|
||||
|
||||
-- Generate components first
|
||||
local gen, err = generate_components( desc, plconf )
|
||||
if not gen then return false, err end
|
||||
header = header .. gen
|
||||
-- Keep generated data for later use
|
||||
glconf, glen = sects.conf, sects.enabled
|
||||
|
||||
-- Then configs
|
||||
gen, err = generate_config( desc, plconf )
|
||||
local multi_alloc = cfgs.needs_multiple_allocator()
|
||||
if not gen then return false, err end
|
||||
header = header .. gen
|
||||
-- Accumulate generated data into 'glconf' and 'glen'
|
||||
utils.concat_tables( glconf, sects.conf )
|
||||
utils.concat_tables( glen, sects.enabled )
|
||||
|
||||
-- Now we have all components and the configuration generated
|
||||
-- It's a good time for some sanity checks
|
||||
gen, err = check_components_and_config()
|
||||
if not gen then return false, err end
|
||||
|
||||
-- Now it's a good time to include the fixed sanity checks
|
||||
header = header .. sanity_code
|
||||
|
||||
-- Generate module configuration
|
||||
gen, err = mgen.gen_module_list( desc, plconf, platform )
|
||||
if not gen then return false, err end
|
||||
header = header .. gen
|
||||
|
||||
-- Generate additional CPU constants
|
||||
gen, err = cpuct.gen_constants( desc )
|
||||
if not gen then return false, err end
|
||||
header = header .. gen
|
||||
|
||||
-- All done, write the header's footer
|
||||
header = header .. sf( "#endif // #ifndef __GENERATED_%s_H__\n", cboardname )
|
||||
|
||||
-- We are done with the header, we still need to check the compile flags
|
||||
local allocator
|
||||
if desc.allocator then
|
||||
local allocs = { 'newlib', 'multiple', 'simple' }
|
||||
if not utils.array_element_index( allocs, desc.allocator ) then
|
||||
return false, sf( "unknown allocator '%s'", desc.allocator )
|
||||
end
|
||||
allocator = desc.allocator
|
||||
end
|
||||
|
||||
local target
|
||||
if desc.target then
|
||||
local targets = { 'lua', 'lualong', 'lualonglong' }
|
||||
if not utils.array_element_index( targets, desc.target ) then
|
||||
return false, sf( "unknown target '%ws'", desc.target )
|
||||
end
|
||||
target = desc.target
|
||||
end
|
||||
|
||||
-- Return the contents of the header, as well as the name of the CPU used by this
|
||||
-- board (this information is needed by the builder) and the build information
|
||||
return { header = header, cpu = desc.cpu, multi_alloc = multi_alloc, allocator = allocator, target = target }
|
||||
end
|
||||
|
166
config/configurations.lua
Normal file
166
config/configurations.lua
Normal file
@ -0,0 +1,166 @@
|
||||
-- eLua configurations description
|
||||
|
||||
module( ..., package.seeall )
|
||||
|
||||
local sf = string.format
|
||||
local at = require "attributes"
|
||||
local gen = require "generators"
|
||||
|
||||
local use_multiple_allocator
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Attribute checkers
|
||||
|
||||
local function mem_checker( eldesc, vals )
|
||||
local startvals = vals.MEM_START_ADDRESS and vals.MEM_START_ADDRESS.value
|
||||
local sizevals = vals.MEM_END_ADDRESS and vals.MEM_END_ADDRESS.value
|
||||
if not startvals and not sizevals then return true end
|
||||
if not startvals then
|
||||
return false, "attribute 'start' must also be specified for element 'extmem' of section 'config'"
|
||||
elseif not sizevals then
|
||||
return false, "attribute 'size' must also be specified for element 'extmem' of section 'config'"
|
||||
end
|
||||
if #startvals == 0 then
|
||||
return false, "attribute 'start' of element 'extmem' in section 'config' must have at least one element"
|
||||
elseif #sizevals == 0 then
|
||||
return false, "attribute 'size' of element 'extmem' in section 'config' must have at least one element"
|
||||
end
|
||||
if #startvals ~= #sizevals then
|
||||
return false, "attributes 'start' and 'size' of element 'extmem' in section 'config' must have the same number of elements'"
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local egc_mode_map =
|
||||
{
|
||||
disabled = "EGC_NOT_ACTIVE",
|
||||
alloc = "EGC_ON_ALLOC_FAILURE",
|
||||
limit = "EGC_ON_MEM_LIMIT",
|
||||
always = "EGC_ALWAYS"
|
||||
}
|
||||
|
||||
local function egc_checker( eldesc, vals )
|
||||
local modev = vals.EGC_INITIAL_MODE.value
|
||||
local limv = vals.EGC_INITIAL_MEMLIMIT and vals.EGC_INITIAL_MEMLIMIT.value
|
||||
local allmodes = {}
|
||||
for w in modev:gmatch( "(%w+)" ) do allmodes[ #allmodes + 1 ] = w:lower() end
|
||||
local has_memlimit
|
||||
for k, v in pairs( allmodes ) do
|
||||
if not egc_mode_map[ v ] then
|
||||
return false, sf( "'%s' is not a valid value for attribute 'mode' of element 'egc' in section 'config'", v )
|
||||
end
|
||||
if v == "limit" then has_memlimit = true end
|
||||
end
|
||||
if has_memlimit and not limv then
|
||||
return false, sf( "you must specify the 'limit' attribute when using 'limit' as a value for attribute 'mode' of element 'egc' in section 'config'" )
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Specific generators
|
||||
|
||||
-- Automatically generates the MEM_START_ADDRESS and MEM_END_ADDRESS macros
|
||||
-- Assumes that definitions for INTERNAL_RAM_FIRST_FREE and INTERNAL_RAM_LAST_FREE
|
||||
-- exist (they should come from <cpu>.h)
|
||||
local function mem_generator( desc, vals, generated )
|
||||
if not vals.MEM_START_ADDRESS and not vals.MEM_END_ADDRESS then
|
||||
-- Generate configuration only for the internal memory
|
||||
local gstr = gen.print_define( "MEM_START_ADDRESS", "{ ( u32 )( INTERNAL_RAM_FIRST_FREE ) }" )
|
||||
gstr = gstr .. gen.print_define( "MEM_END_ADDRESS", "{ ( u32 )( INTERNAL_RAM_LAST_FREE ) }" )
|
||||
generated.MEM_START_ADDRESS = true
|
||||
generated.MEM_END_ADDRESS = true
|
||||
return gstr
|
||||
end
|
||||
local startvals = vals.MEM_START_ADDRESS.value
|
||||
local sizevals = vals.MEM_END_ADDRESS.value
|
||||
table.insert( startvals, 1, "INTERNAL_RAM_FIRST_FREE" )
|
||||
table.insert( sizevals, 1, "INTERNAL_RAM_LAST_FREE" )
|
||||
-- Transform the data in 'sizevals' to 'last address' (the format accepted by eLua)
|
||||
for i = 2, #sizevals do
|
||||
sizevals[ i ] = tonumber( startvals[ i ] ) + tonumber( sizevals[ i ] ) - 1
|
||||
end
|
||||
-- Prefix all the values in the 'start' and 'size' arrays with 'u32'
|
||||
for i = 1, #sizevals do
|
||||
startvals[ i ] = "( u32 )( " .. tostring( startvals[ i ] ) .. ( i > 1 and "u" or "" ) .. " )"
|
||||
sizevals[ i ] = "( u32 )( " .. tostring( sizevals[ i ] ) .. ( i > 1 and "u" or "" ) .. " )"
|
||||
end
|
||||
local gstr = gen.simple_gen( "MEM_START_ADDRESS", vals, generated )
|
||||
gstr = gstr .. gen.simple_gen( "MEM_END_ADDRESS", vals, generated )
|
||||
use_multiple_allocator = #startvals > 1
|
||||
return gstr
|
||||
end
|
||||
|
||||
local function egc_generator( desc, vals, generated )
|
||||
local modev = vals.EGC_INITIAL_MODE.value
|
||||
local limv = vals.EGC_INITIAL_MEMLIMIT and vals.EGC_INITIAL_MEMLIMIT.value
|
||||
local allmodes = {}
|
||||
local has_memlimit, has_always
|
||||
for w in modev:gmatch( "(%w+)" ) do
|
||||
w = w:lower()
|
||||
if w == "limit" then has_memlimit = true end
|
||||
if w == "always" then has_always = true end
|
||||
allmodes[ #allmodes + 1 ] = w:lower()
|
||||
end
|
||||
if has_always then
|
||||
local gstr = gen.print_define( "EGC_INITIAL_MODE", "EGC_ALWAYS" )
|
||||
generated.EGC_INITIAL_MODE = true
|
||||
return gstr
|
||||
end
|
||||
local cmodes = {}
|
||||
for k, v in pairs( allmodes ) do
|
||||
cmodes[ #cmodes + 1 ] = egc_mode_map[ v ]
|
||||
end
|
||||
local gstr = gen.print_define( "EGC_INITIAL_MODE", "( " .. table.concat( cmodes, "|" ) .. " )" )
|
||||
generated.EGC_INITIAL_MODE = true
|
||||
if has_memlimit then gstr = gstr .. gen.simple_gen( "EGC_INITIAL_MEMLIMIT", vals, generated ) end
|
||||
return gstr
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Public interface
|
||||
|
||||
-- Build the configuration data needed by eLua, save it in the "configs" table
|
||||
function init()
|
||||
local configs = {}
|
||||
|
||||
-- Virtual timers
|
||||
configs.vtmr = {
|
||||
attrs = {
|
||||
num = at.int_attr( 'VTMR_NUM_TIMERS', 1 ),
|
||||
freq = at.int_attr( 'VTMR_FREQ_HZ', 1 )
|
||||
},
|
||||
required = { num = 0, freq = 1 }
|
||||
}
|
||||
|
||||
-- EGC
|
||||
configs.egc = {
|
||||
confcheck = egc_checker,
|
||||
gen = egc_generator,
|
||||
attrs = {
|
||||
mode = at.string_attr( 'EGC_INITIAL_MODE' ),
|
||||
limit = at.make_optional( at.int_attr( 'EGC_INITIAL_MEMLIMIT', 1 ) )
|
||||
},
|
||||
}
|
||||
|
||||
-- Memory configuration generator
|
||||
configs.extmem = {
|
||||
gen = mem_generator,
|
||||
confcheck = mem_checker,
|
||||
attrs = {
|
||||
start = at.array_of( at.int_attr( 'MEM_START_ADDRESS' ) ),
|
||||
size = at.array_of( at.int_attr( 'MEM_END_ADDRESS', 1 ) )
|
||||
},
|
||||
required = {}
|
||||
}
|
||||
|
||||
-- All done
|
||||
return configs
|
||||
end
|
||||
|
||||
-- Returns true if a multiple allocator is needed for this configuration,
|
||||
-- false otherwise
|
||||
function needs_multiple_allocator()
|
||||
return use_multiple_allocator
|
||||
end
|
||||
|
50
config/constants.lua
Normal file
50
config/constants.lua
Normal file
@ -0,0 +1,50 @@
|
||||
-- Various constants used by the build descriptor
|
||||
|
||||
module( ..., package.seeall )
|
||||
local sf = string.format
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- UART data
|
||||
|
||||
-- UART flow types
|
||||
uart_flow =
|
||||
{
|
||||
none = 'PLATFORM_UART_FLOW_NONE',
|
||||
rts = 'PLATFORM_UART_FLOW_RTS',
|
||||
cts = 'PLATFORM_UART_FLOW_CTS',
|
||||
rtscts = '( PLATFORM_UART_FLOW_RTS | PLATFORM_UART_FLOW_CTS )'
|
||||
}
|
||||
|
||||
uart_values = {}
|
||||
|
||||
-- Add a sufficient number of virtual and real UARTs
|
||||
for i = 0, 127 do
|
||||
uart_values[ sf( 'vuart%d', i ) ] = sf( '( SERMUX_SERVICE_ID_FIRST + %d )', i )
|
||||
uart_values[ tostring( i ) ] = i
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Timer data
|
||||
|
||||
-- System timer ID
|
||||
timer_values =
|
||||
{
|
||||
systmr = 'PLATFORM_TIMER_SYS_ID'
|
||||
}
|
||||
|
||||
-- Add a sufficient number of virtual timers
|
||||
for i = 0, 127 do
|
||||
timer_values[ sf( 'vtmr%d', i ) ] = sf( '( VTMR_FIRST_ID + %d )', i )
|
||||
timer_values[ tostring( i ) ] = i
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- EGC data
|
||||
|
||||
egc =
|
||||
{
|
||||
alloc_failure = 1,
|
||||
mem_limit = 2,
|
||||
always = 4
|
||||
}
|
||||
|
31
config/cpuconstants.lua
Normal file
31
config/cpuconstants.lua
Normal file
@ -0,0 +1,31 @@
|
||||
-- CPU constants generator
|
||||
|
||||
module( ..., package.seeall )
|
||||
local sf = string.format
|
||||
local gen = require "generators"
|
||||
|
||||
function gen_constants( desc )
|
||||
local ct = desc.cpu_constants
|
||||
if not ct then return '' end
|
||||
local gstr = string.rep( "/", 80 ) .. "\n" .. "// Configured CPU constants\n\n"
|
||||
-- There are two types of macros in cpu_constants: simple (that are already defined somewhere)
|
||||
-- and full ((macro, def) pairs). We need to iterate over the full list first and define those
|
||||
-- macros. After that we generate the whole PLATFORM_CPU_CONSTANTS_CONFIGURED macro
|
||||
for _, m in pairs( ct ) do
|
||||
if type( m ) == "table" then
|
||||
local name, val = m[ 1 ], m[ 2 ]
|
||||
gstr = gstr .. "\n#ifndef " .. name .. "\n"
|
||||
gstr = gstr .. gen.print_define( name, val )
|
||||
gstr = gstr .. "#endif\n\n"
|
||||
end
|
||||
end
|
||||
|
||||
gstr = gstr .. "#define PLATFORM_CPU_CONSTANTS_CONFIGURED\\\n"
|
||||
for _, m in pairs( ct ) do
|
||||
gstr = gstr .. sf( " _C( %s ),\\\n", type( m ) == "string" and m or m[ 1 ] )
|
||||
end
|
||||
|
||||
gstr = gstr .. "\n"
|
||||
return gstr:gsub( "\n\n\n", "\n\n" )
|
||||
end
|
||||
|
40
config/generators.lua
Normal file
40
config/generators.lua
Normal file
@ -0,0 +1,40 @@
|
||||
-- Code generators for various attributes and other constructs
|
||||
|
||||
module( ..., package.seeall )
|
||||
local sf = string.format
|
||||
|
||||
local MACRO_DEF_POS = 41
|
||||
|
||||
-- Formatted print for "#define"
|
||||
function print_define( k, v )
|
||||
local s = sf( "#define %s", k )
|
||||
if v then
|
||||
if #s < MACRO_DEF_POS then s = s .. string.rep( ' ', MACRO_DEF_POS - #s ) end
|
||||
else
|
||||
v = ''
|
||||
end
|
||||
s = s .. tostring( v ) .. "\n"
|
||||
return s
|
||||
end
|
||||
|
||||
-- Simple generator for an attribute
|
||||
function simple_gen( attrname, conf, gentable )
|
||||
if gentable[ attrname ] then return '' end
|
||||
if not conf[ attrname ] then return '' end
|
||||
local adesc, aval = conf[ attrname ].desc, conf[ attrname ].value
|
||||
gentable[ attrname ] = true
|
||||
if adesc.is_ip then -- special generation for this one
|
||||
local s = ''
|
||||
for i = 1, 4 do
|
||||
s = s .. print_define( sf( "%s%d", attrname, i - 1 ), aval[ i ] )
|
||||
end
|
||||
return s
|
||||
end
|
||||
if adesc.mapping then aval = adesc.mapping[ aval ] end
|
||||
if adesc.is_array then
|
||||
-- The element is an array. The default is to define its value as { elements }
|
||||
aval = "{ " .. table.concat( aval, "," ) .. " }"
|
||||
end
|
||||
return print_define( attrname, tostring( aval ) )
|
||||
end
|
||||
|
194
config/modules.lua
Normal file
194
config/modules.lua
Normal file
@ -0,0 +1,194 @@
|
||||
-- Build configuration: module selection
|
||||
|
||||
module( ..., package.seeall )
|
||||
local sf = string.format
|
||||
local gen = require "generators"
|
||||
|
||||
-- List of all generic modules and their build guards
|
||||
-- (if the module guard evaluates to false at compile time, the module is not included in the build)
|
||||
local generic_modules = {
|
||||
adc = { "BUILD_ADC", "NUM_ADC > 0" },
|
||||
bit = {},
|
||||
can = { "NUM_CAN > 0"},
|
||||
cpu = {},
|
||||
elua = {},
|
||||
i2c = { "NUM_I2C > 0" },
|
||||
pack = {},
|
||||
rpc = { "BUILD_RPC" },
|
||||
net = { "BUILD_UIP" },
|
||||
pd = {},
|
||||
pio = { "NUM_PIO > 0" },
|
||||
pwm = { "NUM_PWM > 0" },
|
||||
spi = { "NUM_SPI > 0" },
|
||||
term = { "BUILD_TERM" },
|
||||
tmr = { "NUM_TIMER > 0" },
|
||||
uart = { "NUM_UART > 0" },
|
||||
math = {}
|
||||
}
|
||||
|
||||
-- Auxlib names
|
||||
local auxlibs = { math = "LUA_MATHLIBNAME" }
|
||||
|
||||
-- Open function names
|
||||
local opennames = {}
|
||||
|
||||
-- Map array names
|
||||
local mapnames = {}
|
||||
|
||||
-- Return the auxlib name of a given module
|
||||
local function get_auxlib( m )
|
||||
return auxlibs[ m ] or sf( "AUXLIB_%s", m:upper() )
|
||||
end
|
||||
|
||||
-- Return the open function name of a given module
|
||||
local function get_openf_name( m )
|
||||
return opennames[ m ] or sf( "luaopen_%s", m:lower() )
|
||||
end
|
||||
|
||||
-- Return the map array name of a given module
|
||||
local function get_map_name( m )
|
||||
return mapnames[ m ] or sf( "%s_map", m:lower() )
|
||||
end
|
||||
|
||||
-- Generate a condition string starting from a guard
|
||||
local function gen_cond_string( g )
|
||||
local condition = ''
|
||||
for idx, e in pairs( g ) do
|
||||
local suffix = idx == #g and "" or " && "
|
||||
if e:find( '%s' ) then -- if it has a string, add the condition as it was given, between parantheses
|
||||
condition = condition .. "( " .. e .. " )"
|
||||
else
|
||||
condition = condition .. "defined( " .. e .. " )"
|
||||
end
|
||||
condition = condition .. suffix
|
||||
end
|
||||
return condition
|
||||
end
|
||||
|
||||
-- Generate the complete module list starting from the board description
|
||||
function gen_module_list( desc, plconf, platform )
|
||||
local mdesc = desc.modules
|
||||
if not mdesc then return '' end
|
||||
local gen_list_generic, gen_list_platform = {}, {}
|
||||
local platform_modules = plconf.get_platform_modules() or {}
|
||||
local gstr = string.rep( "/", 80 ) .. "\n" .. "// Module configuration\n\n"
|
||||
local ngenmods, nplmods = 0, 0
|
||||
|
||||
if mdesc == "all" then -- include all the modules. what a brave, brave soul.
|
||||
for m, _ in pairs( generic_modules ) do
|
||||
gen_list_generic[ m ] = true
|
||||
ngenmods = ngenmods + 1
|
||||
end
|
||||
for m, _ in pairs( platform_modules ) do
|
||||
gen_list_platform[ m ] = true
|
||||
nplmods = nplmods + 1
|
||||
end
|
||||
else
|
||||
-- Include only some modules. Validate their names against the corresponding module list
|
||||
if mdesc.generic == "all" then -- all generic modules
|
||||
for m, _ in pairs( generic_modules ) do
|
||||
gen_list_generic[ m ] = true
|
||||
ngenmods = ngenmods + 1
|
||||
end
|
||||
elseif mdesc.generic then
|
||||
for _, m in pairs( mdesc.generic ) do
|
||||
if not generic_modules[ m ] then return false, sf( "unknown generic module '%s' in section 'modules'", m ) end
|
||||
gen_list_generic[ m ] = true
|
||||
ngenmods = ngenmods + 1
|
||||
end
|
||||
end
|
||||
if mdesc.platform == "all" then -- all platform modules
|
||||
for m, _ in pairs( platform_modules ) do
|
||||
gen_list_platform[ m ] = true
|
||||
nplmods = nplmods + 1
|
||||
end
|
||||
elseif mdesc.platform then
|
||||
for _, m in pairs( mdesc.platform ) do
|
||||
if not platform_modules[ m ] then return false, sf( "unknown platform module '%s' in section 'modules'", m ) end
|
||||
gen_list_platform[ m ] = true
|
||||
nplmods = nplmods + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Need to exclude anything?
|
||||
if type( mdesc.exclude_generic ) == "table" then
|
||||
for _, m in pairs( mdesc.exclude_generic ) do
|
||||
if not gen_list_generic[ m ] then
|
||||
return false, sf( "module '%s' in exclude_generic not found in the generic module list", m )
|
||||
end
|
||||
gen_list_generic[ m ] = nil
|
||||
ngenmods = ngenmods - 1
|
||||
end
|
||||
end
|
||||
if type( mdesc.exclude_platform ) == "table" then
|
||||
for _, m in pairs( mdesc.exclude_platform ) do
|
||||
if not gen_list_platform[ m ] then
|
||||
return false, sf( "module '%s' in exclude_platform not found in the platform specific module list", m )
|
||||
end
|
||||
gen_list_platform[ m ] = nil
|
||||
nplmods = nplmods - 1
|
||||
end
|
||||
end
|
||||
if ngenmods + nplmods == 0 then return '' end
|
||||
|
||||
-- Now build all the module lines, starting from the gen_list and the guards
|
||||
-- First define the platform specific line if needed
|
||||
if nplmods > 0 then
|
||||
-- The (hopefully) proper way to generate this is a bit tricky. We enable the
|
||||
-- platform module if _any_ of the modules in gen_list_platform can be enabled.
|
||||
-- In order to do this, we gather their guards in a single, long condition
|
||||
-- Count all guards first
|
||||
local nguards = 0
|
||||
for m, _ in pairs( gen_list_platform ) do nguards = nguards + #platform_modules[ m ] end
|
||||
if nguards == 0 then -- nothing to guard
|
||||
gstr = gstr .. gen.print_define( "PLATFORM_MODULES_LINE", sf( '_ROM( "%s", luaopen_platform, platform_map )', platform ) )
|
||||
gstr = gstr .. gen.print_define( "PS_LIB_TABLE_NAME", sf( '"%s"', platform ) )
|
||||
gstr = gstr .. gen.print_define( "PLATFORM_MODULES_ENABLE" )
|
||||
else
|
||||
-- Gather the composed condition in 'cond'
|
||||
local cond = '\n#if 0' -- the '0' is included here for an easier generation of the composed condition
|
||||
for m, _ in pairs( gen_list_platform ) do
|
||||
local g = platform_modules[ m ]
|
||||
if #g > 0 then
|
||||
cond = cond .. " || ( " .. gen_cond_string( g ) .. " )"
|
||||
end
|
||||
end
|
||||
gstr = gstr .. cond .. "\n"
|
||||
gstr = gstr .. gen.print_define( "PLATFORM_MODULES_LINE", sf( '_ROM( "%s", luaopen_platform, platform_map )', platform ) )
|
||||
gstr = gstr .. gen.print_define( "PS_LIB_TABLE_NAME", sf( '"%s"', platform ) )
|
||||
gstr = gstr .. gen.print_define( "PLATFORM_MODULES_ENABLE" )
|
||||
gstr = gstr .. "#else\n"
|
||||
gstr = gstr .. gen.print_define( sf( "PLATFORM_MODULES_LINE" ) )
|
||||
gstr = gstr .. sf( "#warning Unable to include platform modules in the image\n#endif\n\n" )
|
||||
end
|
||||
else -- no platform modules here, people. move along.
|
||||
gstr = gstr .. gen.print_define( "PLATFORM_MODULES_LINE" )
|
||||
end
|
||||
for m, _ in pairs( gen_list_generic ) do
|
||||
local g = generic_modules[ m ]
|
||||
if #g == 0 then -- no guards
|
||||
gstr = gstr .. gen.print_define( sf( "MODULE_%s_LINE", m:upper() ), sf( "_ROM( %s, %s, %s )", get_auxlib( m ), get_openf_name( m ), get_map_name( m ) ) )
|
||||
else
|
||||
-- Check the guard. If the guard is not satisfied, issue a compile time warning and set the line as empty
|
||||
gstr = gstr .. "\n#if " .. gen_cond_string( g ) .. "\n"
|
||||
gstr = gstr .. gen.print_define( sf( "MODULE_%s_LINE", m:upper() ), sf( "_ROM( %s, %s, %s )", get_auxlib( m ), get_openf_name( m ), get_map_name( m ) ) )
|
||||
gstr = gstr .. "#else\n"
|
||||
gstr = gstr .. gen.print_define( sf( "MODULE_%s_LINE", m:upper() ) )
|
||||
gstr = gstr .. sf( "#warning Unable to include module '%s' in the image\n#endif\n\n", m )
|
||||
end
|
||||
end
|
||||
gstr = gstr .. "\n"
|
||||
|
||||
-- Finally, generate the acutal list of libraries. Phew.
|
||||
gstr = gstr .. "#define LUA_PLATFORM_LIBS_ROM\\\n PLATFORM_MODULES_LINE"
|
||||
for m, _ in pairs( gen_list_generic ) do
|
||||
gstr = gstr .. sf( "\\\n MODULE_%s_LINE", m:upper() )
|
||||
end
|
||||
gstr = gstr .. "\n"
|
||||
|
||||
-- A bit of cosmetic touch ...
|
||||
gstr = gstr .. "\n"
|
||||
gstr = gstr:gsub( "\n\n\n", "\n\n" )
|
||||
return gstr
|
||||
end
|
||||
|
174
config/sections.lua
Normal file
174
config/sections.lua
Normal file
@ -0,0 +1,174 @@
|
||||
-- Sections (collection of elements) management
|
||||
|
||||
module( ..., package.seeall )
|
||||
local sf = string.format
|
||||
local gen = require "generators"
|
||||
local utils = require "utils"
|
||||
|
||||
conf, enabled, required = {}, {}, {}
|
||||
|
||||
-- Enables and configures an element (a collection of attributes)
|
||||
-- section - the section of the element
|
||||
-- sectname - the name of the section that contains the element (components, config ...)
|
||||
-- name - name of the element
|
||||
-- data - values of attributes in the element
|
||||
-- req: required mode. true if this element's value are forced to its required values, false otherwise
|
||||
-- Returns true if OK, (false, err) for error
|
||||
function config_element( section, sectname, name, data, req )
|
||||
local desc = section[ name ]
|
||||
local attrs = desc.attrs or {}
|
||||
|
||||
-- Process each element in 'data' in turn
|
||||
for attr, v in pairs( data ) do
|
||||
local attrmeta = attrs[ attr ]
|
||||
if not attrmeta then return false, sf( "attribute '%s' is not defined for element '%s' in section '%s'", attr, name, sectname ) end
|
||||
if attrmeta.validator and not req then
|
||||
local res, err = attrmeta:validator( attr, v, name, sectname )
|
||||
if not res then
|
||||
return false, err
|
||||
else
|
||||
-- The validator can also change the attribute's value
|
||||
v = res
|
||||
end
|
||||
end
|
||||
if conf[ attrmeta.macro ] and tostring( conf[ attrmeta.macro ].value ) ~= tostring( v ) and not conf[ attrmeta.macro ].from_default then
|
||||
print( utils.col_yellow( sf( "[CONFIG] WARNING: overriding value of attribute '%s' in element '%s' from '%s' to '%s' in section '%s'",
|
||||
attr, name, conf[ attrmeta.macro ].value, v, sectname ) ) )
|
||||
end
|
||||
conf[ attrmeta.macro ] = { name = attr, desc = attrmeta, value = v, sectname = sectname, elname = name, from_default = false }
|
||||
end
|
||||
-- Set default values where needed
|
||||
for name, data in pairs( attrs ) do
|
||||
if not conf[ data.macro ] and data.default then
|
||||
conf[ data.macro ] = { name = name, desc = data, value = data.default, sectname = sectname, elname = name, from_default = true }
|
||||
end
|
||||
end
|
||||
-- Mark this component as configured
|
||||
enabled[ name ] = true
|
||||
if req then required[ name ] = true end
|
||||
return true
|
||||
end
|
||||
|
||||
-- Configures the given section
|
||||
-- section: the section that will be compiled
|
||||
-- sectname: the name of the section
|
||||
-- data: the data corresponding to the section
|
||||
-- Returns true if OK, (false, errmsg) for error
|
||||
function configure_section( section, sectname, data )
|
||||
conf, enabled, required = {}, {}, {}
|
||||
|
||||
-- Configure each element in turn, doing validation if required
|
||||
for elname, elval in pairs( data ) do
|
||||
if not section[ elname ] then return nil, sf( "unknown element '%s' in section '%s'", elname, sectname ) end
|
||||
-- Handle the special situation <elname> = true (or anything else that is not false)
|
||||
if type( elval ) ~= "table" and elval then
|
||||
data[ elname ] = {}
|
||||
elval = data[ elname ]
|
||||
end
|
||||
if elval then
|
||||
local cres, cerr = config_element( section, sectname, elname, elval )
|
||||
if not cres then return false, cerr end
|
||||
end
|
||||
end
|
||||
|
||||
-- We also need to generated required elements. A required element is an element that
|
||||
-- is generated every time, even if it was not specified in the configuration file.
|
||||
for elname, eldesc in pairs( section ) do
|
||||
if eldesc.required and not enabled[ elname ] then
|
||||
config_element( section, sectname, elname, eldesc.required, true )
|
||||
end
|
||||
end
|
||||
|
||||
-- Step 2: basic consistency check
|
||||
-- For each element, we check that all its required attributes (the ones that don't have
|
||||
-- an 'optional' key set to true) have a value. An element can overwrite this default
|
||||
-- verification by specifying its own 'confcheck' function. There is another function called
|
||||
-- 'auxcheck' that is called AFTER the basic consistency check (if it exists)
|
||||
for elname, _ in pairs( enabled ) do
|
||||
if not required[ elname ] then
|
||||
local desc = section[ elname ]
|
||||
local attrs = desc.attrs or {}
|
||||
if desc.confcheck then
|
||||
local d, err = desc:confcheck( conf, enabled )
|
||||
if not d then return false, err end
|
||||
else
|
||||
for attr, adesc in pairs( attrs ) do
|
||||
if not conf[ adesc.macro ] and not adesc.optional then
|
||||
return false, sf( "required attribute '%s' of component '%s' in section '%s' not specified", attr, elname, sectname )
|
||||
end
|
||||
end
|
||||
if desc.auxcheck then
|
||||
local d, err = desc:auxcheck( conf, enabled )
|
||||
if not d then return false, err end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- Generate configuration data for the given section (must be called after configure_section!)
|
||||
-- section: the section that will be compiled
|
||||
-- sectname: the name of the section
|
||||
-- data: the data corresponding to the section
|
||||
-- Returns the generated header if OK, (false, errmsg) for error
|
||||
function generate_section( section, sectname, data )
|
||||
-- Actual generation of code
|
||||
-- The default generator simply adds '#define KEY VALUE' pairs. An element can overwrite this
|
||||
-- default generation by specifying its own 'gen' function. If the element has an 'auxgen'
|
||||
-- function, it will be called after the default attribute generation
|
||||
-- Also, we never generate the same key twice. We ensure this by keeping a table of the
|
||||
-- keys that were already generated
|
||||
local generated = {}
|
||||
local genstr = string.rep( "/", 80 ) .. "\n" .. sf( "// Configuration for section '%s'\n\n", sectname )
|
||||
for elname, _ in pairs( enabled ) do
|
||||
local desc = section[ elname ]
|
||||
local attrs = desc.attrs or {}
|
||||
genstr = genstr .. sf( "// Configuration for element '%s'\n", elname )
|
||||
if desc.gen then
|
||||
genstr = genstr .. desc:gen( conf, generated )
|
||||
else
|
||||
for aname, adesc in pairs( attrs ) do
|
||||
genstr = genstr .. gen.simple_gen( adesc.macro, conf, generated )
|
||||
end
|
||||
if desc.auxgen then genstr = genstr .. desc:auxgen( conf, generated ) end
|
||||
end
|
||||
-- Add the "build enable" macro
|
||||
if desc.macro then
|
||||
genstr = genstr .. gen.print_define( desc.macro ) .. "\n"
|
||||
else
|
||||
genstr = genstr .. "\n"
|
||||
end
|
||||
end
|
||||
|
||||
-- Finally, check for dependencies
|
||||
-- For each attribute that has a 'needs' element, check if the dependency is met
|
||||
-- The attribute can also define the 'depcheck' function for a default dependency check
|
||||
for elname, _ in pairs( enabled ) do
|
||||
local desc = section[ elname ]
|
||||
if desc.depcheck then
|
||||
local res, err = desc:depcheck( conf, generated )
|
||||
if not res then return false, err end
|
||||
elseif desc.needs then
|
||||
local needs = type( desc.needs ) == "table" and desc.needs or { desc.needs }
|
||||
for _, v in pairs( needs ) do
|
||||
-- Look for negative expressions (not enabled)
|
||||
local neg
|
||||
if v:sub( 1, 1 ) == "!" then
|
||||
neg = true
|
||||
v = v:sub( 2 )
|
||||
end
|
||||
if not neg and not enabled[ v ] then
|
||||
return false, sf( "element '%s' in section '%s' needs element '%s' to be enabled", elname, sectname, v )
|
||||
elseif neg and enabled[ v ] then
|
||||
return false, sf( "element '%s' in section '%s' needs element '%s' to be disabled", elname, sectname, v )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- All done
|
||||
return genstr
|
||||
end
|
||||
|
@ -1,6 +1,9 @@
|
||||
package.path = package.path .. ";../utils/?.lua;"
|
||||
|
||||
require "lfs"
|
||||
require "eluadoc"
|
||||
require "md5"
|
||||
local utils = require "utils"
|
||||
|
||||
-- Uncomment this when generating offline docs
|
||||
local is_offline = true
|
||||
@ -150,21 +153,6 @@ local function copy_dir_rec( src, dst )
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove a directory recusively
|
||||
-- USE WITH CARE!! Doesn't do much checks :)
|
||||
local function rm_dir_rec( dirname )
|
||||
for f in lfs.dir( dirname ) do
|
||||
local ename = string.format( "%s/%s", dirname, f )
|
||||
local attrs = lfs.attributes( ename )
|
||||
if attrs.mode == 'directory' and f ~= '.' and f ~= '..' then
|
||||
rm_dir_rec( ename )
|
||||
elseif attrs.mode == 'file' or attrs.mode == 'named pipe' or attrs.mode == 'link' then
|
||||
os.remove( ename )
|
||||
end
|
||||
end
|
||||
lfs.rmdir( dirname )
|
||||
end
|
||||
|
||||
-- Copy a directory to another directory
|
||||
local function copy_dir( src, dst )
|
||||
local newdir = string.format( "%s/%s", dst, src )
|
||||
@ -678,7 +666,7 @@ else
|
||||
print( string.format( "%s is not a directory", destdir ) )
|
||||
return
|
||||
end
|
||||
rm_dir_rec( destdir )
|
||||
utils.rm_dir_rec( destdir )
|
||||
lfs.mkdir( destdir )
|
||||
end
|
||||
|
||||
@ -690,7 +678,7 @@ if cleancache then
|
||||
print( "'cache' is not a directory" )
|
||||
return
|
||||
end
|
||||
rm_dir_rec( 'cache' )
|
||||
utils.rm_dir_rec( 'cache' )
|
||||
lfs.mkdir( 'cache' )
|
||||
end
|
||||
end
|
||||
|
19
inc/platform_conf.h
Normal file
19
inc/platform_conf.h
Normal file
@ -0,0 +1,19 @@
|
||||
// Generic platform configuration file
|
||||
|
||||
#ifndef __PLATFORM_CONF_H__
|
||||
#define __PLATFORM_CONF_H__
|
||||
|
||||
#include "buf.h"
|
||||
#include "sermux.h"
|
||||
#include "legc.h"
|
||||
#include "platform.h"
|
||||
#include "auxmods.h"
|
||||
#include "elua_int.h"
|
||||
#include "lualib.h"
|
||||
|
||||
#include ELUA_CPU_HEADER
|
||||
#include ELUA_BOARD_HEADER
|
||||
#include "platform_generic.h" // generic platform header (include whatever else is missing here)
|
||||
|
||||
#endif
|
||||
|
@ -4,7 +4,7 @@
|
||||
stty -echo raw -igncr
|
||||
|
||||
# Run simulator
|
||||
./elua_lua$1_linux.elf
|
||||
./elua_lua$1_sim.elf
|
||||
|
||||
# Restore terminal to default settings
|
||||
stty echo cooked
|
||||
|
45
src/common.c
45
src/common.c
@ -20,43 +20,14 @@
|
||||
#include "lapi.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
// [TODO] the new builder should automatically do this
|
||||
#if defined( BUILD_LUA_INT_HANDLERS ) || defined( BUILD_C_INT_HANDLERS )
|
||||
#define BUILD_INT_HANDLERS
|
||||
|
||||
#ifndef INT_TMR_MATCH
|
||||
#define INT_TMR_MATCH ELUA_INT_INVALID_INTERRUPT
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_INT_HANDLERS
|
||||
extern const elua_int_descriptor elua_int_table[ INT_ELUA_LAST ];
|
||||
#endif // #ifdef BUILD_INT_HANDLERS
|
||||
|
||||
#endif // #if defined( BUILD_LUA_INT_HANDLERS ) || defined( BUILD_C_INT_HANDLERS )
|
||||
|
||||
// [TODO] the new builder should automatically do this
|
||||
#ifndef VTMR_NUM_TIMERS
|
||||
#define VTMR_NUM_TIMERS 0
|
||||
#endif // #ifndef VTMR_NUM_TIMERS
|
||||
|
||||
// [TODO] the new builder should automatically do this
|
||||
#ifndef CON_BUF_SIZE
|
||||
#define CON_BUF_SIZE 0
|
||||
#endif // #ifndef CON_BUF_SIZE
|
||||
|
||||
// [TODO] the new builder should automatically do this
|
||||
#ifndef SERMUX_FLOW_TYPE
|
||||
#define SERMUX_FLOW_TYPE PLATFORM_UART_FLOW_NONE
|
||||
#endif
|
||||
|
||||
// [TODO] the new builder should automatically do this
|
||||
#ifndef CON_FLOW_TYPE
|
||||
#define CON_FLOW_TYPE PLATFORM_UART_FLOW_NONE
|
||||
#endif
|
||||
|
||||
// [TODO] the new builder should automatically do this
|
||||
#ifndef CON_TIMER_ID
|
||||
#define CON_TIMER_ID PLATFORM_TIMER_SYS_ID
|
||||
#endif
|
||||
|
||||
// ****************************************************************************
|
||||
// XMODEM support code
|
||||
|
||||
@ -350,12 +321,12 @@ extern char end[];
|
||||
|
||||
void* platform_get_first_free_ram( unsigned id )
|
||||
{
|
||||
void* mstart[] = MEM_START_ADDRESS;
|
||||
u32 mstart[] = MEM_START_ADDRESS;
|
||||
u32 p;
|
||||
|
||||
if( id >= sizeof( mstart ) / sizeof( void* ) )
|
||||
if( id >= sizeof( mstart ) / sizeof( u32 ) )
|
||||
return NULL;
|
||||
p = ( u32 )mstart[ id ];
|
||||
p = mstart[ id ];
|
||||
if( p & ( MIN_ALIGN - 1 ) )
|
||||
p = ( ( p >> MIN_ALIGN_SHIFT ) + 1 ) << MIN_ALIGN_SHIFT;
|
||||
return ( void* )p;
|
||||
@ -363,12 +334,12 @@ void* platform_get_first_free_ram( unsigned id )
|
||||
|
||||
void* platform_get_last_free_ram( unsigned id )
|
||||
{
|
||||
void* mend[] = MEM_END_ADDRESS;
|
||||
u32 mend[] = MEM_END_ADDRESS;
|
||||
u32 p;
|
||||
|
||||
if( id >= sizeof( mend ) / sizeof( void* ) )
|
||||
if( id >= sizeof( mend ) / sizeof( u32 ) )
|
||||
return NULL;
|
||||
p = ( u32 )mend[ id ];
|
||||
p = mend[ id ];
|
||||
if( p & ( MIN_ALIGN - 1 ) )
|
||||
p = ( ( p >> MIN_ALIGN_SHIFT ) - 1 ) << MIN_ALIGN_SHIFT;
|
||||
return ( void* )p;
|
||||
|
16
src/main.c
16
src/main.c
@ -40,21 +40,7 @@ char *boot_order[] = {
|
||||
|
||||
extern char etext[];
|
||||
|
||||
|
||||
#ifdef ELUA_BOOT_RPC
|
||||
|
||||
#ifndef RPC_UART_ID
|
||||
#define RPC_UART_ID CON_UART_ID
|
||||
#endif
|
||||
|
||||
#ifndef RPC_TIMER_ID
|
||||
#define RPC_TIMER_ID PLATFORM_TIMER_SYS_ID
|
||||
#endif
|
||||
|
||||
#ifndef RPC_UART_SPEED
|
||||
#define RPC_UART_SPEED CON_UART_SPEED
|
||||
#endif
|
||||
|
||||
void boot_rpc( void )
|
||||
{
|
||||
lua_State *L = lua_open();
|
||||
@ -70,7 +56,7 @@ void boot_rpc( void )
|
||||
lua_pushnumber( L, RPC_TIMER_ID );
|
||||
lua_pcall( L, 2, 0, 0 );
|
||||
}
|
||||
#endif
|
||||
#endif // #ifdef ELUA_BOOT_RPC
|
||||
|
||||
// ****************************************************************************
|
||||
// Program entry point
|
||||
|
@ -11,6 +11,22 @@
|
||||
#define _C( x ) { #x, x }
|
||||
#include "platform_conf.h"
|
||||
|
||||
#if defined( PLATFORM_CPU_CONSTANTS_INTS ) || defined( PLATFORM_CPU_CONSTANTS_PLATFORM ) || defined( PLATFORM_CPU_CONSTANTS_CONFIGURED )
|
||||
#define HAS_CPU_CONSTANTS
|
||||
#endif
|
||||
|
||||
#if defined( HAS_CPU_CONSTANTS ) && !defined( PLATFORM_CPU_CONSTANTS_INTS )
|
||||
#define PLATFORM_CPU_CONSTANTS_INTS
|
||||
#endif
|
||||
|
||||
#if defined( HAS_CPU_CONSTANTS ) && !defined( PLATFORM_CPU_CONSTANTS_PLATFORM )
|
||||
#define PLATFORM_CPU_CONSTANTS_PLATFORM
|
||||
#endif
|
||||
|
||||
#if defined( HAS_CPU_CONSTANTS ) && !defined( PLATFORM_CPU_CONSTANTS_CONFIGURED )
|
||||
#define PLATFORM_CPU_CONSTANTS_CONFIGURED
|
||||
#endif
|
||||
|
||||
// Lua: w32( address, data )
|
||||
static int cpu_w32( lua_State *L )
|
||||
{
|
||||
@ -143,10 +159,12 @@ typedef struct
|
||||
u32 val;
|
||||
} cpu_const_t;
|
||||
|
||||
#ifdef PLATFORM_CPU_CONSTANTS
|
||||
#ifdef HAS_CPU_CONSTANTS
|
||||
static const cpu_const_t cpu_constants[] =
|
||||
{
|
||||
PLATFORM_CPU_CONSTANTS,
|
||||
PLATFORM_CPU_CONSTANTS_INTS
|
||||
PLATFORM_CPU_CONSTANTS_PLATFORM
|
||||
PLATFORM_CPU_CONSTANTS_CONFIGURED
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
@ -166,7 +184,7 @@ static int cpu_mt_index( lua_State *L )
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif // #ifdef HAS_CPU_CONSTANTS
|
||||
|
||||
#ifdef BUILD_LUA_INT_HANDLERS
|
||||
|
||||
@ -258,10 +276,10 @@ const LUA_REG_TYPE cpu_map[] =
|
||||
{ LSTRKEY( "get_int_handler" ), LFUNCVAL( cpu_get_int_handler ) },
|
||||
{ LSTRKEY( "get_int_flag" ), LFUNCVAL( cpu_get_int_flag) },
|
||||
#endif
|
||||
#if defined( PLATFORM_CPU_CONSTANTS ) && LUA_OPTIMIZE_MEMORY > 0
|
||||
#if defined( HAS_CPU_CONSTANTS ) && LUA_OPTIMIZE_MEMORY > 0
|
||||
{ LSTRKEY( "__metatable" ), LROVAL( cpu_map ) },
|
||||
#endif
|
||||
#ifdef PLATFORM_CPU_CONSTANTS
|
||||
#ifdef HAS_CPU_CONSTANTS
|
||||
{ LSTRKEY( "__index" ), LFUNCVAL( cpu_mt_index ) },
|
||||
#endif
|
||||
{ LNILKEY, LNILVAL }
|
||||
@ -281,11 +299,11 @@ LUALIB_API int luaopen_cpu( lua_State *L )
|
||||
// Register methods
|
||||
luaL_register( L, AUXLIB_CPU, cpu_map );
|
||||
|
||||
#ifdef PLATFORM_CPU_CONSTANTS
|
||||
#ifdef HAS_CPU_CONSTANTS
|
||||
// Set table as its own metatable
|
||||
lua_pushvalue( L, -1 );
|
||||
lua_setmetatable( L, -2 );
|
||||
#endif // #ifdef PLATFORM_CPU_CONSTANTS
|
||||
#endif // #ifdef HAS_CPU_CONSTANTS
|
||||
|
||||
return 1;
|
||||
#endif // #if LUA_OPTIMIZE_MEMORY > 0
|
||||
|
47
src/platform/lpc24xx/cpu_lpc2468.h
Normal file
47
src/platform/lpc24xx/cpu_lpc2468.h
Normal file
@ -0,0 +1,47 @@
|
||||
// LPC2468 CPU definitions
|
||||
|
||||
#ifndef __CPU_LPC2468_H__
|
||||
#define __CPU_LPC2468_H__
|
||||
|
||||
#include "stacks.h"
|
||||
#include "target.h"
|
||||
#include "platform_ints.h"
|
||||
|
||||
// Number of resources (0 if not available/not implemented)
|
||||
#define NUM_PIO 5
|
||||
#define NUM_SPI 0
|
||||
#define NUM_UART 4
|
||||
#define NUM_PWM 12
|
||||
#define NUM_ADC 8
|
||||
#define NUM_CAN 0
|
||||
#define NUM_TIMER 4
|
||||
|
||||
// ADC Configuration Params
|
||||
#define ADC_BIT_RESOLUTION 10
|
||||
|
||||
// CPU frequency (needed by the CPU module and MMCFS code, 0 if not used)
|
||||
#define CPU_FREQUENCY Fcclk
|
||||
|
||||
// PIO prefix ('0' for P0, P1, ... or 'A' for PA, PB, ...)
|
||||
#define PIO_PREFIX '0'
|
||||
// Pins per port configuration:
|
||||
// #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
|
||||
// #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
|
||||
// Use #define PIO_PINS_PER_PORT 0 if this isn't needed
|
||||
#define PIO_PINS_PER_PORT 32
|
||||
|
||||
// Internal RAM
|
||||
#define SRAM_ORIGIN 0x40000000
|
||||
#define SRAM_SIZE 0x10000 // [TODO]: make this 96k?
|
||||
#define INTERNAL_RAM_FIRST_FREE end
|
||||
#define INTERNAL_RAM_LAST_FREE ( SRAM_ORIGIN + SRAM_SIZE - STACK_SIZE_TOTAL - 1 )
|
||||
|
||||
// Interrupt list for this CPU
|
||||
#define PLATFORM_CPU_CONSTANTS_INTS\
|
||||
_C( INT_GPIO_POSEDGE ), \
|
||||
_C( INT_GPIO_NEGEDGE ), \
|
||||
_C( INT_TMR_MATCH ), \
|
||||
_C( INT_UART_RX ),
|
||||
|
||||
#endif // #ifndef __CPU_LPC2468_H__
|
||||
|
@ -1,197 +0,0 @@
|
||||
// eLua platform configuration
|
||||
|
||||
#ifndef __PLATFORM_CONF_H__
|
||||
#define __PLATFORM_CONF_H__
|
||||
|
||||
#include "auxmods.h"
|
||||
#include "stacks.h"
|
||||
#include "target.h"
|
||||
#include "buf.h"
|
||||
#include "elua_int.h"
|
||||
#include "sermux.h"
|
||||
|
||||
// *****************************************************************************
|
||||
// Define here what components you want for this platform
|
||||
|
||||
#define BUILD_XMODEM
|
||||
#define BUILD_SHELL
|
||||
#define BUILD_ROMFS
|
||||
#define BUILD_TERM
|
||||
#define BUILD_CON_GENERIC
|
||||
#define BUILD_ADC
|
||||
#define BUILD_RPC
|
||||
//#define BUILD_RFS
|
||||
//#define BUILD_SERMUX
|
||||
#define BUILD_LUA_INT_HANDLERS
|
||||
#define BUILD_C_INT_HANDLERS
|
||||
|
||||
#define PLATFORM_HAS_SYSTIMER
|
||||
|
||||
// *****************************************************************************
|
||||
// UART/Timer IDs configuration data (used in main.c)
|
||||
|
||||
//#define CON_UART_ID ( SERMUX_SERVICE_ID_FIRST + 1 )
|
||||
#define CON_UART_ID 0
|
||||
#define CON_UART_SPEED 115200
|
||||
#define TERM_LINES 25
|
||||
#define TERM_COLS 80
|
||||
|
||||
// *****************************************************************************
|
||||
// Auxiliary libraries that will be compiled for this platform
|
||||
|
||||
#ifdef BUILD_ADC
|
||||
#define ADCLINE _ROM( AUXLIB_ADC, luaopen_adc, adc_map )
|
||||
#else
|
||||
#define ADCLINE
|
||||
#endif
|
||||
|
||||
#if defined( ELUA_BOOT_RPC ) && !defined( BUILD_RPC )
|
||||
#define BUILD_RPC
|
||||
#endif
|
||||
|
||||
#if defined( BUILD_RPC )
|
||||
#define RPCLINE _ROM( AUXLIB_RPC, luaopen_rpc, rpc_map )
|
||||
#else
|
||||
#define RPCLINE
|
||||
#endif
|
||||
|
||||
#define LUA_PLATFORM_LIBS_ROM\
|
||||
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
|
||||
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
|
||||
ADCLINE\
|
||||
_ROM( AUXLIB_UART, luaopen_uart, uart_map )\
|
||||
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
|
||||
_ROM( AUXLIB_PD, luaopen_pd, pd_map )\
|
||||
_ROM( AUXLIB_TERM, luaopen_term, term_map )\
|
||||
_ROM( AUXLIB_PACK, luaopen_pack, pack_map )\
|
||||
_ROM( AUXLIB_BIT, luaopen_bit, bit_map )\
|
||||
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map )\
|
||||
_ROM( AUXLIB_ELUA, luaopen_elua, elua_map )\
|
||||
_ROM( AUXLIB_PWM, luaopen_pwm, pwm_map )\
|
||||
RPCLINE\
|
||||
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )
|
||||
|
||||
// *****************************************************************************
|
||||
// Configuration data
|
||||
|
||||
// Virtual timers (0 if not used)
|
||||
#define VTMR_NUM_TIMERS 4
|
||||
// NOTE: DON'T define VTMR_FREQ_HZ as 0!
|
||||
#define VTMR_FREQ_HZ 4
|
||||
|
||||
// Number of resources (0 if not available/not implemented)
|
||||
#define NUM_PIO 5
|
||||
#define NUM_SPI 0
|
||||
#define NUM_UART 4
|
||||
#define NUM_PWM 12
|
||||
#define NUM_ADC 8
|
||||
#define NUM_CAN 0
|
||||
// If virtual timers are enabled, the last timer will be used only for them
|
||||
#if VTMR_NUM_TIMERS == 0
|
||||
#define NUM_TIMER 4
|
||||
#else
|
||||
#define NUM_TIMER 3
|
||||
#endif
|
||||
|
||||
// Interrupt data
|
||||
#define PLATFORM_INT_QUEUE_LOG_SIZE BUF_SIZE_32
|
||||
// Enable RX buffering on UART
|
||||
#define BUF_ENABLE_UART
|
||||
#define CON_BUF_SIZE BUF_SIZE_128
|
||||
|
||||
// ADC Configuration Params
|
||||
#define ADC_BIT_RESOLUTION 10
|
||||
#define BUF_ENABLE_ADC
|
||||
#define ADC_BUF_SIZE BUF_SIZE_2
|
||||
|
||||
// These should be adjusted to support multiple ADC devices
|
||||
#define ADC_TIMER_FIRST_ID 0
|
||||
#define ADC_NUM_TIMERS 4
|
||||
|
||||
// RPC boot options
|
||||
#define RPC_UART_ID CON_UART_ID
|
||||
#define RPC_UART_SPEED CON_UART_SPEED
|
||||
|
||||
// CPU frequency (needed by the CPU module and MMCFS code, 0 if not used)
|
||||
#define CPU_FREQUENCY Fcclk
|
||||
|
||||
// PIO prefix ('0' for P0, P1, ... or 'A' for PA, PB, ...)
|
||||
#define PIO_PREFIX '0'
|
||||
// Pins per port configuration:
|
||||
// #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
|
||||
// #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
|
||||
// Use #define PIO_PINS_PER_PORT 0 if this isn't needed
|
||||
#define PIO_PINS_PER_PORT 32
|
||||
|
||||
// Remote file system data
|
||||
/*
|
||||
#define RFS_BUFFER_SIZE BUF_SIZE_512
|
||||
#define RFS_UART_ID ( SERMUX_SERVICE_ID_FIRST )
|
||||
#define RFS_TIMEOUT 100000
|
||||
#define RFS_UART_SPEED 115200
|
||||
|
||||
#define SERMUX_PHYS_ID 0
|
||||
#define SERMUX_PHYS_SPEED 115200
|
||||
#define SERMUX_NUM_VUART 2
|
||||
#define SERMUX_BUFFER_SIZES { RFS_BUFFER_SIZE, CON_BUF_SIZE }
|
||||
*/
|
||||
|
||||
// Allocator data: define your free memory zones here in two arrays
|
||||
// (start address and end address)
|
||||
#define SRAM_ORIGIN 0x40000000
|
||||
#define SRAM_SIZE 0x10000 // [TODO]: make this 96k?
|
||||
|
||||
#ifdef ELUA_BOARD_ELUAPUC
|
||||
#define SDRAM_BASE_ADDR2 0xA0000000
|
||||
#define SDRAM_SIZE ( 8 * 1048576 )
|
||||
#define MEM_START_ADDRESS { ( void* )end, ( void* )SDRAM_BASE_ADDR2 }
|
||||
#define MEM_END_ADDRESS { ( void* )( SRAM_ORIGIN + SRAM_SIZE - STACK_SIZE_TOTAL - 1 ), ( void* )( SDRAM_BASE_ADDR2 + SDRAM_SIZE - 1 ) }
|
||||
//#define MEM_START_ADDRESS { ( void* )SDRAM_BASE_ADDR2 }
|
||||
//#define MEM_END_ADDRESS { ( void* )( SDRAM_BASE_ADDR2 + SDRAM_SIZE - 1 ) }
|
||||
#else
|
||||
#define MEM_START_ADDRESS { ( void* )end }
|
||||
#define MEM_END_ADDRESS { ( void* )( SRAM_ORIGIN + SRAM_SIZE - STACK_SIZE_TOTAL - 1 ) }
|
||||
#endif
|
||||
|
||||
// *****************************************************************************
|
||||
// CPU constants that should be exposed to the eLua "cpu" module
|
||||
|
||||
#define PINSEL_BASE_ADDR 0xE002C000
|
||||
#define IO_PINSEL0 ( PINSEL_BASE_ADDR + 0x00 )
|
||||
#define IO_PINSEL1 ( PINSEL_BASE_ADDR + 0x04 )
|
||||
#define IO_PINSEL2 ( PINSEL_BASE_ADDR + 0x08 )
|
||||
#define IO_PINSEL3 ( PINSEL_BASE_ADDR + 0x0C )
|
||||
#define IO_PINSEL4 ( PINSEL_BASE_ADDR + 0x10 )
|
||||
#define IO_PINSEL5 ( PINSEL_BASE_ADDR + 0x14 )
|
||||
#define IO_PINSEL6 ( PINSEL_BASE_ADDR + 0x18 )
|
||||
#define IO_PINSEL7 ( PINSEL_BASE_ADDR + 0x1C )
|
||||
#define IO_PINSEL8 ( PINSEL_BASE_ADDR + 0x20 )
|
||||
#define IO_PINSEL9 ( PINSEL_BASE_ADDR + 0x24 )
|
||||
#define IO_PINSEL10 ( PINSEL_BASE_ADDR + 0x28 )
|
||||
|
||||
// Interrupt list
|
||||
#define INT_GPIO_POSEDGE ELUA_INT_FIRST_ID
|
||||
#define INT_GPIO_NEGEDGE ( ELUA_INT_FIRST_ID + 1 )
|
||||
#define INT_TMR_MATCH ( ELUA_INT_FIRST_ID + 2 )
|
||||
#define INT_UART_RX ( ELUA_INT_FIRST_ID + 3 )
|
||||
#define INT_ELUA_LAST INT_UART_RX
|
||||
|
||||
#define PLATFORM_CPU_CONSTANTS\
|
||||
_C( IO_PINSEL0 ),\
|
||||
_C( IO_PINSEL1 ),\
|
||||
_C( IO_PINSEL2 ),\
|
||||
_C( IO_PINSEL3 ),\
|
||||
_C( IO_PINSEL4 ),\
|
||||
_C( IO_PINSEL5 ),\
|
||||
_C( IO_PINSEL6 ),\
|
||||
_C( IO_PINSEL7 ),\
|
||||
_C( IO_PINSEL8 ),\
|
||||
_C( IO_PINSEL9 ),\
|
||||
_C( IO_PINSEL10 ),\
|
||||
_C( INT_GPIO_POSEDGE ),\
|
||||
_C( INT_GPIO_NEGEDGE ),\
|
||||
_C( INT_TMR_MATCH ),\
|
||||
_C( INT_UART_RX )
|
||||
|
||||
#endif // #ifndef __PLATFORM_CONF_H__
|
||||
|
44
src/platform/lpc24xx/platform_generic.h
Normal file
44
src/platform/lpc24xx/platform_generic.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Platform-wide configuration file, included by platform_conf.h
|
||||
|
||||
#ifndef __PLATFORM_GENERIC_H__
|
||||
#define __PLATFORM_GENERIC_H__
|
||||
|
||||
#define PLATFORM_HAS_SYSTIMER
|
||||
|
||||
// If virtual timers are enabled, the last timer will be used only for them
|
||||
#if VTMR_NUM_TIMERS > 0
|
||||
#undef NUM_TIMER
|
||||
#define NUM_TIMER 3
|
||||
#endif
|
||||
|
||||
// *****************************************************************************
|
||||
// CPU constants that should be exposed to the eLua "cpu" module
|
||||
|
||||
#define PINSEL_BASE_ADDR 0xE002C000
|
||||
#define IO_PINSEL0 ( PINSEL_BASE_ADDR + 0x00 )
|
||||
#define IO_PINSEL1 ( PINSEL_BASE_ADDR + 0x04 )
|
||||
#define IO_PINSEL2 ( PINSEL_BASE_ADDR + 0x08 )
|
||||
#define IO_PINSEL3 ( PINSEL_BASE_ADDR + 0x0C )
|
||||
#define IO_PINSEL4 ( PINSEL_BASE_ADDR + 0x10 )
|
||||
#define IO_PINSEL5 ( PINSEL_BASE_ADDR + 0x14 )
|
||||
#define IO_PINSEL6 ( PINSEL_BASE_ADDR + 0x18 )
|
||||
#define IO_PINSEL7 ( PINSEL_BASE_ADDR + 0x1C )
|
||||
#define IO_PINSEL8 ( PINSEL_BASE_ADDR + 0x20 )
|
||||
#define IO_PINSEL9 ( PINSEL_BASE_ADDR + 0x24 )
|
||||
#define IO_PINSEL10 ( PINSEL_BASE_ADDR + 0x28 )
|
||||
|
||||
#define PLATFORM_CPU_CONSTANTS_PLATFORM\
|
||||
_C( IO_PINSEL0 ),\
|
||||
_C( IO_PINSEL1 ),\
|
||||
_C( IO_PINSEL2 ),\
|
||||
_C( IO_PINSEL3 ),\
|
||||
_C( IO_PINSEL4 ),\
|
||||
_C( IO_PINSEL5 ),\
|
||||
_C( IO_PINSEL6 ),\
|
||||
_C( IO_PINSEL7 ),\
|
||||
_C( IO_PINSEL8 ),\
|
||||
_C( IO_PINSEL9 ),\
|
||||
_C( IO_PINSEL10 ),
|
||||
|
||||
#endif // #ifndef __PLATFORM_GENERIC_H__
|
||||
|
15
src/platform/lpc24xx/platform_ints.h
Normal file
15
src/platform/lpc24xx/platform_ints.h
Normal file
@ -0,0 +1,15 @@
|
||||
// This header lists all interrupts defined for this platform
|
||||
|
||||
#ifndef __PLATFORM_INTS_H__
|
||||
#define __PLATFORM_INTS_H__
|
||||
|
||||
#include "elua_int.h"
|
||||
|
||||
#define INT_GPIO_POSEDGE ELUA_INT_FIRST_ID
|
||||
#define INT_GPIO_NEGEDGE ( ELUA_INT_FIRST_ID + 1 )
|
||||
#define INT_TMR_MATCH ( ELUA_INT_FIRST_ID + 2 )
|
||||
#define INT_UART_RX ( ELUA_INT_FIRST_ID + 3 )
|
||||
#define INT_ELUA_LAST INT_UART_RX
|
||||
|
||||
#endif // #ifndef __PLATFORM_INTS_H__
|
||||
|
32
src/platform/sim/cpu_linux.h
Normal file
32
src/platform/sim/cpu_linux.h
Normal file
@ -0,0 +1,32 @@
|
||||
// Linux "CPU" description for the eLua simulator
|
||||
|
||||
#ifndef __CPU_LINUX_H__
|
||||
#define __CPU_LINUX_H__
|
||||
|
||||
// Number of resources (0 if not available/not implemented)
|
||||
#define NUM_PIO 0
|
||||
#define NUM_SPI 0
|
||||
#define NUM_UART 0
|
||||
#define NUM_TIMER 0
|
||||
#define NUM_PWM 0
|
||||
#define NUM_ADC 0
|
||||
#define NUM_CAN 0
|
||||
|
||||
// PIO prefix ('0' for P0, P1, ... or 'A' for PA, PB, ...)
|
||||
#define PIO_PREFIX 'A'
|
||||
// Pins per port configuration:
|
||||
// #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
|
||||
// #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
|
||||
// Use #define PIO_PINS_PER_PORT 0 if this isn't needed
|
||||
#define PIO_PINS_PER_PORT 0
|
||||
|
||||
// Allocator data: define your free memory zones here in two arrays
|
||||
// (start address and end address)
|
||||
extern void *memory_start_address;
|
||||
extern void *memory_end_address;
|
||||
#define MEM_LENGTH (1024 * 1024)
|
||||
#define INTERNAL_RAM_FIRST_FREE ( void* )memory_start_address
|
||||
#define INTERNAL_RAM_LAST_FREE ( void* )memory_end_address
|
||||
|
||||
#endif
|
||||
|
@ -1,78 +0,0 @@
|
||||
// eLua platform configuration
|
||||
|
||||
#ifndef __PLATFORM_CONF_H__
|
||||
#define __PLATFORM_CONF_H__
|
||||
|
||||
#include "auxmods.h"
|
||||
#include "type.h"
|
||||
#include "stacks.h"
|
||||
#include "buf.h"
|
||||
|
||||
// *****************************************************************************
|
||||
// Define here what components you want for this platform
|
||||
|
||||
#define BUILD_SHELL
|
||||
#define BUILD_ROMFS
|
||||
#define BUILD_CON_GENERIC
|
||||
#define BUILD_TERM
|
||||
//#define BUILD_RFS
|
||||
#define BUILD_WOFS
|
||||
|
||||
#define TERM_LINES 25
|
||||
#define TERM_COLS 80
|
||||
|
||||
#define PLATFORM_HAS_SYSTIMER
|
||||
|
||||
// *****************************************************************************
|
||||
// Auxiliary libraries that will be compiled for this platform
|
||||
|
||||
#define LUA_PLATFORM_LIBS_ROM\
|
||||
_ROM( AUXLIB_PD, luaopen_pd, pd_map )\
|
||||
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )\
|
||||
_ROM( AUXLIB_TERM, luaopen_term, term_map )\
|
||||
_ROM( AUXLIB_ELUA, luaopen_elua, elua_map )\
|
||||
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
|
||||
|
||||
// Bogus defines for common.c
|
||||
#define CON_UART_ID 0
|
||||
#define CON_UART_SPEED 0
|
||||
|
||||
// *****************************************************************************
|
||||
// Configuration data
|
||||
|
||||
// Virtual timers (0 if not used)
|
||||
#define VTMR_NUM_TIMERS 0
|
||||
|
||||
// Number of resources (0 if not available/not implemented)
|
||||
#define NUM_PIO 0
|
||||
#define NUM_SPI 0
|
||||
#define NUM_UART 0
|
||||
#define NUM_TIMER 0
|
||||
#define NUM_PWM 0
|
||||
#define NUM_ADC 0
|
||||
#define NUM_CAN 0
|
||||
|
||||
// CPU frequency (needed by the CPU module and MMCFS code, 0 if not used)
|
||||
#define CPU_FREQUENCY 0
|
||||
|
||||
// PIO prefix ('0' for P0, P1, ... or 'A' for PA, PB, ...)
|
||||
#define PIO_PREFIX 'A'
|
||||
// Pins per port configuration:
|
||||
// #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
|
||||
// #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
|
||||
// Use #define PIO_PINS_PER_PORT 0 if this isn't needed
|
||||
#define PIO_PINS_PER_PORT 0
|
||||
|
||||
// Allocator data: define your free memory zones here in two arrays
|
||||
// (start address and end address)
|
||||
extern void *memory_start_address;
|
||||
extern void *memory_end_address;
|
||||
#define MEM_LENGTH (1024 * 1024)
|
||||
#define MEM_START_ADDRESS { ( void* )memory_start_address }
|
||||
#define MEM_END_ADDRESS { ( void* )memory_end_address }
|
||||
|
||||
// RFS configuration
|
||||
#define RFS_TIMEOUT 0 // dummy, always blocking by implementation
|
||||
#define RFS_BUFFER_SIZE BUF_SIZE_512
|
||||
|
||||
#endif // #ifndef __PLATFORM_CONF_H__
|
9
src/platform/sim/platform_generic.h
Normal file
9
src/platform/sim/platform_generic.h
Normal file
@ -0,0 +1,9 @@
|
||||
// Included by platform_conf.h for platform customizations
|
||||
|
||||
#ifndef __PLATFORM_GENERIC_H__
|
||||
#define __PLATFORM_GENERIC_H__
|
||||
|
||||
#define PLATFORM_HAS_SYSTIMER
|
||||
|
||||
#endif // #ifndef __PLATFORM_GENERIC_H__
|
||||
|
19
src/platform/stm32/build_config.lua
Normal file
19
src/platform/stm32/build_config.lua
Normal file
@ -0,0 +1,19 @@
|
||||
-- This is the platform specific board configuration file
|
||||
-- It is used by the generic board configuration system (config/)
|
||||
|
||||
module( ..., package.seeall )
|
||||
|
||||
-- Add specific components to the 'components' table
|
||||
function add_platform_components( t )
|
||||
t.stm32_enc = { macro = 'ENABLE_ENC' }
|
||||
end
|
||||
|
||||
-- Add specific configuration to the 'configs' table
|
||||
function add_platform_configs( t )
|
||||
end
|
||||
|
||||
-- Return an array of all the available platform modules for the given cpu
|
||||
function get_platform_modules( cpu )
|
||||
return { enc = { 'ENABLE_ENC' } }
|
||||
end
|
||||
|
51
src/platform/stm32/cpu_stm32f103re.h
Normal file
51
src/platform/stm32/cpu_stm32f103re.h
Normal file
@ -0,0 +1,51 @@
|
||||
// CPU definition file for STM32F103RE
|
||||
|
||||
#ifndef __CPU_STM32F103RE_H__
|
||||
#define __CPU_STM32F103RE_H__
|
||||
|
||||
#include "type.h"
|
||||
#include "stacks.h"
|
||||
#include "stm32f10x.h"
|
||||
#include "platform_ints.h"
|
||||
|
||||
// Number of resources (0 if not available/not implemented)
|
||||
#define NUM_PIO 7
|
||||
#define NUM_SPI 2
|
||||
#define NUM_UART 5
|
||||
#define NUM_TIMER 5
|
||||
#define NUM_PHYS_TIMER 5
|
||||
#define NUM_PWM 4
|
||||
#define NUM_ADC 16
|
||||
#define NUM_CAN 1
|
||||
|
||||
#define ADC_BIT_RESOLUTION 12
|
||||
|
||||
u32 platform_s_cpu_get_frequency();
|
||||
#define CPU_FREQUENCY platform_s_cpu_get_frequency()
|
||||
|
||||
// PIO prefix ('0' for P0, P1, ... or 'A' for PA, PB, ...)
|
||||
#define PIO_PREFIX 'A'
|
||||
// Pins per port configuration:
|
||||
// #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
|
||||
// #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
|
||||
// Use #define PIO_PINS_PER_PORT 0 if this isn't needed
|
||||
#define PIO_PINS_PER_PORT 16
|
||||
|
||||
// Internal memory data
|
||||
#define SRAM_SIZE ( 64 * 1024 )
|
||||
#define INTERNAL_RAM_FIRST_FREE end
|
||||
#define INTERNAL_RAM_LAST_FREE ( SRAM_BASE + SRAM_SIZE - STACK_SIZE_TOTAL - 1 )
|
||||
|
||||
#define INTERNAL_FLASH_SIZE ( 512 * 1024 )
|
||||
#define INTERNAL_FLASH_SECTOR_SIZE 2048
|
||||
#define INTERNAL_FLASH_START_ADDRESS 0x08000000
|
||||
|
||||
// Interrupt list for this CPU
|
||||
#define PLATFORM_CPU_CONSTANTS_INTS\
|
||||
_C( INT_GPIO_POSEDGE ), \
|
||||
_C( INT_GPIO_NEGEDGE ), \
|
||||
_C( INT_TMR_MATCH ), \
|
||||
_C( INT_UART_RX ),
|
||||
|
||||
#endif // #ifndef __CPU_STM32F103RE_H__
|
||||
|
14
src/platform/stm32/cpu_stm32f103ze.h
Normal file
14
src/platform/stm32/cpu_stm32f103ze.h
Normal file
@ -0,0 +1,14 @@
|
||||
// CPU definition file for STM32F103ZE
|
||||
// Use the STM32F103RE description as a base
|
||||
|
||||
#ifndef __CPU_STM32F103ZE_H__
|
||||
#define __CPU_STM32F103ZE_H__
|
||||
|
||||
#include "cpu_stm32f103re.h"
|
||||
|
||||
// 21 ADCs instead of 16
|
||||
#undef NUM_ADC
|
||||
#define NUM_ADC 21
|
||||
|
||||
#endif // #ifndef __CPU_STM32F103ZE_H__
|
||||
|
@ -1,200 +0,0 @@
|
||||
// eLua platform configuration
|
||||
|
||||
#ifndef __PLATFORM_CONF_H__
|
||||
#define __PLATFORM_CONF_H__
|
||||
|
||||
#include "auxmods.h"
|
||||
#include "type.h"
|
||||
#include "stacks.h"
|
||||
#include "stm32f10x.h"
|
||||
#include "elua_int.h"
|
||||
#include "sermux.h"
|
||||
|
||||
// *****************************************************************************
|
||||
// Define here what components you want for this platform
|
||||
|
||||
#define BUILD_XMODEM
|
||||
#define BUILD_SHELL
|
||||
#define BUILD_ROMFS
|
||||
//#define BUILD_MMCFS
|
||||
#define BUILD_TERM
|
||||
//#define BUILD_UIP
|
||||
//#define BUILD_DHCPC
|
||||
//#define BUILD_DNS
|
||||
#define BUILD_CON_GENERIC
|
||||
#define BUILD_ADC
|
||||
#define BUILD_RPC
|
||||
//#define BUILD_RFS
|
||||
//#define BUILD_CON_TCP
|
||||
#define BUILD_LINENOISE
|
||||
#define BUILD_C_INT_HANDLERS
|
||||
#define BUILD_LUA_INT_HANDLERS
|
||||
#define ENABLE_ENC
|
||||
|
||||
#define PLATFORM_HAS_SYSTIMER
|
||||
|
||||
// *****************************************************************************
|
||||
// UART/Timer IDs configuration data (used in main.c)
|
||||
|
||||
#define CON_UART_ID 0
|
||||
#define CON_UART_SPEED 115200
|
||||
#define TERM_LINES 25
|
||||
#define TERM_COLS 80
|
||||
|
||||
// *****************************************************************************
|
||||
// Auxiliary libraries that will be compiled for this platform
|
||||
|
||||
//#ifdef FORSTM3210E_EVAL
|
||||
//#define AUXLIB_LCD "stm3210lcd"
|
||||
//LUALIB_API int ( luaopen_lcd )( lua_State* L );
|
||||
//#define LCDLINE _ROM( AUXLIB_LCD, luaopen_lcd, lcd_map )
|
||||
//#else
|
||||
#define LCDLINE
|
||||
//#endif
|
||||
|
||||
#ifdef ENABLE_ENC
|
||||
#define PS_LIB_TABLE_NAME "stm32"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef BUILD_ADC
|
||||
#define ADCLINE _ROM( AUXLIB_ADC, luaopen_adc, adc_map )
|
||||
#else
|
||||
#define ADCLINE
|
||||
#endif
|
||||
|
||||
#if defined( ELUA_BOOT_RPC ) && !defined( BUILD_RPC )
|
||||
#define BUILD_RPC
|
||||
#endif
|
||||
|
||||
#if defined( BUILD_RPC )
|
||||
#define RPCLINE _ROM( AUXLIB_RPC, luaopen_rpc, rpc_map )
|
||||
#else
|
||||
#define RPCLINE
|
||||
#endif
|
||||
|
||||
#ifdef PS_LIB_TABLE_NAME
|
||||
#define PLATLINE _ROM( PS_LIB_TABLE_NAME, luaopen_platform, platform_map )
|
||||
#else
|
||||
#define PLATLINE
|
||||
#endif
|
||||
|
||||
#define LUA_PLATFORM_LIBS_ROM\
|
||||
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
|
||||
_ROM( AUXLIB_SPI, luaopen_spi, spi_map )\
|
||||
_ROM( AUXLIB_PD, luaopen_pd, pd_map )\
|
||||
_ROM( AUXLIB_UART, luaopen_uart, uart_map )\
|
||||
_ROM( AUXLIB_TERM, luaopen_term, term_map )\
|
||||
_ROM( AUXLIB_PACK, luaopen_pack, pack_map )\
|
||||
_ROM( AUXLIB_BIT, luaopen_bit, bit_map )\
|
||||
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map )\
|
||||
_ROM( AUXLIB_ELUA, luaopen_elua, elua_map )\
|
||||
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
|
||||
ADCLINE\
|
||||
_ROM( AUXLIB_CAN, luaopen_can, can_map )\
|
||||
_ROM( AUXLIB_PWM, luaopen_pwm, pwm_map )\
|
||||
RPCLINE\
|
||||
LCDLINE\
|
||||
_ROM( AUXLIB_ELUA, luaopen_elua, elua_map )\
|
||||
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )\
|
||||
PLATLINE
|
||||
|
||||
// *****************************************************************************
|
||||
// Configuration data
|
||||
|
||||
#define EGC_INITIAL_MODE 1
|
||||
|
||||
// Virtual timers (0 if not used)
|
||||
#define VTMR_NUM_TIMERS 4
|
||||
#define VTMR_FREQ_HZ 10
|
||||
|
||||
// Number of resources (0 if not available/not implemented)
|
||||
#define NUM_PIO 7
|
||||
#define NUM_SPI 2
|
||||
#define NUM_UART 5
|
||||
#define NUM_TIMER 5
|
||||
#define NUM_PHYS_TIMER 5
|
||||
#define NUM_PWM 4
|
||||
#define NUM_ADC 16
|
||||
#define NUM_CAN 1
|
||||
|
||||
// Enable RX buffering on UART
|
||||
#define BUF_ENABLE_UART
|
||||
#define CON_BUF_SIZE BUF_SIZE_128
|
||||
|
||||
// ADC Configuration Params
|
||||
#define ADC_BIT_RESOLUTION 12
|
||||
#define BUF_ENABLE_ADC
|
||||
#define ADC_BUF_SIZE BUF_SIZE_2
|
||||
|
||||
// These should be adjusted to support multiple ADC devices
|
||||
#define ADC_TIMER_FIRST_ID 0
|
||||
#define ADC_NUM_TIMERS 4
|
||||
|
||||
// RPC boot options
|
||||
#define RPC_UART_ID CON_UART_ID
|
||||
#define RPC_UART_SPEED CON_UART_SPEED
|
||||
|
||||
|
||||
|
||||
|
||||
// MMCFS Support (FatFs on SD/MMC)
|
||||
// For STM32F103RET6 - PA5 = CLK, PA6 = MISO, PA7 = MOSI, PA8 = CS
|
||||
#define MMCFS_CS_PORT 0
|
||||
#define MMCFS_CS_PIN 8
|
||||
#define MMCFS_SPI_NUM 0
|
||||
|
||||
// CPU frequency (needed by the CPU module, 0 if not used)
|
||||
u32 platform_s_cpu_get_frequency();
|
||||
#define CPU_FREQUENCY platform_s_cpu_get_frequency()
|
||||
|
||||
// PIO prefix ('0' for P0, P1, ... or 'A' for PA, PB, ...)
|
||||
#define PIO_PREFIX 'A'
|
||||
// Pins per port configuration:
|
||||
// #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
|
||||
// #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
|
||||
// Use #define PIO_PINS_PER_PORT 0 if this isn't needed
|
||||
#define PIO_PINS_PER_PORT 16
|
||||
|
||||
// Remote file system data
|
||||
#define RFS_BUFFER_SIZE BUF_SIZE_512
|
||||
#define RFS_UART_ID 0
|
||||
#define RFS_TIMEOUT 100000
|
||||
#define RFS_UART_SPEED 115200
|
||||
|
||||
// Linenoise buffer sizes
|
||||
#define LINENOISE_HISTORY_SIZE_LUA 50
|
||||
#define LINENOISE_HISTORY_SIZE_SHELL 10
|
||||
|
||||
// Allocator data: define your free memory zones here in two arrays
|
||||
// (start address and end address)
|
||||
#define SRAM_SIZE ( 64 * 1024 )
|
||||
#define MEM_START_ADDRESS { ( void* )end }
|
||||
#define MEM_END_ADDRESS { ( void* )( SRAM_BASE + SRAM_SIZE - STACK_SIZE_TOTAL - 1 ) }
|
||||
|
||||
// Flash data (only for STM32F103RE for now)
|
||||
#ifdef ELUA_CPU_STM32F103RE
|
||||
#define INTERNAL_FLASH_SIZE ( 512 * 1024 )
|
||||
#define INTERNAL_FLASH_SECTOR_SIZE 2048
|
||||
#define INTERNAL_FLASH_START_ADDRESS 0x08000000
|
||||
#define BUILD_WOFS
|
||||
#endif // #ifdef ELUA_CPU_STM32F103RE
|
||||
|
||||
// Interrupt queue size
|
||||
#define PLATFORM_INT_QUEUE_LOG_SIZE 5
|
||||
|
||||
// Interrupt list
|
||||
#define INT_GPIO_POSEDGE ELUA_INT_FIRST_ID
|
||||
#define INT_GPIO_NEGEDGE ( ELUA_INT_FIRST_ID + 1 )
|
||||
#define INT_TMR_MATCH ( ELUA_INT_FIRST_ID + 2 )
|
||||
#define INT_UART_RX ( ELUA_INT_FIRST_ID + 3 )
|
||||
#define INT_ELUA_LAST INT_UART_RX
|
||||
|
||||
#define PLATFORM_CPU_CONSTANTS\
|
||||
_C( INT_GPIO_POSEDGE ), \
|
||||
_C( INT_GPIO_NEGEDGE ), \
|
||||
_C( INT_TMR_MATCH ), \
|
||||
_C( INT_UART_RX )
|
||||
|
||||
#endif // #ifndef __PLATFORM_CONF_H__
|
||||
|
9
src/platform/stm32/platform_generic.h
Normal file
9
src/platform/stm32/platform_generic.h
Normal file
@ -0,0 +1,9 @@
|
||||
// Generic platform-wide header
|
||||
|
||||
#ifndef __PLATFORM_GENERIC_H__
|
||||
#define __PLATFORM_GENERIC_H__
|
||||
|
||||
#define PLATFORM_HAS_SYSTIMER
|
||||
|
||||
#endif // #ifndef __PLATFORM_GENERIC_H__
|
||||
|
15
src/platform/stm32/platform_ints.h
Normal file
15
src/platform/stm32/platform_ints.h
Normal file
@ -0,0 +1,15 @@
|
||||
// This header lists all interrupts defined for this platform
|
||||
|
||||
#ifndef __PLATFORM_INTS_H__
|
||||
#define __PLATFORM_INTS_H__
|
||||
|
||||
#include "elua_int.h"
|
||||
|
||||
#define INT_GPIO_POSEDGE ELUA_INT_FIRST_ID
|
||||
#define INT_GPIO_NEGEDGE ( ELUA_INT_FIRST_ID + 1 )
|
||||
#define INT_TMR_MATCH ( ELUA_INT_FIRST_ID + 2 )
|
||||
#define INT_UART_RX ( ELUA_INT_FIRST_ID + 3 )
|
||||
#define INT_ELUA_LAST INT_UART_RX
|
||||
|
||||
#endif // #ifndef __PLATFORM_INTS_H__
|
||||
|
34
src/platform/str7/cpu_str711fr2.h
Normal file
34
src/platform/str7/cpu_str711fr2.h
Normal file
@ -0,0 +1,34 @@
|
||||
// STR711FR2 CPU description
|
||||
|
||||
#ifndef __CPU_STR711FR2_H__
|
||||
#define __CPU_STR711FR2_H__
|
||||
|
||||
#include "stacks.h"
|
||||
|
||||
// Number of resources (0 if not available/not implemented)
|
||||
#define NUM_PIO 2
|
||||
#define NUM_SPI 0
|
||||
#define NUM_UART 4
|
||||
#define NUM_TIMER 4
|
||||
#define NUM_PWM 3
|
||||
#define NUM_ADC 0
|
||||
#define NUM_CAN 0
|
||||
|
||||
// CPU frequency (needed by the CPU module and MMCFS code, 0 if not used)
|
||||
#define CPU_FREQUENCY 0
|
||||
|
||||
// PIO prefix ('0' for P0, P1, ... or 'A' for PA, PB, ...)
|
||||
#define PIO_PREFIX '0'
|
||||
// Pins per port configuration:
|
||||
// #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
|
||||
// #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
|
||||
// Use #define PIO_PINS_PER_PORT 0 if this isn't needed
|
||||
#define PIO_PINS_PER_PORT 16
|
||||
|
||||
#define SRAM_ORIGIN 0x20000000
|
||||
#define SRAM_SIZE 0x10000
|
||||
#define INTERNAL_RAM_FIRST_FREE end
|
||||
#define INTERNAL_RAM_LAST_FREE ( SRAM_ORIGIN + SRAM_SIZE - STACK_SIZE_TOTAL - 1 )
|
||||
|
||||
#endif // #ifndef __CPU_STR711FR2_H__
|
||||
|
@ -1,94 +0,0 @@
|
||||
// eLua platform configuration
|
||||
|
||||
#ifndef __PLATFORM_CONF_H__
|
||||
#define __PLATFORM_CONF_H__
|
||||
|
||||
#include "auxmods.h"
|
||||
#include "stacks.h"
|
||||
|
||||
// *****************************************************************************
|
||||
// Define here what components you want for this platform
|
||||
|
||||
#define BUILD_XMODEM
|
||||
#define BUILD_SHELL
|
||||
#define BUILD_ROMFS
|
||||
#define BUILD_TERM
|
||||
#define BUILD_CON_GENERIC
|
||||
//#define BUILD_RPC
|
||||
|
||||
// *****************************************************************************
|
||||
// UART/Timer IDs configuration data (used in main.c)
|
||||
|
||||
#define CON_UART_ID 1
|
||||
#define CON_UART_SPEED 38400
|
||||
#define CON_TIMER_ID 0
|
||||
#define TERM_LINES 25
|
||||
#define TERM_COLS 80
|
||||
|
||||
// *****************************************************************************
|
||||
// Auxiliary libraries that will be compiled for this platform
|
||||
|
||||
#if defined( ELUA_BOOT_RPC ) && !defined( BUILD_RPC )
|
||||
#define BUILD_RPC
|
||||
#endif
|
||||
|
||||
#if defined( BUILD_RPC )
|
||||
#define RPCLINE _ROM( AUXLIB_RPC, luaopen_rpc, rpc_map )
|
||||
#else
|
||||
#define RPCLINE
|
||||
#endif
|
||||
|
||||
#define LUA_PLATFORM_LIBS_ROM\
|
||||
_ROM( AUXLIB_PIO, luaopen_pio, pio_map )\
|
||||
_ROM( AUXLIB_TMR, luaopen_tmr, tmr_map )\
|
||||
_ROM( AUXLIB_PD, luaopen_pd, pd_map )\
|
||||
_ROM( AUXLIB_PWM, luaopen_pwm, pwm_map )\
|
||||
_ROM( AUXLIB_UART, luaopen_uart, uart_map )\
|
||||
_ROM( AUXLIB_TERM, luaopen_term, term_map )\
|
||||
_ROM( AUXLIB_PACK, luaopen_pack, pack_map )\
|
||||
_ROM( AUXLIB_BIT, luaopen_bit, bit_map )\
|
||||
_ROM( AUXLIB_ELUA, luaopen_elua, elua_map )\
|
||||
_ROM( AUXLIB_CPU, luaopen_cpu, cpu_map )\
|
||||
RPCLINE\
|
||||
_ROM( LUA_MATHLIBNAME, luaopen_math, math_map )
|
||||
|
||||
// *****************************************************************************
|
||||
// Configuration data
|
||||
|
||||
// Virtual timers (0 if not used)
|
||||
#define VTMR_NUM_TIMERS 0
|
||||
#define VTMR_FREQ_HZ 4
|
||||
|
||||
// Number of resources (0 if not available/not implemented)
|
||||
#define NUM_PIO 2
|
||||
#define NUM_SPI 0
|
||||
#define NUM_UART 4
|
||||
#define NUM_TIMER 4
|
||||
#define NUM_PWM 3
|
||||
#define NUM_ADC 0
|
||||
#define NUM_CAN 0
|
||||
|
||||
// RPC boot options
|
||||
#define RPC_UART_ID CON_UART_ID
|
||||
#define RPC_TIMER_ID CON_TIMER_ID
|
||||
#define RPC_UART_SPEED CON_UART_SPEED
|
||||
|
||||
// CPU frequency (needed by the CPU module and MMCFS code, 0 if not used)
|
||||
#define CPU_FREQUENCY 0
|
||||
|
||||
// PIO prefix ('0' for P0, P1, ... or 'A' for PA, PB, ...)
|
||||
#define PIO_PREFIX '0'
|
||||
// Pins per port configuration:
|
||||
// #define PIO_PINS_PER_PORT (n) if each port has the same number of pins, or
|
||||
// #define PIO_PIN_ARRAY { n1, n2, ... } to define pins per port in an array
|
||||
// Use #define PIO_PINS_PER_PORT 0 if this isn't needed
|
||||
#define PIO_PINS_PER_PORT 16
|
||||
|
||||
// Allocator data: define your free memory zones here in two arrays
|
||||
// (start address and end address)
|
||||
#define SRAM_ORIGIN 0x20000000
|
||||
#define SRAM_SIZE 0x10000
|
||||
#define MEM_START_ADDRESS { ( void* )end }
|
||||
#define MEM_END_ADDRESS { ( void* )( SRAM_ORIGIN + SRAM_SIZE - STACK_SIZE_TOTAL - 1 ) }
|
||||
|
||||
#endif // #ifndef __PLATFORM_CONF_H__
|
7
src/platform/str7/platform_generic.h
Normal file
7
src/platform/str7/platform_generic.h
Normal file
@ -0,0 +1,7 @@
|
||||
// Platform customization header
|
||||
|
||||
#ifndef __PLATFORM_GENERIC_H__
|
||||
#define __PLATFORM_GENERIC_H__
|
||||
|
||||
#endif // #ifndef __PLATFORM_GENERIC_H__
|
||||
|
@ -328,6 +328,7 @@ builder.new = function( build_dir )
|
||||
self.clean_mode = false
|
||||
self.opts = utils.options_handler()
|
||||
self.args = {}
|
||||
self.user_args = {}
|
||||
self.build_mode = self.KEEP_DIR
|
||||
self.targets = {}
|
||||
self.targetargs = {}
|
||||
@ -389,6 +390,7 @@ builder.init = function( self, args )
|
||||
os.exit( 1 )
|
||||
end
|
||||
self.args[ k:upper() ] = v
|
||||
self.user_args[ k:upper() ] = true
|
||||
else -- this must be the target name / target arguments
|
||||
if self.targetname == nil then
|
||||
self.targetname = a
|
||||
@ -408,6 +410,11 @@ builder.get_option = function( self, optname )
|
||||
return self.args[ optname:upper() ]
|
||||
end
|
||||
|
||||
-- Returns true if the given option was specified by the user on the command line, false otherwise
|
||||
builder.is_user_option = function( self, optname )
|
||||
return self.user_args[ optname:upper() ]
|
||||
end
|
||||
|
||||
-- Show builder help
|
||||
builder._show_help = function( self )
|
||||
print( "[builder] Valid options:" )
|
||||
@ -719,11 +726,11 @@ end
|
||||
builder.build = function( self, target )
|
||||
local t = self.targetname or self.deftarget
|
||||
if not t then
|
||||
print( "[builder] Error: build target not specified" )
|
||||
print( utils.col_red( "[builder] Error: build target not specified" ) )
|
||||
os.exit( 1 )
|
||||
end
|
||||
if not self.targets[ t ] then
|
||||
print( sf( "[builder] Error: target '%s' not found", t ) )
|
||||
print( utils.col_red( sf( "[builder] Error: target '%s' not found", t ) ) )
|
||||
print( "Available targets: " )
|
||||
for k, v in pairs( self.targets ) do
|
||||
if not is_phony( k ) then
|
||||
@ -738,19 +745,19 @@ builder.build = function( self, target )
|
||||
self:_create_outdir()
|
||||
-- At this point check if we have a change in the state that would require a rebuild
|
||||
if self:_compare_config( 'comp' ) then
|
||||
print "[builder] Forcing rebuild due to configuration change"
|
||||
print( utils.col_yellow( "[builder] Forcing rebuild due to configuration change." ) )
|
||||
self.global_force_rebuild = true
|
||||
else
|
||||
self.global_force_rebuild = false
|
||||
end
|
||||
-- Do the actual build
|
||||
local res = self.targets[ t ].target:build()
|
||||
if not res then print( sf( '[builder] %s: up to date', t ) ) end
|
||||
if not res then print( utils.col_yellow( sf( '[builder] %s: up to date', t ) ) ) end
|
||||
if self.clean_mode then
|
||||
os.remove( self.build_dir .. utils.dir_sep .. ".builddata.comp" )
|
||||
os.remove( self.build_dir .. utils.dir_sep .. ".builddata.link" )
|
||||
end
|
||||
print "[builder] Done building target."
|
||||
print( utils.col_yellow( "[builder] Done building target." ) )
|
||||
return res
|
||||
end
|
||||
|
||||
|
@ -4,6 +4,7 @@ module( ..., package.seeall )
|
||||
|
||||
local lfs = require "lfs"
|
||||
local sf = string.format
|
||||
local md5 = require "md5"
|
||||
|
||||
-- Taken from Lake
|
||||
dir_sep = package.config:sub( 1, 1 )
|
||||
@ -37,7 +38,13 @@ end
|
||||
-- Replace the extension of a give file name
|
||||
replace_extension = function( s, newext )
|
||||
local p, e = split_path( s )
|
||||
if e then s = p .. "." .. newext end
|
||||
if e then
|
||||
if newext and #newext > 0 then
|
||||
s = p .. "." .. newext
|
||||
else
|
||||
s = p
|
||||
end
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
@ -111,6 +118,13 @@ table_keys = function( t )
|
||||
return keys
|
||||
end
|
||||
|
||||
-- Return an array with the values of a table
|
||||
table_values = function( t )
|
||||
local vals = {}
|
||||
foreach( t, function( k, v ) table.insert( vals, v ) end )
|
||||
return vals
|
||||
end
|
||||
|
||||
-- Returns true if 'path' is a regular file, false otherwise
|
||||
is_file = function( path )
|
||||
return lfs.attributes( path, "mode" ) == "file"
|
||||
@ -168,22 +182,71 @@ foreach = function ( t, cmd )
|
||||
for k, v in pairs( t ) do cmd( k, v ) end
|
||||
end
|
||||
|
||||
-- Template header
|
||||
gen_header = function( name, defines )
|
||||
local hname = "inc" .. dir_sep .. name:lower() .. ".h"
|
||||
local h = assert(io.open(hname, "w"))
|
||||
h:write("// eLua " .. name:lower() .. " definition\n\n")
|
||||
h:write("#ifndef __" .. name:upper() .. "_H__\n")
|
||||
h:write("#define __" .. name:upper() .. "_H__\n\n")
|
||||
-- Generate header with the given #defines, return result as string
|
||||
gen_header_string = function( name, defines )
|
||||
local s = "// eLua " .. name:lower() .. " definition\n\n"
|
||||
s = s .. "#ifndef __" .. name:upper() .. "_H__\n"
|
||||
s = s .. "#define __" .. name:upper() .. "_H__\n\n"
|
||||
|
||||
for key,value in pairs(defines) do
|
||||
h:write(string.format("#define %-25s%-19s\n",key:upper(),value))
|
||||
s = s .. string.format("#define %-25s%-19s\n",key:upper(),value)
|
||||
end
|
||||
|
||||
h:write("\n#endif\n")
|
||||
s = s .. "\n#endif\n"
|
||||
return s
|
||||
end
|
||||
|
||||
-- Generate header with the given #defines, save result to file
|
||||
gen_header_file = function( name, defines )
|
||||
local hname = concat_path{ "inc", name:lower() .. ".h" }
|
||||
local h = assert( io.open( hname, "w" ) )
|
||||
h:write( gen_header_string( name, defines ) )
|
||||
h:close()
|
||||
end
|
||||
|
||||
-- Remove the given elements from an array
|
||||
remove_array_elements = function( arr, del )
|
||||
del = istable( del ) and del or { del }
|
||||
foreach( del, function( k, v )
|
||||
local pos = array_element_index( arr, v )
|
||||
if pos then table.remove( arr, pos ) end
|
||||
end )
|
||||
end
|
||||
|
||||
-- Remove a directory recusively
|
||||
-- USE WITH CARE!! Doesn't do much checks :)
|
||||
rm_dir_rec = function ( dirname )
|
||||
for f in lfs.dir( dirname ) do
|
||||
local ename = string.format( "%s/%s", dirname, f )
|
||||
local attrs = lfs.attributes( ename )
|
||||
if attrs.mode == 'directory' and f ~= '.' and f ~= '..' then
|
||||
rm_dir_rec( ename )
|
||||
elseif attrs.mode == 'file' or attrs.mode == 'named pipe' or attrs.mode == 'link' then
|
||||
os.remove( ename )
|
||||
end
|
||||
end
|
||||
lfs.rmdir( dirname )
|
||||
end
|
||||
|
||||
-- Computes the hash of the given string
|
||||
get_hash_of_string = function( s )
|
||||
return md5.sumhexa( s )
|
||||
end
|
||||
|
||||
-- Computes the hash of the given file
|
||||
get_hash_of_file = function( f )
|
||||
local f = io.open( f, "rb" )
|
||||
if not f then return end
|
||||
local d = f:read( "*a" )
|
||||
f:close()
|
||||
return get_hash_of_string( d )
|
||||
end
|
||||
|
||||
-- Concatenates the second table into the first one
|
||||
concat_tables = function( dst, src )
|
||||
foreach( src, function( k, v ) dst[ k ] = v end )
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Color-related funtions
|
||||
-- Currently disabled when running in Windows
|
||||
|
Loading…
x
Reference in New Issue
Block a user