mirror of https://github.com/ARMmbed/mbed-os.git
Merge branch 'master' of https://github.com/ARMmbed/mbed-os
commit
cd4172a80b
|
@ -0,0 +1,110 @@
|
||||||
|
#include "mbed.h"
|
||||||
|
#include "test_env.h"
|
||||||
|
#include "unity.h"
|
||||||
|
#include "utest.h"
|
||||||
|
#include "rtos.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace utest::v1;
|
||||||
|
|
||||||
|
|
||||||
|
// Tasks with different functions to test on threads
|
||||||
|
void increment(const void *var) {
|
||||||
|
(*(int *)var)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment_with_yield(const void *var) {
|
||||||
|
Thread::yield();
|
||||||
|
(*(int *)var)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment_with_wait(const void *var) {
|
||||||
|
Thread::wait(100);
|
||||||
|
(*(int *)var)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment_with_child(const void *var) {
|
||||||
|
Thread child(increment, (void*)var);
|
||||||
|
child.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment_with_murder(const void *var) {
|
||||||
|
Thread child(increment_with_wait, (void*)var);
|
||||||
|
// Kill child before it can increment var
|
||||||
|
child.terminate();
|
||||||
|
(*(int *)var)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tests that spawn tasks in different configurations
|
||||||
|
template <void (*F)(const void *)>
|
||||||
|
void test_single_thread() {
|
||||||
|
int var = 0;
|
||||||
|
Thread thread(F, &var);
|
||||||
|
thread.join();
|
||||||
|
TEST_ASSERT_EQUAL(var, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int N, void (*F)(const void *)>
|
||||||
|
void test_parallel_threads() {
|
||||||
|
int var = 0;
|
||||||
|
Thread *threads[N];
|
||||||
|
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
threads[i] = new Thread(F, &var);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
threads[i]->join();
|
||||||
|
delete threads[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(var, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <int N, void (*F)(const void *)>
|
||||||
|
void test_serial_threads() {
|
||||||
|
int var = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < N; i++) {
|
||||||
|
Thread thread(F, &var);
|
||||||
|
thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(var, N);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t test_setup(const size_t number_of_cases) {
|
||||||
|
GREENTEA_SETUP(40, "default_auto");
|
||||||
|
return verbose_test_setup_handler(number_of_cases);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test cases
|
||||||
|
Case cases[] = {
|
||||||
|
Case("Testing single thread", test_single_thread<increment>),
|
||||||
|
Case("Testing parallel threads", test_parallel_threads<3, increment>),
|
||||||
|
Case("Testing serial threads", test_serial_threads<10, increment>),
|
||||||
|
|
||||||
|
Case("Testing single thread with yield", test_single_thread<increment_with_yield>),
|
||||||
|
Case("Testing parallel threads with yield", test_parallel_threads<3, increment_with_yield>),
|
||||||
|
Case("Testing serial threads with yield", test_serial_threads<10, increment_with_yield>),
|
||||||
|
|
||||||
|
Case("Testing single thread with wait", test_single_thread<increment_with_wait>),
|
||||||
|
Case("Testing parallel threads with wait", test_parallel_threads<3, increment_with_wait>),
|
||||||
|
Case("Testing serial threads with wait", test_serial_threads<10, increment_with_wait>),
|
||||||
|
|
||||||
|
Case("Testing single thread with child", test_single_thread<increment_with_child>),
|
||||||
|
Case("Testing parallel threads with child", test_parallel_threads<3, increment_with_child>),
|
||||||
|
Case("Testing serial threads with child", test_serial_threads<10, increment_with_child>),
|
||||||
|
|
||||||
|
Case("Testing single thread with murder", test_single_thread<increment_with_murder>),
|
||||||
|
Case("Testing parallel threads with murder", test_parallel_threads<3, increment_with_murder>),
|
||||||
|
Case("Testing serial threads with murder", test_serial_threads<10, increment_with_murder>),
|
||||||
|
};
|
||||||
|
|
||||||
|
Specification specification(test_setup, cases);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return !Harness::run(specification);
|
||||||
|
}
|
|
@ -26,34 +26,82 @@
|
||||||
|
|
||||||
namespace rtos {
|
namespace rtos {
|
||||||
|
|
||||||
Thread::Thread(void (*task)(void const *argument), void *argument,
|
Thread::Thread(osPriority priority,
|
||||||
osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) {
|
uint32_t stack_size, unsigned char *stack_pointer):
|
||||||
|
_tid(NULL), _dynamic_stack(stack_pointer == NULL) {
|
||||||
#ifdef __MBED_CMSIS_RTOS_CM
|
#ifdef __MBED_CMSIS_RTOS_CM
|
||||||
_thread_def.pthread = task;
|
|
||||||
_thread_def.tpriority = priority;
|
_thread_def.tpriority = priority;
|
||||||
_thread_def.stacksize = stack_size;
|
_thread_def.stacksize = stack_size;
|
||||||
if (stack_pointer != NULL) {
|
_thread_def.stack_pointer = (uint32_t*)stack_pointer;
|
||||||
_thread_def.stack_pointer = (uint32_t*)stack_pointer;
|
#endif
|
||||||
_dynamic_stack = false;
|
}
|
||||||
} else {
|
|
||||||
_thread_def.stack_pointer = new uint32_t[stack_size/sizeof(uint32_t)];
|
Thread::Thread(void (*task)(void const *argument), void *argument,
|
||||||
if (_thread_def.stack_pointer == NULL)
|
osPriority priority, uint32_t stack_size, unsigned char *stack_pointer):
|
||||||
|
_tid(NULL), _dynamic_stack(stack_pointer == NULL) {
|
||||||
|
#ifdef __MBED_CMSIS_RTOS_CM
|
||||||
|
_thread_def.tpriority = priority;
|
||||||
|
_thread_def.stacksize = stack_size;
|
||||||
|
_thread_def.stack_pointer = (uint32_t*)stack_pointer;
|
||||||
|
#endif
|
||||||
|
switch(start(task, argument)) {
|
||||||
|
case osErrorResource:
|
||||||
|
error("OS ran out of threads!\n");
|
||||||
|
break;
|
||||||
|
case osErrorParameter:
|
||||||
|
error("Thread already running!\n");
|
||||||
|
break;
|
||||||
|
case osErrorNoMemory:
|
||||||
error("Error allocating the stack memory\n");
|
error("Error allocating the stack memory\n");
|
||||||
_dynamic_stack = true;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
osStatus Thread::start(void (*task)(void const *argument), void *argument) {
|
||||||
|
if (_tid != NULL) {
|
||||||
|
return osErrorParameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __MBED_CMSIS_RTOS_CM
|
||||||
|
_thread_def.pthread = task;
|
||||||
|
if (_thread_def.stack_pointer == NULL) {
|
||||||
|
_thread_def.stack_pointer = new uint32_t[_thread_def.stacksize/sizeof(uint32_t)];
|
||||||
|
if (_thread_def.stack_pointer == NULL)
|
||||||
|
return osErrorNoMemory;
|
||||||
|
}
|
||||||
|
|
||||||
//Fill the stack with a magic word for maximum usage checking
|
//Fill the stack with a magic word for maximum usage checking
|
||||||
for (uint32_t i = 0; i < (stack_size / sizeof(uint32_t)); i++) {
|
for (uint32_t i = 0; i < (_thread_def.stacksize / sizeof(uint32_t)); i++) {
|
||||||
_thread_def.stack_pointer[i] = 0xE25A2EA5;
|
_thread_def.stack_pointer[i] = 0xE25A2EA5;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
_tid = osThreadCreate(&_thread_def, argument);
|
_tid = osThreadCreate(&_thread_def, argument);
|
||||||
|
if (_tid == NULL) {
|
||||||
|
if (_dynamic_stack) delete[] (_thread_def.stack_pointer);
|
||||||
|
return osErrorResource;
|
||||||
|
}
|
||||||
|
return osOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
osStatus Thread::terminate() {
|
osStatus Thread::terminate() {
|
||||||
return osThreadTerminate(_tid);
|
return osThreadTerminate(_tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osStatus Thread::join() {
|
||||||
|
while (true) {
|
||||||
|
uint8_t state = get_state();
|
||||||
|
if (state == Thread::Inactive || state == osErrorParameter) {
|
||||||
|
return osOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
osStatus status = yield();
|
||||||
|
if (status != osOK) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
osStatus Thread::set_priority(osPriority priority) {
|
osStatus Thread::set_priority(osPriority priority) {
|
||||||
return osThreadSetPriority(_tid, priority);
|
return osThreadSetPriority(_tid, priority);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,15 @@ namespace rtos {
|
||||||
/** The Thread class allow defining, creating, and controlling thread functions in the system. */
|
/** The Thread class allow defining, creating, and controlling thread functions in the system. */
|
||||||
class Thread {
|
class Thread {
|
||||||
public:
|
public:
|
||||||
|
/** Allocate a new thread without starting execution
|
||||||
|
@param priority initial priority of the thread function. (default: osPriorityNormal).
|
||||||
|
@param stack_size stack size (in bytes) requirements for the thread function. (default: DEFAULT_STACK_SIZE).
|
||||||
|
@param stack_pointer pointer to the stack area to be used by this thread (default: NULL).
|
||||||
|
*/
|
||||||
|
Thread(osPriority priority=osPriorityNormal,
|
||||||
|
uint32_t stack_size=DEFAULT_STACK_SIZE,
|
||||||
|
unsigned char *stack_pointer=NULL);
|
||||||
|
|
||||||
/** Create a new thread, and start it executing the specified function.
|
/** Create a new thread, and start it executing the specified function.
|
||||||
@param task function to be executed by this thread.
|
@param task function to be executed by this thread.
|
||||||
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
|
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
|
||||||
|
@ -42,6 +51,19 @@ public:
|
||||||
uint32_t stack_size=DEFAULT_STACK_SIZE,
|
uint32_t stack_size=DEFAULT_STACK_SIZE,
|
||||||
unsigned char *stack_pointer=NULL);
|
unsigned char *stack_pointer=NULL);
|
||||||
|
|
||||||
|
/** Starts a thread executing the specified function.
|
||||||
|
@param task function to be executed by this thread.
|
||||||
|
@param argument pointer that is passed to the thread function as start argument. (default: NULL).
|
||||||
|
@return status code that indicates the execution status of the function.
|
||||||
|
*/
|
||||||
|
osStatus start(void (*task)(void const *argument), void *argument=NULL);
|
||||||
|
|
||||||
|
/** Wait for thread to terminate
|
||||||
|
@return status code that indicates the execution status of the function.
|
||||||
|
@note not callable from interrupt
|
||||||
|
*/
|
||||||
|
osStatus join();
|
||||||
|
|
||||||
/** Terminate execution of a thread and remove it from Active Threads
|
/** Terminate execution of a thread and remove it from Active Threads
|
||||||
@return status code that indicates the execution status of the function.
|
@return status code that indicates the execution status of the function.
|
||||||
*/
|
*/
|
||||||
|
@ -113,17 +135,20 @@ public:
|
||||||
@param signals wait until all specified signal flags set or 0 for any single signal flag.
|
@param signals wait until all specified signal flags set or 0 for any single signal flag.
|
||||||
@param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
|
@param millisec timeout value or 0 in case of no time-out. (default: osWaitForever).
|
||||||
@return event flag information or error code.
|
@return event flag information or error code.
|
||||||
|
@note not callable from interrupt
|
||||||
*/
|
*/
|
||||||
static osEvent signal_wait(int32_t signals, uint32_t millisec=osWaitForever);
|
static osEvent signal_wait(int32_t signals, uint32_t millisec=osWaitForever);
|
||||||
|
|
||||||
/** Wait for a specified time period in millisec:
|
/** Wait for a specified time period in millisec:
|
||||||
@param millisec time delay value
|
@param millisec time delay value
|
||||||
@return status code that indicates the execution status of the function.
|
@return status code that indicates the execution status of the function.
|
||||||
|
@note not callable from interrupt
|
||||||
*/
|
*/
|
||||||
static osStatus wait(uint32_t millisec);
|
static osStatus wait(uint32_t millisec);
|
||||||
|
|
||||||
/** Pass control to next thread that is in state READY.
|
/** Pass control to next thread that is in state READY.
|
||||||
@return status code that indicates the execution status of the function.
|
@return status code that indicates the execution status of the function.
|
||||||
|
@note not callable from interrupt
|
||||||
*/
|
*/
|
||||||
static osStatus yield();
|
static osStatus yield();
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ sys.path.insert(0, ROOT)
|
||||||
|
|
||||||
from tools.test_api import test_path_to_name, find_tests, print_tests, build_tests, test_spec_from_test_build
|
from tools.test_api import test_path_to_name, find_tests, print_tests, build_tests, test_spec_from_test_build
|
||||||
from tools.options import get_default_options_parser
|
from tools.options import get_default_options_parser
|
||||||
from tools.build_api import build_project
|
from tools.build_api import build_project, build_library
|
||||||
from tools.targets import TARGET_MAP
|
from tools.targets import TARGET_MAP
|
||||||
from tools.utils import mkdir
|
from tools.utils import mkdir
|
||||||
|
|
||||||
|
@ -115,10 +115,17 @@ if __name__ == '__main__':
|
||||||
if not base_source_paths:
|
if not base_source_paths:
|
||||||
base_source_paths = ['.']
|
base_source_paths = ['.']
|
||||||
|
|
||||||
|
|
||||||
target = TARGET_MAP[options.mcu]
|
target = TARGET_MAP[options.mcu]
|
||||||
|
|
||||||
|
lib_build_res = build_library(base_source_paths, options.build_dir, target, options.tool,
|
||||||
|
options=options.options,
|
||||||
|
jobs=options.jobs,
|
||||||
|
clean=options.clean,
|
||||||
|
archive=False)
|
||||||
|
|
||||||
# Build all the tests
|
# Build all the tests
|
||||||
test_build = build_tests(tests, base_source_paths, options.build_dir, target, options.tool,
|
test_build = build_tests(tests, [options.build_dir], options.build_dir, target, options.tool,
|
||||||
options=options.options,
|
options=options.options,
|
||||||
clean=options.clean,
|
clean=options.clean,
|
||||||
jobs=options.jobs)
|
jobs=options.jobs)
|
||||||
|
|
|
@ -2041,13 +2041,13 @@ def build_tests(tests, base_source_paths, build_path, target, toolchain_name,
|
||||||
}
|
}
|
||||||
|
|
||||||
for test_name, test_path in tests.iteritems():
|
for test_name, test_path in tests.iteritems():
|
||||||
|
test_build_path = os.path.join(build_path, test_path)
|
||||||
src_path = base_source_paths + [test_path]
|
src_path = base_source_paths + [test_path]
|
||||||
artifact_name = os.path.join(test_path, test_name)
|
bin_file = build_project(src_path, test_build_path, target, toolchain_name,
|
||||||
bin_file = build_project(src_path, build_path, target, toolchain_name,
|
|
||||||
options=options,
|
options=options,
|
||||||
jobs=jobs,
|
jobs=jobs,
|
||||||
clean=clean,
|
clean=clean,
|
||||||
name=artifact_name,
|
name=test_name,
|
||||||
report=report,
|
report=report,
|
||||||
properties=properties,
|
properties=properties,
|
||||||
verbose=verbose)
|
verbose=verbose)
|
||||||
|
|
|
@ -29,6 +29,7 @@ from multiprocessing import Pool, cpu_count
|
||||||
from tools.utils import run_cmd, mkdir, rel_path, ToolException, NotSupportedException, split_path
|
from tools.utils import run_cmd, mkdir, rel_path, ToolException, NotSupportedException, split_path
|
||||||
from tools.settings import BUILD_OPTIONS, MBED_ORG_USER
|
from tools.settings import BUILD_OPTIONS, MBED_ORG_USER
|
||||||
import tools.hooks as hooks
|
import tools.hooks as hooks
|
||||||
|
from hashlib import md5
|
||||||
|
|
||||||
|
|
||||||
#Disables multiprocessing if set to higher number than the host machine CPUs
|
#Disables multiprocessing if set to higher number than the host machine CPUs
|
||||||
|
@ -210,6 +211,7 @@ class mbedToolchain:
|
||||||
self.has_config = False
|
self.has_config = False
|
||||||
|
|
||||||
self.build_all = False
|
self.build_all = False
|
||||||
|
self.build_dir = None
|
||||||
self.timestamp = time()
|
self.timestamp = time()
|
||||||
self.jobs = 1
|
self.jobs = 1
|
||||||
|
|
||||||
|
@ -476,19 +478,35 @@ class mbedToolchain:
|
||||||
mkdir(obj_dir)
|
mkdir(obj_dir)
|
||||||
return join(obj_dir, name + '.o')
|
return join(obj_dir, name + '.o')
|
||||||
|
|
||||||
|
def get_inc_file(self, includes):
|
||||||
|
include_file = join(self.build_dir, ".includes_%s.txt" % self.inc_md5)
|
||||||
|
if not exists(include_file):
|
||||||
|
with open(include_file, "wb") as f:
|
||||||
|
cmd_list = []
|
||||||
|
for c in includes:
|
||||||
|
if c:
|
||||||
|
cmd_list.append(('-I%s' % c).replace("\\", "/"))
|
||||||
|
string = " ".join(cmd_list)
|
||||||
|
f.write(string)
|
||||||
|
return include_file
|
||||||
|
|
||||||
def compile_sources(self, resources, build_path, inc_dirs=None):
|
def compile_sources(self, resources, build_path, inc_dirs=None):
|
||||||
# Web IDE progress bar for project build
|
# Web IDE progress bar for project build
|
||||||
files_to_compile = resources.s_sources + resources.c_sources + resources.cpp_sources
|
files_to_compile = resources.s_sources + resources.c_sources + resources.cpp_sources
|
||||||
self.to_be_compiled = len(files_to_compile)
|
self.to_be_compiled = len(files_to_compile)
|
||||||
self.compiled = 0
|
self.compiled = 0
|
||||||
|
|
||||||
#for i in self.build_params:
|
|
||||||
# self.debug(i)
|
|
||||||
# self.debug("%s" % self.build_params[i])
|
|
||||||
|
|
||||||
inc_paths = resources.inc_dirs
|
inc_paths = resources.inc_dirs
|
||||||
if inc_dirs is not None:
|
if inc_dirs is not None:
|
||||||
inc_paths.extend(inc_dirs)
|
inc_paths.extend(inc_dirs)
|
||||||
|
# De-duplicate include paths
|
||||||
|
inc_paths = set(inc_paths)
|
||||||
|
# Sort include paths for consistency
|
||||||
|
inc_paths = sorted(set(inc_paths))
|
||||||
|
# Unique id of all include paths
|
||||||
|
self.inc_md5 = md5(' '.join(inc_paths)).hexdigest()
|
||||||
|
# Where to store response files
|
||||||
|
self.build_dir = build_path
|
||||||
|
|
||||||
objects = []
|
objects = []
|
||||||
queue = []
|
queue = []
|
||||||
|
@ -496,6 +514,7 @@ class mbedToolchain:
|
||||||
|
|
||||||
# The dependency checking for C/C++ is delegated to the compiler
|
# The dependency checking for C/C++ is delegated to the compiler
|
||||||
base_path = resources.base_path
|
base_path = resources.base_path
|
||||||
|
# Sort compile queue for consistency
|
||||||
files_to_compile.sort()
|
files_to_compile.sort()
|
||||||
work_dir = getcwd()
|
work_dir = getcwd()
|
||||||
|
|
||||||
|
@ -641,28 +660,6 @@ class mbedToolchain:
|
||||||
else:
|
else:
|
||||||
raise ToolException(_stderr)
|
raise ToolException(_stderr)
|
||||||
|
|
||||||
def compile(self, cc, source, object, includes):
|
|
||||||
_, ext = splitext(source)
|
|
||||||
ext = ext.lower()
|
|
||||||
|
|
||||||
command = cc + ['-D%s' % s for s in self.get_symbols()] + ["-I%s" % i for i in includes] + ["-o", object, source]
|
|
||||||
|
|
||||||
if hasattr(self, "get_dep_opt"):
|
|
||||||
base, _ = splitext(object)
|
|
||||||
dep_path = base + '.d'
|
|
||||||
command.extend(self.get_dep_opt(dep_path))
|
|
||||||
|
|
||||||
if hasattr(self, "cc_extra"):
|
|
||||||
command.extend(self.cc_extra(base))
|
|
||||||
|
|
||||||
return [command]
|
|
||||||
|
|
||||||
def compile_c(self, source, object, includes):
|
|
||||||
return self.compile(self.cc, source, object, includes)
|
|
||||||
|
|
||||||
def compile_cpp(self, source, object, includes):
|
|
||||||
return self.compile(self.cppc, source, object, includes)
|
|
||||||
|
|
||||||
def build_library(self, objects, dir, name):
|
def build_library(self, objects, dir, name):
|
||||||
needed_update = False
|
needed_update = False
|
||||||
lib = self.STD_LIB_NAME % name
|
lib = self.STD_LIB_NAME % name
|
||||||
|
@ -712,12 +709,12 @@ class mbedToolchain:
|
||||||
return bin, needed_update
|
return bin, needed_update
|
||||||
|
|
||||||
def default_cmd(self, command):
|
def default_cmd(self, command):
|
||||||
|
self.debug("Command: %s"% ' '.join(command))
|
||||||
_stdout, _stderr, _rc = run_cmd(command)
|
_stdout, _stderr, _rc = run_cmd(command)
|
||||||
# Print all warning / erros from stderr to console output
|
# Print all warning / erros from stderr to console output
|
||||||
for error_line in _stderr.splitlines():
|
for error_line in _stderr.splitlines():
|
||||||
print error_line
|
print error_line
|
||||||
|
|
||||||
self.debug("Command: %s"% ' '.join(command))
|
|
||||||
self.debug("Return: %s"% _rc)
|
self.debug("Return: %s"% _rc)
|
||||||
|
|
||||||
for output_line in _stdout.splitlines():
|
for output_line in _stdout.splitlines():
|
||||||
|
|
|
@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
from os.path import join, dirname, basename
|
from os.path import join, dirname, splitext, basename, exists
|
||||||
|
|
||||||
from tools.toolchains import mbedToolchain
|
from tools.toolchains import mbedToolchain
|
||||||
from tools.settings import ARM_BIN, ARM_INC, ARM_LIB, MY_ARM_CLIB, ARM_CPPLIB, GOANNA_PATH
|
from tools.settings import ARM_BIN, ARM_INC, ARM_LIB, MY_ARM_CLIB, ARM_CPPLIB, GOANNA_PATH
|
||||||
|
@ -78,11 +78,6 @@ class ARM(mbedToolchain):
|
||||||
self.ar = join(ARM_BIN, "armar")
|
self.ar = join(ARM_BIN, "armar")
|
||||||
self.elf2bin = join(ARM_BIN, "fromelf")
|
self.elf2bin = join(ARM_BIN, "fromelf")
|
||||||
|
|
||||||
def remove_option(self, option):
|
|
||||||
for tool in [self.asm, self.cc, self.cppc]:
|
|
||||||
if option in tool:
|
|
||||||
tool.remove(option)
|
|
||||||
|
|
||||||
def parse_dependencies(self, dep_path):
|
def parse_dependencies(self, dep_path):
|
||||||
dependencies = []
|
dependencies = []
|
||||||
for line in open(dep_path).readlines():
|
for line in open(dep_path).readlines():
|
||||||
|
@ -112,9 +107,14 @@ class ARM(mbedToolchain):
|
||||||
match.group('message')
|
match.group('message')
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_dep_opt(self, dep_path):
|
def get_dep_option(self, object):
|
||||||
|
base, _ = splitext(object)
|
||||||
|
dep_path = base + '.d'
|
||||||
return ["--depend", dep_path]
|
return ["--depend", dep_path]
|
||||||
|
|
||||||
|
def get_compile_options(self, defines, includes):
|
||||||
|
return ['-D%s' % d for d in defines] + ['--via', self.get_inc_file(includes)]
|
||||||
|
|
||||||
@hook_tool
|
@hook_tool
|
||||||
def assemble(self, source, object, includes):
|
def assemble(self, source, object, includes):
|
||||||
# Preprocess first, then assemble
|
# Preprocess first, then assemble
|
||||||
|
@ -123,8 +123,8 @@ class ARM(mbedToolchain):
|
||||||
tempfile = join(dir, basename(object) + '.E.s')
|
tempfile = join(dir, basename(object) + '.E.s')
|
||||||
|
|
||||||
# Build preprocess assemble command
|
# Build preprocess assemble command
|
||||||
cmd_pre = self.asm + ['-D%s' % s for s in self.get_symbols() + self.macros] + ["-I%s" % i for i in includes] + ["-E", "-o", tempfile, source]
|
cmd_pre = self.asm + self.get_compile_options(self.get_symbols(), includes) + ["-E", "-o", tempfile, source]
|
||||||
|
|
||||||
# Build main assemble command
|
# Build main assemble command
|
||||||
cmd = self.asm + ["-o", object, tempfile]
|
cmd = self.asm + ["-o", object, tempfile]
|
||||||
|
|
||||||
|
@ -135,6 +135,25 @@ class ARM(mbedToolchain):
|
||||||
# Return command array, don't execute
|
# Return command array, don't execute
|
||||||
return [cmd_pre, cmd]
|
return [cmd_pre, cmd]
|
||||||
|
|
||||||
|
@hook_tool
|
||||||
|
def compile(self, cc, source, object, includes):
|
||||||
|
# Build compile command
|
||||||
|
cmd = cc + self.get_compile_options(self.get_symbols(), includes)
|
||||||
|
|
||||||
|
cmd.extend(self.get_dep_option(object))
|
||||||
|
|
||||||
|
cmd.extend(["-o", object, source])
|
||||||
|
|
||||||
|
# Call cmdline hook
|
||||||
|
cmd = self.hook.get_cmdline_compiler(cmd)
|
||||||
|
|
||||||
|
return [cmd]
|
||||||
|
|
||||||
|
def compile_c(self, source, object, includes):
|
||||||
|
return self.compile(self.cc, source, object, includes)
|
||||||
|
|
||||||
|
def compile_cpp(self, source, object, includes):
|
||||||
|
return self.compile(self.cppc, source, object, includes)
|
||||||
|
|
||||||
@hook_tool
|
@hook_tool
|
||||||
def link(self, output, objects, libraries, lib_dirs, mem_map):
|
def link(self, output, objects, libraries, lib_dirs, mem_map):
|
||||||
|
|
|
@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
from os.path import join, basename, splitext, dirname
|
from os.path import join, basename, splitext, dirname, exists
|
||||||
|
|
||||||
from tools.toolchains import mbedToolchain
|
from tools.toolchains import mbedToolchain
|
||||||
from tools.settings import GCC_ARM_PATH, GCC_CR_PATH
|
from tools.settings import GCC_ARM_PATH, GCC_CR_PATH
|
||||||
|
@ -68,7 +68,7 @@ class GCC(mbedToolchain):
|
||||||
"-Wno-unused-parameter", "-Wno-missing-field-initializers",
|
"-Wno-unused-parameter", "-Wno-missing-field-initializers",
|
||||||
"-fmessage-length=0", "-fno-exceptions", "-fno-builtin",
|
"-fmessage-length=0", "-fno-exceptions", "-fno-builtin",
|
||||||
"-ffunction-sections", "-fdata-sections",
|
"-ffunction-sections", "-fdata-sections",
|
||||||
"-MMD", "-fno-delete-null-pointer-checks", "-fomit-frame-pointer"
|
"-fno-delete-null-pointer-checks", "-fomit-frame-pointer"
|
||||||
] + self.cpu
|
] + self.cpu
|
||||||
|
|
||||||
if "save-asm" in self.options:
|
if "save-asm" in self.options:
|
||||||
|
@ -161,10 +161,18 @@ class GCC(mbedToolchain):
|
||||||
message + match.group('message')
|
message + match.group('message')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_dep_option(self, object):
|
||||||
|
base, _ = splitext(object)
|
||||||
|
dep_path = base + '.d'
|
||||||
|
return ["-MD", "-MF", dep_path]
|
||||||
|
|
||||||
|
def get_compile_options(self, defines, includes):
|
||||||
|
return ['-D%s' % d for d in defines] + ['@%s' % self.get_inc_file(includes)]
|
||||||
|
|
||||||
@hook_tool
|
@hook_tool
|
||||||
def assemble(self, source, object, includes):
|
def assemble(self, source, object, includes):
|
||||||
# Build assemble command
|
# Build assemble command
|
||||||
cmd = self.asm + ['-D%s' % s for s in self.get_symbols() + self.macros] + ["-I%s" % i for i in includes] + ["-o", object, source]
|
cmd = self.asm + self.get_compile_options(self.get_symbols(), includes) + ["-o", object, source]
|
||||||
|
|
||||||
# Call cmdline hook
|
# Call cmdline hook
|
||||||
cmd = self.hook.get_cmdline_assembler(cmd)
|
cmd = self.hook.get_cmdline_assembler(cmd)
|
||||||
|
@ -172,6 +180,26 @@ class GCC(mbedToolchain):
|
||||||
# Return command array, don't execute
|
# Return command array, don't execute
|
||||||
return [cmd]
|
return [cmd]
|
||||||
|
|
||||||
|
@hook_tool
|
||||||
|
def compile(self, cc, source, object, includes):
|
||||||
|
# Build compile command
|
||||||
|
cmd = cc + self.get_compile_options(self.get_symbols(), includes)
|
||||||
|
|
||||||
|
cmd.extend(self.get_dep_option(object))
|
||||||
|
|
||||||
|
cmd.extend(["-o", object, source])
|
||||||
|
|
||||||
|
# Call cmdline hook
|
||||||
|
cmd = self.hook.get_cmdline_compiler(cmd)
|
||||||
|
|
||||||
|
return [cmd]
|
||||||
|
|
||||||
|
def compile_c(self, source, object, includes):
|
||||||
|
return self.compile(self.cc, source, object, includes)
|
||||||
|
|
||||||
|
def compile_cpp(self, source, object, includes):
|
||||||
|
return self.compile(self.cppc, source, object, includes)
|
||||||
|
|
||||||
@hook_tool
|
@hook_tool
|
||||||
def link(self, output, objects, libraries, lib_dirs, mem_map):
|
def link(self, output, objects, libraries, lib_dirs, mem_map):
|
||||||
libs = []
|
libs = []
|
||||||
|
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
from os import remove
|
from os import remove
|
||||||
from os.path import join, exists, dirname
|
from os.path import join, exists, dirname, splitext, exists
|
||||||
|
|
||||||
from tools.toolchains import mbedToolchain
|
from tools.toolchains import mbedToolchain
|
||||||
from tools.settings import IAR_PATH
|
from tools.settings import IAR_PATH
|
||||||
|
@ -72,6 +72,10 @@ class IAR(mbedToolchain):
|
||||||
self.ar = join(IAR_BIN, "iarchive")
|
self.ar = join(IAR_BIN, "iarchive")
|
||||||
self.elf2bin = join(IAR_BIN, "ielftool")
|
self.elf2bin = join(IAR_BIN, "ielftool")
|
||||||
|
|
||||||
|
def parse_dependencies(self, dep_path):
|
||||||
|
return [path.strip() for path in open(dep_path).readlines()
|
||||||
|
if (path and not path.isspace())]
|
||||||
|
|
||||||
def parse_output(self, output):
|
def parse_output(self, output):
|
||||||
for line in output.splitlines():
|
for line in output.splitlines():
|
||||||
match = IAR.DIAGNOSTIC_PATTERN.match(line)
|
match = IAR.DIAGNOSTIC_PATTERN.match(line)
|
||||||
|
@ -93,20 +97,22 @@ class IAR(mbedToolchain):
|
||||||
match.group('message')
|
match.group('message')
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_dep_opt(self, dep_path):
|
def get_dep_option(self, object):
|
||||||
|
base, _ = splitext(object)
|
||||||
|
dep_path = base + '.d'
|
||||||
return ["--dependencies", dep_path]
|
return ["--dependencies", dep_path]
|
||||||
|
|
||||||
def cc_extra(self, base):
|
def cc_extra(self, object):
|
||||||
|
base, _ = splitext(object)
|
||||||
return ["-l", base + '.s']
|
return ["-l", base + '.s']
|
||||||
|
|
||||||
def parse_dependencies(self, dep_path):
|
def get_compile_options(self, defines, includes):
|
||||||
return [path.strip() for path in open(dep_path).readlines()
|
return ['-D%s' % d for d in defines] + ['-f', self.get_inc_file(includes)]
|
||||||
if (path and not path.isspace())]
|
|
||||||
|
|
||||||
@hook_tool
|
@hook_tool
|
||||||
def assemble(self, source, object, includes):
|
def assemble(self, source, object, includes):
|
||||||
# Build assemble command
|
# Build assemble command
|
||||||
cmd = self.asm + ['-D%s' % s for s in self.get_symbols() + self.macros] + ["-I%s" % i for i in includes] + ["-o", object, source]
|
cmd = self.asm + self.get_compile_options(self.get_symbols(), includes) + ["-o", object, source]
|
||||||
|
|
||||||
# Call cmdline hook
|
# Call cmdline hook
|
||||||
cmd = self.hook.get_cmdline_assembler(cmd)
|
cmd = self.hook.get_cmdline_assembler(cmd)
|
||||||
|
@ -114,6 +120,28 @@ class IAR(mbedToolchain):
|
||||||
# Return command array, don't execute
|
# Return command array, don't execute
|
||||||
return [cmd]
|
return [cmd]
|
||||||
|
|
||||||
|
@hook_tool
|
||||||
|
def compile(self, cc, source, object, includes):
|
||||||
|
# Build compile command
|
||||||
|
cmd = cc + self.get_compile_options(self.get_symbols(), includes)
|
||||||
|
|
||||||
|
cmd.extend(self.get_dep_option(object))
|
||||||
|
|
||||||
|
cmd.extend(self.cc_extra(object))
|
||||||
|
|
||||||
|
cmd.extend(["-o", object, source])
|
||||||
|
|
||||||
|
# Call cmdline hook
|
||||||
|
cmd = self.hook.get_cmdline_compiler(cmd)
|
||||||
|
|
||||||
|
return [cmd]
|
||||||
|
|
||||||
|
def compile_c(self, source, object, includes):
|
||||||
|
return self.compile(self.cc, source, object, includes)
|
||||||
|
|
||||||
|
def compile_cpp(self, source, object, includes):
|
||||||
|
return self.compile(self.cppc, source, object, includes)
|
||||||
|
|
||||||
@hook_tool
|
@hook_tool
|
||||||
def link(self, output, objects, libraries, lib_dirs, mem_map):
|
def link(self, output, objects, libraries, lib_dirs, mem_map):
|
||||||
# Build linker command
|
# Build linker command
|
||||||
|
|
|
@ -34,8 +34,12 @@ def cmd(l, check=True, verbose=False, shell=False, cwd=None):
|
||||||
|
|
||||||
def run_cmd(command, wd=None, redirect=False):
|
def run_cmd(command, wd=None, redirect=False):
|
||||||
assert is_cmd_valid(command[0])
|
assert is_cmd_valid(command[0])
|
||||||
p = Popen(command, stdout=PIPE, stderr=STDOUT if redirect else PIPE, cwd=wd)
|
try:
|
||||||
_stdout, _stderr = p.communicate()
|
p = Popen(command, stdout=PIPE, stderr=STDOUT if redirect else PIPE, cwd=wd)
|
||||||
|
_stdout, _stderr = p.communicate()
|
||||||
|
except:
|
||||||
|
print "[OS ERROR] Command: "+(' '.join(command))
|
||||||
|
raise
|
||||||
return _stdout, _stderr, p.returncode
|
return _stdout, _stderr, p.returncode
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue