Thanks Chris,

I think this is a great step in the right direction. I¹m looking forward
to seeing it.

Just a few quick questions/comments about sysinit.

Would you expect that everyone that writes a new core package, would add
their init code to sys/sysinit package and include their package in the
dependencies for sys/sysinit?  Would that mean that if I include
sys/sysinit as a dependency in my app (every app probably would), it
automatically becomes dependent on all packages, or would this be special
somehow and not be necessary.

Does it make sense to have the sysinit.yml file include the "init method
name² for the package and have newt build that sysintit.c file special for
your target?  This has the advantage that we are not coupling these
projects together or using tons of ifdefs which make the code hard to read
(its hard to teach my idea about defines that newt creates). It raises the
issue of order though since we can¹t enforce an order if its generated
like this. We would also have to make these a fixed prototype to make it
easy (I think it would be easy to make the int foo(void)).


Would non-core packages put their init code in sys/sysinit?  Or is this
just for os-core stuff?

My preference is to put some thought into the yml file format for future.
We¹ve got tons of packages and its may be a pain to make a drastic change
later.  We don¹t need to add the features now, just make sure the yml file
has the hierarchy to support the things we are thinking about now.

Paul

On 8/29/16, 4:53 PM, "marko kiiskila" <[email protected]> wrote:

