diff --git a/tools/build_api.py b/tools/build_api.py
index f125edb53f3..86de024da9d 100644
--- a/tools/build_api.py
+++ b/tools/build_api.py
@@ -232,8 +232,8 @@ def build_project(src_path, build_path, target, toolchain_name,
             prev_features = features
         config.validate_config()
 
-        # And add the configuration macros to the toolchain
-        toolchain.add_macros(config.get_config_data_macros())
+        # Set the toolchain's config header with the config data
+        toolchain.set_config_header_content(config.get_config_data_header())
 
         # Compile Sources
         for path in src_paths:
@@ -403,8 +403,8 @@ def build_library(src_paths, build_path, target, toolchain_name,
             prev_features = features
         config.validate_config()
 
-        # And add the configuration macros to the toolchain
-        toolchain.add_macros(config.get_config_data_macros())
+        # Set the toolchain's config header with the config data
+        toolchain.set_config_header_content(config.get_config_data_header())
 
         # Compile Sources
         for path in src_paths:
diff --git a/tools/config.py b/tools/config.py
index c95b0206c75..9e1364d5e07 100644
--- a/tools/config.py
+++ b/tools/config.py
@@ -132,8 +132,10 @@ def __init__(self, name, unit_name, unit_kind):
             if len(tmp) != 2:
                 raise ValueError("Invalid macro definition '%s' in '%s'" % (name, self.defined_by))
             self.macro_name = tmp[0]
+            self.macro_value = tmp[1]
         else:
             self.macro_name = name
+            self.macro_value = None
 
 # 'Config' implements the mbed configuration mechanism
 class Config:
@@ -343,13 +345,13 @@ def get_app_config_data(self, params, macros):
 
     # Return the configuration data in two parts:
     #   - params: a dictionary with (name, ConfigParam) entries
-    #   - macros: the list of macros defined with "macros" in libraries and in the application
+    #   - macros: the list of macros defined with "macros" in libraries and in the application (as ConfigMacro instances)
     def get_config_data(self):
         all_params = self.get_target_config_data()
         lib_params, macros = self.get_lib_config_data()
         all_params.update(lib_params)
         self.get_app_config_data(all_params, macros)
-        return all_params, [m.name for m in macros.values()]
+        return all_params, macros
 
     # Helper: verify if there are any required parameters without a value in 'params'
     def _check_required_parameters(self, params):
@@ -363,11 +365,17 @@ def _check_required_parameters(self, params):
     def parameters_to_macros(params):
         return ['%s=%s' % (m.macro_name, m.value) for m in params.values() if m.value is not None]
 
+    # Return the macro definitions generated for a dictionary of ConfigMacros (as returned by get_config_data)
+    # params: a dictionary of (name, ConfigMacro instance) mappings
+    @staticmethod
+    def config_macros_to_macros(macros):
+        return [m.name for m in macros.values()]
+
     # Return the configuration data converted to a list of C macros
     def get_config_data_macros(self):
         params, macros = self.get_config_data()
         self._check_required_parameters(params)
-        return macros + self.parameters_to_macros(params)
+        return self.config_macros_to_macros(macros) + self.parameters_to_macros(params)
 
     # Returns any features in the configuration data
     def get_features(self):
@@ -387,4 +395,43 @@ def validate_config(self):
         if self.config_errors:
             raise self.config_errors[0]
         return True
-        
+
+    # Return the configuration data converted to the content of a C header file,
+    # meant to be included to a C/C++ file. The content is returned as a string.
+    # If 'fname' is given, the content is also written to the file called "fname".
+    # WARNING: if 'fname' names an existing file, that file will be overwritten!
+    def get_config_data_header(self, fname = None):
+        params, macros = self.get_config_data()
+        self._check_required_parameters(params)
+        header_data =  "// Automatically generated configuration file.\n"
+        header_data += "// DO NOT EDIT, content will be overwritten.\n\n"
+        header_data += "#ifndef __MBED_CONFIG_DATA__\n"
+        header_data += "#define __MBED_CONFIG_DATA__\n\n"
+        # Compute maximum length of macro names for proper alignment
+        max_param_macro_name_len = max([len(m.macro_name) for m in params.values() if m.value is not None]) if params else 0
+        max_direct_macro_name_len = max([len(m.macro_name) for m in macros.values()]) if macros else 0
+        max_macro_name_len = max(max_param_macro_name_len, max_direct_macro_name_len)
+        # Compute maximum length of macro values for proper alignment
+        max_param_macro_val_len = max([len(str(m.value)) for m in params.values() if m.value is not None]) if params else 0
+        max_direct_macro_val_len = max([len(m.macro_value or "") for m in macros.values()]) if macros else 0
+        max_macro_val_len = max(max_param_macro_val_len, max_direct_macro_val_len)
+        # Generate config parameters first
+        if params:
+            header_data += "// Configuration parameters\n"
+            for m in params.values():
+                if m.value is not None:
+                    header_data += "#define {0:<{1}} {2!s:<{3}} // set by {4}\n".format(m.macro_name, max_macro_name_len, m.value, max_macro_val_len, m.set_by)
+        # Then macros
+        if macros:
+            header_data += "// Macros\n"
+            for m in macros.values():
+                if m.macro_value:
+                    header_data += "#define {0:<{1}} {2!s:<{3}} // defined by {4}\n".format(m.macro_name, max_macro_name_len, m.macro_value, max_macro_val_len, m.defined_by)
+                else:
+                    header_data += "#define {0:<{1}} // defined by {2}\n".format(m.macro_name, max_macro_name_len + max_macro_val_len + 1, m.defined_by)
+        header_data += "\n#endif\n"
+        # If fname is given, write "header_data" to it
+        if fname:
+            with open(fname, "wt") as f:
+                f.write(header_data)
+        return header_data
diff --git a/tools/get_config.py b/tools/get_config.py
index 6d8af838176..9d9e7dc5fa2 100644
--- a/tools/get_config.py
+++ b/tools/get_config.py
@@ -62,7 +62,7 @@
     options.prefix = options.prefix or [""]
 
     try:
-        params, macros = get_config(options.source_dir, target, toolchain)
+        params, macros, features = get_config(options.source_dir, target, toolchain)
         if not params and not macros:
             print "No configuration data available."
             _exit(0)
@@ -79,7 +79,7 @@
         print "Macros"
         print "------"
         if macros:
-            print 'Defined with "macros":', macros
+            print 'Defined with "macros":', Config.config_macros_to_macros(macros)
         print "Generated from configuration parameters:", Config.parameters_to_macros(params)
 
     except KeyboardInterrupt, e:
diff --git a/tools/test/config_test/config_test.py b/tools/test/config_test/config_test.py
index a0e5eab8ff9..59c2b50c98d 100644
--- a/tools/test/config_test/config_test.py
+++ b/tools/test/config_test/config_test.py
@@ -16,7 +16,7 @@
 """
 
 from tools.build_api import get_config
-from tools.config import ConfigException
+from tools.config import ConfigException, Config
 import os, sys
 
 # Compare the output of config against a dictionary of known good results
@@ -44,6 +44,7 @@ def test_tree(full_name, name):
         err_msg = None
         try:
             cfg, macros, features = get_config(full_name, target, "GCC_ARM")
+            macros = Config.config_macros_to_macros(macros)
         except ConfigException as e:
             err_msg = e.message
         if err_msg:
diff --git a/tools/toolchains/__init__.py b/tools/toolchains/__init__.py
index 043acaa2798..28e2f170a95 100644
--- a/tools/toolchains/__init__.py
+++ b/tools/toolchains/__init__.py
@@ -265,6 +265,9 @@ def __init__(self, target, options=None, notify=None, macros=None, silent=False,
             
         self.flags = deepcopy(self.DEFAULT_FLAGS)
 
+        # config_header_content will hold the content of the config header (if used)
+        self.config_header_content = None
+
     def get_output(self):
         return self.output
 
@@ -867,6 +870,26 @@ def mem_stats(self, map):
         map_csv = splitext(map)[0] + "_map.csv"
         memap.generate_output('csv-ci', map_csv)
 
+    # "Prefix headers" are automatically included by the compiler at the beginning of
+    # each source file. They are used to provide configuration data.
+    # header_content - the content of the config header file.
+    def set_config_header_content(self, header_content):
+        self.config_header_content = header_content
+
+    # Return the location of the config header. This function will create the config
+    # header first if needed. The header will be written in a file called "mbed_conf.h"
+    # located in the project's build directory.
+    # If config headers are not used (self.config_header_content is None), the function
+    # returns None
+    def get_config_header(self):
+        if self.config_header_content is None:
+            return None
+        config_file = join(self.build_dir, "mbed_conf.h")
+        if not exists(config_file):
+            with open(config_file, "wt") as f:
+                f.write(self.config_header_content)
+        return config_file
+
 
 from tools.settings import ARM_BIN
 from tools.settings import GCC_ARM_PATH, GCC_CR_PATH
diff --git a/tools/toolchains/arm.py b/tools/toolchains/arm.py
index f58a20b0179..deff6cf9fd3 100644
--- a/tools/toolchains/arm.py
+++ b/tools/toolchains/arm.py
@@ -115,7 +115,11 @@ def get_dep_option(self, object):
         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)]
+        opts = ['-D%s' % d for d in defines] + ['--via', self.get_inc_file(includes)]
+        config_header = self.get_config_header()
+        if config_header is not None:
+            opts = opts + ['--preinclude', config_header]
+        return opts
 
     @hook_tool
     def assemble(self, source, object, includes):
diff --git a/tools/toolchains/gcc.py b/tools/toolchains/gcc.py
index 3d0f9b5095a..dc10c13d8c8 100644
--- a/tools/toolchains/gcc.py
+++ b/tools/toolchains/gcc.py
@@ -166,7 +166,11 @@ def get_dep_option(self, object):
         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)]
+        opts = ['-D%s' % d for d in defines] + ['@%s' % self.get_inc_file(includes)]
+        config_header = self.get_config_header()
+        if config_header is not None:
+            opts = opts + ['-include', config_header]
+        return opts
 
     @hook_tool
     def assemble(self, source, object, includes):
diff --git a/tools/toolchains/iar.py b/tools/toolchains/iar.py
index aac31bc49df..72f94a826cb 100644
--- a/tools/toolchains/iar.py
+++ b/tools/toolchains/iar.py
@@ -119,7 +119,11 @@ def cc_extra(self, object):
         return ["-l", base + '.s.txt']
 
     def get_compile_options(self, defines, includes):
-        return ['-D%s' % d for d in defines] + ['-f', self.get_inc_file(includes)]
+        opts = ['-D%s' % d for d in defines] + ['-f', self.get_inc_file(includes)]
+        config_header = self.get_config_header()
+        if config_header is not None:
+            opts = opts + ['--preinclude', config_header]
+        return opts
 
     @hook_tool
     def assemble(self, source, object, includes):