>Hi,
>
>for bootloader I¹d like to have different set of devices than the app.
>What did you have in mind for that? Different bsp_init() routines?
>Or would bsp_init() have conditional parts depending on syscfg.h says?
>
>> On Aug 29, 2016, at 2:23 PM, Christopher Collins <[email protected]>
>>wrote:
>> 
>> Hello all,
>> 
>> This will be a long email about changes to the way Mynewt performs
>>system
>> initialization.  Any and all feedback is greatly appreciated.
>> 
>> Proposal:
>>    1. Move system initialization out of apps and into BSPs and
>>       system-level packages.
>>    2. Specify system settings in config file.
>> 
>> Motivations:
>>    1. Simplify process of creating an app (no more boilerplate code).
>>    2. Simplify system configuration (don't specify config within C
>>       code).
>>    3. Better code organization; cputime, msys, etc. "feel" more like
>>       system-level modules than application-level, so put
>>       initialization code where it belongs.
>> 
>> Examples of "system modules" are:
>>    * mbufs / msys.
>>    * Network stacks (e.g., NimBLE host, controller, and HCI transport).
>>    * newtmgr
>>    * console
>>    * logging
>>    * drivers
>> 
>> The biggest challenge is: ensuring the developer maintains precise
>> control over the system configuration.  The current Mynewt scheme gives
>> control to the developer by pushing configuration up to the application
>> level where he is forced to deal with it.
>> 
>> ### Proposal Summary
>> 
>> System initialization happens in two stages:
>>    1. BSP init (bsp_init())
>>    2. sysinit (sysinit())
>> 
>> (1) BSP init sets up everything that is BSP specific:
>>    * UARTs
>>    * Flash map
>>    * Other hardware drivers
>> 
>> (2) Sysinit sets up all the libraries which aren't BSP or hardware
>> dependent (os, msys, network stacks, etc).  Sysinit is implemented in
>> the sys/sysinit package.
>> 
>> The system knows what to initialize and how to initialize it based on
>> the contents of the following header file:
>> 
>>    <target-path>/include/syscfg/syscfg.h
>> 
>> For example:
>> 
>>    targets/bleprph-nrf52dk/include/syscfg/syscfg.h
>> 
>> This header file is generated by newt during the build process.  Newt
>> arranges for all packages to have access to this header file.
>> 
>> The syscfg.h header file consists of three sections:
>>    * Settings
>>    * Indication of which packages are present
>>    * Indication of which APIs are available
>> 
>> Here is an excerpt from a sample syscfg.h file (the actual file is much
>> larger):
>> 
>>    /*** Settings */
>> 
>>    #ifndef MYNEWT_CLOCK_FREQ
>>    #define MYNEWT_CLOCK_FREQ (1000000)
>>    #endif
>> 
>>    #ifndef MYNEWT_MSYS_1_BLOCK_COUNT
>>    #define MYNEWT_MSYS_1_BLOCK_COUNT (15)
>>    #endif
>> 
>>    #ifndef MYNEWT_MSYS_1_BLOCK_SIZE
>>    #define MYNEWT_MSYS_1_BLOCK_SIZE (260)
>>    #endif
>> 
>>    /*** Packages */
>> 
>>    #ifndef MYNEWT_PKG_LIBS_NEWTMGR
>>    #define MYNEWT_PKG_LIBS_NEWTMGR (1)
>>    #endif
>> 
>>    #ifndef MYNEWT_PKG_LIBS_NEWTMGR_TRANSPORT_BLE
>>    #define MYNEWT_PKG_LIBS_NEWTMGR_TRANSPORT_BLE (1)
>>    #endif
>> 
>>    #ifndef MYNEWT_PKG_SYS_CONFIG
>>    #define MYNEWT_PKG_SYS_CONFIG (1)
>>    #endif
>> 
>>    /*** APIs */
>> 
>>    #ifndef MYNEWT_API_BLE_DRIVER
>>    #define MYNEWT_API_BLE_DRIVER (1)
>>    #endif
>> 
>>    #ifndef MYNEWT_API_BLE_TRANSPORT
>>    #define MYNEWT_API_BLE_TRANSPORT (1)
>>    #endif
>> 
>>    #ifndef MYNEWT_API_CONSOLE
>>    #define MYNEWT_API_CONSOLE (1)
>>    #endif
>> 
>> 
>> ### Syscfg header file generation
>> 
>> Newt generates the syscfg.h file by parsing a series of "syscfg.yml"
>> files.  Any package may contain a syscfg.yml file in its directory.
>> A syscfg.yml file defining the three settings shown above might look
>> like this:
>> 
>>    MYNEWT_CLOCK_FREQ:          1000000
>>    MYNEWT_MSYS_1_BLOCK_COUNT:  12
>>    MYNEWT_MSYS_1_BLOCK_SIZE:   260
>> 
>> If several packages define the same setting, the tie is broken according
>> to package priority.  Packages are prioritized as follows (lowest
>> priority first, highest last):
>> 
>>    1. Library
>>    2. BSP
>>    3. App
>>    4. Target
>> 
>> The expectation is that libraries would define sensible defaults in
>> their syscfg.yml files, and BSPs, apps, and targets would override those
>> defaults.
>> 
>> To prevent unnecessary rebuilds, newt only overwrites the header file if
>> there are any configuration changes since the previous build.
>> 
>> ### newt target config command
>> 
>> Newt would have a new command: newt target config <target-name>.  This
>> command shows the following information about each setting for the
>> specified target:
>> 
>>    * Default value and package which specifies it.
>>    * Actual value and package which specifies it.
>> 
>> ### System init C code
>> 
>> The system init code conditionally initializes modules in sequence.
>> Here is an example of how this might look:
>> 
>>    #if MYNEWT_PKG_SYS_ID
>>        id_init();
>>    #endif
>> 
>>    #if MYNEWT_API_CONSOLE
>>        rc = console_init(NULL);
>>        assert(rc == 0);
>>    #endif
>> 
>>    #ifdef MYNEWT_REBOOT_LOG_0_TYPE
>>        reboot_init_handler(MYNEWT_REBOOT_LOG_0_TYPE,
>>                            MYNEWT_REBOOT_LOG_0_ENTRY_COUNT);
>>    #endif
>> 
>>    #if MYNEWT_PKG_LIBS_SHELL
>>        shell_task_init();
>>    #endif
>> 
>> Each module's init function (e.g., shell_task_init()) also reads the
>> syscfg.h header to know how to configure the module.
>> 
>> ### Questions / issues
>> 
>> Here are some issues that I'm struggling with:
>> 
>> 1. Settings lack structure.
>> 
>> Do the syscfg.yml files need more information?  Ideally (in my opinion),
>> each setting would be defined by its package with the following
>> information:
>>    * Name
>>    * Default value
>>    * Description
>>    * Restrictions
>> 
>> By "restrictions", I mean prerequisites for enabling a particular
>> setting.  For example, it is illegal to configure the config module to
>> use nffs if the fs/nffs package is not pulled into the build.  It would
>> be nice if newt could catch this configuration error with a helpful
>> message rather than letting the compiler and linker generate
>> incomprehensible errors.
>> 
>> Thinking about this "richer" syscfg format is what got me worrying that
>> this feature may be getting way too complicated.  Even though it might
>> be messy to change the syscfg format in the future, I don't think it is
>> a good idea to try to implement the super-complicated option for 1.0.
>> 
>> 2. Default task priorities.
>> 
>> A package's default settings reside in the package's syscfg.yml file.
>> Among these settings is default task priority.  I don't think it is
>> possible to assign meaningful default priorities.  I see two options:
>> 
>>    * Don't specify default priorities.  Force the user to specify all
>>      priorities in the bsp/app/target syscfg.yml file.
>> 
>>    * Allow an "any" priority value to be specified.  While generating
>>      the syscfg.h file, newt would assign unused values to priorities
>>      marked as "any".  Tasks with strict timing requirements (e.g., the
>>      nimble controller) would specify actual values.  Other tasks
>>      (e.g., shell) would use "any".
>> 
>> I think the second option is better, but requires more work.
>> 
>> 3. General flash map problems.
>> 
>> Currently it is assumed that all parts of a BSP (C code, linker script,
>> and bash scripts) have the same flash map definition.  It would be nice
>> if the flash map could be specified once in a single place.
>> 
>> Another problem concerns initialization of some flash-dependent
>> packages.  For example, if the sys/config package is configured to use
>> FCB, something needs to indicate where in flash the FCB goes.  With the
>> flash map definition living in C code, is not really feasible to specify
>> this in the system configuration yaml files.
>> 
>> Even though I see this as a problem, I am OK with keeping flash-specific
>> stuff in BSP C code for now.
>> 
>> Thanks,
>> Chris
>

Reply via email to