Date   

Re: RFC[1/2] Common logging infrastructure and API

Nashif, Anas
 

Hi,




On 24/02/2016, 17:13, "Saucedo Tejada, Genaro" <genaro.saucedo.tejada(a)intel.com> wrote:

Hello, please review this proposal and provide feedback if possible.
This email should be followed by a patch containing a prototype
implementation for reference but not meant to be applied.

Background:

Currently several files declare their own logging infrastructure and
sometimes even in the same way, effectively duplicating code, there is
no common logger header or a single interface for logging, this
situation also complicates enhancement of logging functionality.

We want to concentrate logging functionality at a single point to ease
configuration and enhancement while retaining (and reusing) all
existing logging features when decided by developers.

Additional features are proposed anticipating possibly desired
functionality.
This is a much needed enhancement, thanks for making this proposal.



Proposal to implement new logging API:

Create a new header file at include directory, remove all logger macro
definition from .c files and have a single, compatible definition on
the new header. On each .c file that requires logging include the new
header and specify feature/file specific values, such as logging domain
(if any) and per-feature logging switch (view number 2.1 below).

The retained features surveyed on existing implementations of logging
are:

1. Make based identification of output appender, these currently being
stdio printf when console is available and printk as fall back.

2. Optional macro expansion, controlled by Kconfig files and make
menuconfig command. Disabling this helps saving memory on production
when logging is not needed.

2.1. Fine grain per-feature log activation. Allows enabling log at
specific parts of the code on menuconfig.

3. Multilevel log formatting.

3.1 Colored log, when console is active it helps differentiate three
existing log levels. currently in use only on Bluetooth files.

4. Caller thread printing, currently Bluetooth files print the current
thread pointer.

5. Caller function printing, some logging macros print the function
that called them.

All above features are kept by this proposal and most become
configurable. The following new ones are added:

6. Labeled log, helps differentiate log levels by using a tag, useful
if color is not available.

7. Incremental per-level log activation. Orthogonal to existing per-
feature filter, this filter allows to set one logging level out of:
INFO, ERROR, WARNING and DEBUG. The higher the level the more verbose
the log becomes. Also as levels are hidden by preprocessor decreasing
level also helps reducing footprint. This is set at menuconfig as well.
We need to make sure we support logging for more than debugging and during development. In most cases logging will be used during development to assist with debugging and printing information on the console, however, we need to make sure this design also addresses cases where logging is part of the application, for example you might want to write to a file-system, send messages to a remote endpoint or write messages to a connected display. This basically means we also need to support different backends, the most immediate and straightforward backend would be printing to the console using printk and printf.

An application should be able to configure the domains and levels it wants to log, for example, if I am debugging an issue with I2C and I am only interested in I2C, I want to be able to select this domain and the logging level, so for example:

the defaults:
CONFIG_LOG=y
CONFIG_LOG_BACKEND=“printk”
CONFIG_LOG_DOMAINS=“*”

CONFIG_LOG_LEVEL=“INFO”


would enable logging (INFO) for everything using printk

For the case above I would change the following in my application .config:

CONFIG_LOG_DOMAINS=“I2C”
CONFIG_LOG_LEVEL=“DEBUG”






Design decisions and rationale:

It was decided to implement this API preferring macros instead of run-
time functions (except for thread retrieval) in an attempt to minimize
overhead introduced by logging.

Also, within this macro implementation, two extreme sides can be
discerned, these are concatenate compile time values with preprocessor
## versus using printf format arguments (%s). Preferring formatting
slightly impacts run-time overhead while preferring preprocessor
concatenation produces longer strings that duplicate substrings. In
this case none of the extremes was reached, instead something closer to
formatting was picked seeking to keep the prototype code simpler. Final
patch can be tuned likewise or one of the two extreme approaches can be
taken.

Implementation details:

The patch following this email is meant as proof-of-concept prototype.
It might compile but has not been thoughtfully tested and it only
covers Bluetooth and lcd_rgb.c files.

In this example path configuration is done through menuconfig, new
options need to be enabled in addition to existing ones, for modified
files CONFIG_BLUETOOTH_CONN, CONFIG_BLUETOOTH_DEBUG,
CONFIG_BLUETOOTH_DEBUG_HCI_CORE and CONFIG_GROVE_DEBUG.

A "logging domain" can be specified, it helps filter a log output in
case several features are enabled, domain is specified by:
LOG_DMN: short for log domain.

Example:
#define LOG_DMN "bt"
Just use LOG_DOMAIN, no need to abbreviate this



The macros at logging.h get enabled by two definitions:
CONFIG_USE_COMPILE_LOG: This is the global Kconfig switch for logging.
Keep it simple, CONFIG_LOG, the COMPILE wording can be misleading, In Kconfig we compile almost everything that is enabled, i.e. y means USE_COMPILE...


LOG_THIS_MODULE: This is an additional switch intended to bridge the
generic definitions on the header to a feature-specific logging switch
from Kconfig.

Example usage of LOG_THIS_MODULE:
#define LOG_THIS_MODULE CONFIG_BLUETOOTH_DEBUG_HCI_CORE
#include <logging.h>
I think this is were things will get confusing, we do need to change all of those existing DEBUG variables and make them work with the new model instead of keeping them in the code. See my example above, using the right domains and level, the same will be achieved.



That way logging.h will know that if CONFIG_BLUETOOTH_DEBUG_HCI_CORE
was not set by menuconfig it should not log at all (at current
compilation unit).

This requires an additional line to be included by files that use
logging but could be made optional, doing so requires deciding default
behavior between having unfiltered features (on 2.1 filter mentioned
above) or allowing developer to included logging.h file with no effect.
On current prototype this line requirement is enforced by #error
directive.

Future work:

* Final patch needs to unify system wide the macro naming and such
naming should be less likely to collide.
* An alternative run-time implementation could be later developed to
provide more features.
* Compare footprint between different degrees of ## usage over printf
format.

We should implement backends and clean up all the custom DEBUG usage in Kconfig and move everything to the new model reducing complexity and making things more consistent.

Please make sure we have a JIRA story to track this and add the final proposal to that JIRA once we have reached consensus.

Anas



Example macro expansions:

printf("" "%s%s\t%p: %s" "Grove LCD: background set to white\n" "%s\n",
"DBG ", __func__, sys_thread_self_get(), "", "");
(messages were left unchaged so domain is still repeated as part of the
message)
printf("bt" ":\t" "%s%s\t%p: %s" "Unable to allocate new HCI command"
"%s\n", "", __func__, sys_thread_self_get(), "\x1B[0;31m", "\x1B[0m");
(domain is defined through macro, color and thread are in use)
printf("bt" ":\t" "%s%s\t: %s" "No HCI driver registered" "%s\n", "",
__func__, "\x1B[0;31m", "\x1B[0m");
(same but without thread)


Re: STM32F103x port

Maciek Borzecki <maciek.borzecki@...>
 

Hi list,

It has been a slow weekend, as part of my self-doubt recovery after a
bad Codility experience I've started writing drivers for RCC, UART and
pinmux for STM32F10x chips. The changes are pushed to
bboozzoo/stm32f103-next branch here:
https://github.com/bboozzoo/zephyr/tree/bboozzoo/stm32f103-next/ Beware,
I'm treating this branch as a backup of my local work, so there might be
force pushes from time to time.

The demo code has been archived in bboozzoo/stm32f103-demo branch.

Once I deem the work somewhat feature complete, I'll clean that up and
push for review. I'd be glad if someone took a look at the code and
shared their opinion on whether the path I took seems reasonable.

I think there might be some room for extending clock control driver
API. The problem comes form the fact that some chips may a more
elaborate clock distribution within the SoC itself. For instance, inside
the STM32F103x chip, there are at least 2 clock domains driving the
peripherals (low speed clock PCLK1 and high speed PCLK2). When setting
up UARTx baud rate one needs to know the clock rate in order to
calculate the timings for the peripheral. Also, on this particular chip
USART1 is driven by PCLK2, while the remaining for UARTx are driven by
PLCK1. Finding out the rate of the clock driving particular peripheral
is useful if we want to keep things generic to some extent.

I've added the following call to driver specific part of the API:

void stm32f10x_clock_control_get_subsys_rate(struct device *clock,
clock_control_subsys_t subsys,
uint32_t *rate);

where `subsys` is the regular clock subsystem and the clock rate is returned
in `*rate` field.

Since this might be a more general problem, I think the functionality
can be added to the clock_control API:

typedef void (*clock_control_get_clock)(struct device *dev,
clock_control_subsys_t sys,
uint32_t *rate);

struct clock_control_driver_api {
...
clock_control_get_clock get_clock;
}

As for the drivers. The RCC (Reset & Clock Control) driver mostly
delivers the CC part of the name. I have intentionally specified a low
priority (1) in DEVICE_INIT() call. The RCC has to be initialized early
in the startup process, otherwise no peripherals will work.

RCC subsytem mapping enums have been put in driver specific header. I
did not feel like these belonged to the SoC specific part as the mappings
are shared by the whole family of SoCs.

The pinmux driver contains only the parts essential for getting the UART
to work. Again, this is not part of the board specific code, neither the
SoC specific one, as the driver is shared by a family of MCUs. I have
looked at the pinmux driver for Galileo and I understand the the API has
been shaped having this board in mind. While the API methods are
sufficient, I have only implemented the *_get() and *_set() calls. The
pin config on STM32F10x is a bit elaborate so I reused the `func`
parameter in *_get()/*_set() calls to pass driver specific function
mappings. The function mapping names are currently shaped after
pinconf-generic Linux driver. Perhaps I'm being too pragmatic here, but
I'd like to avoid replication of STM32Cube's functionality and typing in
all possible pin mappings.

The UART driver is still using polling, however drive init has been
reworked to use the pinmux and clock_control APIs. The baud rate is not
hardcoded anymore and is calculated based on configuration. The fixed
point arithmetic should be correct for low speeds and close enough for
higher speeds.

Depending the amount of Yocto/OE work things might be a bit slower next
week, but I'll do some testing and push updates when
possible. Eventually I'd like to hook up a BMP180 pressure sensor over
I2C and get that working.

Cheers,
--
Maciek Borzecki


[RFC] Docker-based development environment for Windows

LeMay, Michael <michael.lemay@...>
 

Problem: Setting up a Zephyr development environment on Microsoft Windows involves many steps.

Proposal: Use Docker to automate the setup procedure.

Docker Toolbox (https://www.docker.com/products/docker-toolbox) can be installed on Windows. It automates the installation of a VMM and a Linux VM suitable for running Docker containers. It also installs associated tools.

A Dockerfile is a sort of script for creating a Linux container (https://docs.docker.com/engine/reference/builder/). I wrote one that automates the creation of a Zephyr development environment based on Ubuntu 15.10. It's fairly short, so I pasted it at the end of this message in its entirety. It would be placed in a new, empty directory, e.g. $ZEPHYR_BASE/scripts/docker.

To build the container, the developer would execute "docker build -t zephyr-build ." in that directory from the "Docker Quickstart Terminal".

To run the container, the developer would execute "docker run -t -i -v /c/Users/<username>/<zephyr_src_dir>:/zephyr zephyr-build", where <zephyr_src_dir> is a Zephyr source tree. This would present the developer with a command prompt in the Zephyr development environment with the root of the Zephyr source tree as the initial working directory.

To build an app, the developer would navigate to the desired app source directory and execute the same commands that would be used in any other Ubuntu Linux environment. The output binary can be accessed from Windows after being built.

This environment is also suitable for building GRUB for the Intel Galileo using the scripts/build_grub.sh script. However, the script must first be copied to /tmp within the Linux container and executed from there, since the GRUB build process is incompatible with the virtual filesystem for the Zephyr source tree.

I think that this environment would only be suitable for building Zephyr binaries. Installing the binaries to the target is an orthogonal procedure. The files simply need to be copied to a USB-connected flash device for a board like the Intel Galileo, but the installation procedure is more complicated for some other boards.

I can submit this Dockerfile as a patch with associated documentation if it seems potentially useful.

This could potentially be useful on other platforms besides Windows, but I have only tested it on Windows 10 so far.

--
Dockerfile:

FROM ubuntu:15.10

RUN apt-get update \
&& apt-get install -y \
autoconf automake bison bzip2 file flex gcc-multilib git make python \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /tmp
ENV SDK_VER 0.7.2
ENV SDK_ARCHIVE zephyr-sdk-$SDK_VER-i686-setup.run
ADD https://nexus.zephyrproject.org/content/repositories/releases/org/zephyrproject/zephyr-sdk/$SDK_VER-i686/$SDK_ARCHIVE ./
RUN chmod u+x $SDK_ARCHIVE
ENV ZEPHYR_SDK_INSTALL_DIR /opt/zephyr-sdk
RUN ./$SDK_ARCHIVE --nox11 -- -d $ZEPHYR_SDK_INSTALL_DIR
RUN rm $SDK_ARCHIVE

RUN echo export ZEPHYR_GCC_VARIANT=zephyr >> ~/.bashrc
RUN echo export ZEPHYR_SDK_INSTALL_DIR=$ZEPHYR_SDK_INSTALL_DIR >> ~/.bashrc
RUN echo source /zephyr/zephyr-env.sh >> ~/.bashrc

WORKDIR /zephyr
CMD ["/bin/bash", "-l"]


Re: Counter driver API

Tseng, Kuo-Lang <kuo-lang.tseng@...>
 

Just to add missing sub-folder name in the hardware specific driver path:

-----Original Message-----
From: Tseng, Kuo-Lang [mailto:kuo-lang.tseng(a)intel.com]
Sent: Friday, February 26, 2016 12:29 PM
To: devel(a)lists.zephyrproject.org
Subject: [devel] RFC: Counter driver API

Hi,

As per suggestion from Gerrit comment, moving the discussion to mailing list.

Background
--------------

On Quark (SE and D2000), there are Always On Counter (free running) and
Always ON Periodic Timer devices. A counter|timer driver is to be added for
supporting these devices. At same time, the goal is to create an API that is
generic enough for not just these two specific devices.

Proposal:
-----------

Generic counter driver API:
-------------------------------
We will have 3 routines - start, stop, and read, which takes in the device pointer
- which identifies the timer. The driver header, counter.h, is under /include
folder:

/**
* @brief Set up counter configuration and start it.
* @param dev Pointer to the device structure for the driver instance.
* @param config Pointer to counter configuration structure
*
* @retval DEV_OK If successful.
* @retval DEV_* Code otherwise.
*/
int counter_start(struct device *dev, counter_input *config);

/**
* @brief Stop the counter.
* @param dev Pointer to the device structure for the driver instance.
*
* @retval DEV_OK If successful.
* @retval DEV_* Code otherwise.
*/
int counter_stop(struct device *dev);

/**
* @brief Read current counter value
* @param dev Pointer to the device structure for the driver instance.
*
* @return 32-bit value
*/
uint32_t counter_read(struct device *dev)

The counter_input structure can be something like below:

/**
* @brief Counter configuration.
*
* Acceptable setting in the configuration structure is hardware-specific.
*
* initial_value - Initial value to load to the counter or timer.
* callback - Callback function when timer expires.
*/
struct counter_input {
uint32_t initial_value;
void (*callback)(void);
};

Note - Using structure, tomorrow we can add more fields for a counter with
more features.
For the Free Running counter in Quark, these fields would be null as it does not
support interrupt or callback notification.

The hardware-specific driver implementation:
-----------------------------------

This can be implemented in /drivers directory. For example, for Quark SE and
D2000, we can have below file which implements the API functionality using the
AON Counter and AON Periodic Timer:

drivers/quark_aon_counter.c
I missed sub-folder name here. It should be drivers/counter/quark_aon_counter.c


Comment, feedback welcome.


Building project

Corey Williamson <corey.bailey.williamson@...>
 

Hi,

I'm currently trying to build the hello world example in a directory
outside the zephyr SDK and I keep getting this make error:

corey(a)corey-H97M-D3H:~/ZephyrWorkspace/eclipse_workspace/hello_world$ make
Using
/home/corey/ZephyrWorkspace/zephyr-project/boards/frdm_k64f/frdm_k64f_defconfig
as base
Merging
/home/corey/ZephyrWorkspace/zephyr-project/kernel/configs/mico.config
The merge file
'/home/corey/ZephyrWorkspace/zephyr-project/kernel/configs/mico.config'
does not exist. Exit.
make: ***
[/home/corey/ZephyrWorkspace/eclipse_workspace/hello_world/outdir/.config]
Error 1

I thought I might be environment variables but I echoed ZEPHYR_BASE and it
was correct.

Any help is much appreciated,

Thanks!

Corey


Re: STM32F103x port

Nashif, Anas
 

On Feb 26, 2016, at 11:08, Maciek Borzecki <maciek.borzecki(a)gmail.com> wrote:

Hi list,

I've done a PoC port of Zephyr to STM32F103VE MCU on a EB-STM_06 dev
board. The port is rather minimal, most of the configuration is
hardcoded. The MCU is configured to use internal HSI clock source, with
PLL feeding a 36MHz clock to SYSCLK and AHB/APB (tried to make it board
agnostic). The minimal UART driver assumes that USART1 will be used with
a fixed speed of 9600kbps. The the best of my knowledge, this should be
enough as a starting point for porting to other boards.

The source code lives here:
https://github.com/bboozzoo/zephyr/tree/bboozzoo/stm32f103 in
bboozzoo/stm32f103 branch.

Obligatory video: https://goo.gl/photos/AGhfXYvv8CswjRRu7 (sorry for the
background sound and overall potato quality). In the vide I flash the
firmware through STLink, the board resets and starts the hello world
sample. The output is received via a USB RS232 adapter. The sample
program has been also modified to print an increasing loop counter, just
to make sure we're not looping the same content.

If anyone feels like this is worth working on I might be able to try and
clean it up a little bit and push out to Gerrit (once I get my access
issues resolved). I also have a couple of boards with STM32F3xx and
STM32L4xx MCUs so I might give these a try, unfortunately all of these
are Cortex-M4 based.

Has anyone looked at ports to Cortex-M0?

There is an effort going on right now, details will be provided soon.

Anas



Cheers,
--
Maciek Borzecki


RFC: Counter driver API

Tseng, Kuo-Lang <kuo-lang.tseng@...>
 

Hi,

As per suggestion from Gerrit comment, moving the discussion to mailing list.

Background
--------------

On Quark (SE and D2000), there are Always On Counter (free running) and Always ON Periodic Timer devices. A counter|timer driver is to be added for supporting these devices. At same time, the goal is to create an API that is generic enough for not just these two specific devices.

Proposal:
-----------

Generic counter driver API:
-------------------------------
We will have 3 routines - start, stop, and read, which takes in the device pointer - which identifies the timer. The driver header, counter.h, is under /include folder:

/**
* @brief Set up counter configuration and start it.
* @param dev Pointer to the device structure for the driver instance.
* @param config Pointer to counter configuration structure
*
* @retval DEV_OK If successful.
* @retval DEV_* Code otherwise.
*/
int counter_start(struct device *dev, counter_input *config);

/**
* @brief Stop the counter.
* @param dev Pointer to the device structure for the driver instance.
*
* @retval DEV_OK If successful.
* @retval DEV_* Code otherwise.
*/
int counter_stop(struct device *dev);

/**
* @brief Read current counter value
* @param dev Pointer to the device structure for the driver instance.
*
* @return 32-bit value
*/
uint32_t counter_read(struct device *dev)

The counter_input structure can be something like below:

/**
* @brief Counter configuration.
*
* Acceptable setting in the configuration structure is hardware-specific.
*
* initial_value - Initial value to load to the counter or timer.
* callback - Callback function when timer expires.
*/
struct counter_input {
uint32_t initial_value;
void (*callback)(void);
};

Note - Using structure, tomorrow we can add more fields for a counter with more features.
For the Free Running counter in Quark, these fields would be null as it does not support interrupt or callback notification.

The hardware-specific driver implementation:
-----------------------------------

This can be implemented in /drivers directory. For example, for Quark SE and D2000, we can have below file which implements the API functionality using the AON Counter and AON Periodic Timer:

drivers/quark_aon_counter.c

Comment, feedback welcome.


Re: STM32F103x port

Maciek Borzecki <maciek.borzecki@...>
 

On Fri, Feb 26, 2016 at 5:39 PM, Tomasz Bursztyka
<tomasz.bursztyka(a)linux.intel.com> wrote:
Hi Maciek,

This is great stuff, it's totally worth working on porting Zephyr for STM32.

I actually recently got the Nucleo boards F103, F030 and F334 as I was
planning to
play with Zephyr on it. I'll try your branch on it and I'll take some time
to review it.
(as soon as I get some time)
The problem with the dev board that I used is that it's not really
available anymore. To the best of my knowledge, the unit I have is an
older version of this one:
https://kamami.pl/zestawy-uruchomieniowe-stm32/187712-eb-stm3206.html?search_query=stm32f103vet6&results=3
However, since there are some apparent differences in the pinout and
since I don't really have the schematics, I'll have to replace it with
something more usable. We have some Discovery (STM32F3, STM32F4) and
Nucleo (F030R8, maybe one F103) kits at the office, I guess one of
these will be my next target.

As for the code, there's really not much of it. I've typed in the
structs for RCC (Reset & Clock Control), GPIOs and UART register
mappings and wired that up.

BR,
--
Maciek Borzecki


Re: STM32F103x port

Kalowsky, Daniel <daniel.kalowsky@...>
 

-----Original Message-----
From: Maciek Borzecki [mailto:maciek.borzecki(a)gmail.com]
Sent: Friday, February 26, 2016 8:07 AM
To: devel(a)lists.zephyrproject.org; users(a)lists.zephyrproject.org
Subject: [devel] STM32F103x port

Hi list,

I've done a PoC port of Zephyr to STM32F103VE MCU on a EB-STM_06 dev
board. The port is rather minimal, most of the configuration is hardcoded.
The MCU is configured to use internal HSI clock source, with PLL feeding a
36MHz clock to SYSCLK and AHB/APB (tried to make it board agnostic). The
minimal UART driver assumes that USART1 will be used with a fixed speed of
9600kbps. The the best of my knowledge, this should be enough as a starting
point for porting to other boards.

Looks like you beat me to some of it. I have been slowly working on an STM32F2xx support. If you clean up your patches and submit to gerrit, much of the STM32F2xx patches can be easily integrated.


The source code lives here:
https://github.com/bboozzoo/zephyr/tree/bboozzoo/stm32f103 in
bboozzoo/stm32f103 branch.

Obligatory video: https://goo.gl/photos/AGhfXYvv8CswjRRu7 (sorry for the
background sound and overall potato quality). In the vide I flash the firmware
through STLink, the board resets and starts the hello world sample. The
output is received via a USB RS232 adapter. The sample program has been
also modified to print an increasing loop counter, just to make sure we're not
looping the same content.

If anyone feels like this is worth working on I might be able to try and clean it
up a little bit and push out to Gerrit (once I get my access issues resolved). I
also have a couple of boards with STM32F3xx and STM32L4xx MCUs so I
might give these a try, unfortunately all of these are Cortex-M4 based.

Has anyone looked at ports to Cortex-M0?

Cheers,
--
Maciek Borzecki


Re: STM32F103x port

Tomasz Bursztyka
 

Hi Maciek,

This is great stuff, it's totally worth working on porting Zephyr for STM32.

I actually recently got the Nucleo boards F103, F030 and F334 as I was
planning to
play with Zephyr on it. I'll try your branch on it and I'll take some
time to review it.
(as soon as I get some time)

M0, M0+, M4... all these are relevant for Zephyr I would say. I don't
know if anybody
is already working around though.

Br,

Tomasz

Hi list,

I've done a PoC port of Zephyr to STM32F103VE MCU on a EB-STM_06 dev
board. The port is rather minimal, most of the configuration is
hardcoded. The MCU is configured to use internal HSI clock source, with
PLL feeding a 36MHz clock to SYSCLK and AHB/APB (tried to make it board
agnostic). The minimal UART driver assumes that USART1 will be used with
a fixed speed of 9600kbps. The the best of my knowledge, this should be
enough as a starting point for porting to other boards.

The source code lives here:
https://github.com/bboozzoo/zephyr/tree/bboozzoo/stm32f103 in
bboozzoo/stm32f103 branch.

Obligatory video: https://goo.gl/photos/AGhfXYvv8CswjRRu7 (sorry for the
background sound and overall potato quality). In the vide I flash the
firmware through STLink, the board resets and starts the hello world
sample. The output is received via a USB RS232 adapter. The sample
program has been also modified to print an increasing loop counter, just
to make sure we're not looping the same content.

If anyone feels like this is worth working on I might be able to try and
clean it up a little bit and push out to Gerrit (once I get my access
issues resolved). I also have a couple of boards with STM32F3xx and
STM32L4xx MCUs so I might give these a try, unfortunately all of these
are Cortex-M4 based.

Has anyone looked at ports to Cortex-M0?

Cheers,


Re: STM32F103x port

Benjamin Walsh <benjamin.walsh@...>
 

Hi Maciek,

I've done a PoC port of Zephyr to STM32F103VE MCU on a EB-STM_06 dev
board. The port is rather minimal, most of the configuration is
hardcoded. The MCU is configured to use internal HSI clock source, with
PLL feeding a 36MHz clock to SYSCLK and AHB/APB (tried to make it board
agnostic). The minimal UART driver assumes that USART1 will be used with
a fixed speed of 9600kbps. The the best of my knowledge, this should be
enough as a starting point for porting to other boards.

The source code lives here:
https://github.com/bboozzoo/zephyr/tree/bboozzoo/stm32f103 in
bboozzoo/stm32f103 branch.

Obligatory video: https://goo.gl/photos/AGhfXYvv8CswjRRu7 (sorry for the
background sound and overall potato quality). In the vide I flash the
firmware through STLink, the board resets and starts the hello world
sample. The output is received via a USB RS232 adapter. The sample
program has been also modified to print an increasing loop counter, just
to make sure we're not looping the same content.

If anyone feels like this is worth working on I might be able to try and
clean it up a little bit and push out to Gerrit (once I get my access
issues resolved). I also have a couple of boards with STM32F3xx and
STM32L4xx MCUs so I might give these a try, unfortunately all of these
are Cortex-M4 based.
Very cool!

Cortex-M4 should work as well, since the M4 is a superset of the M3. The
first board we supported is the Freescale FRDM-K64F, which is an M4.

Has anyone looked at ports to Cortex-M0?
For M0, you have to do an arch port as well. The M3 arch port was done
by using a couple of features that are not available on M0, basically
BASEPRI for interrupt locking instead of PRIMASK and some Thumb2
instructions that are not available on M0.

That said, it might not be too hard to make the M3 arch M0-capable, we
just haven't had the time to look very deep into it.

Cheers,
Ben

--
Benjamin Walsh, SMTS
Wind River Rocket
Zephyr kernel maintainer
zephyrproject.org
www.windriver.com


STM32F103x port

Maciek Borzecki <maciek.borzecki@...>
 

Hi list,

I've done a PoC port of Zephyr to STM32F103VE MCU on a EB-STM_06 dev
board. The port is rather minimal, most of the configuration is
hardcoded. The MCU is configured to use internal HSI clock source, with
PLL feeding a 36MHz clock to SYSCLK and AHB/APB (tried to make it board
agnostic). The minimal UART driver assumes that USART1 will be used with
a fixed speed of 9600kbps. The the best of my knowledge, this should be
enough as a starting point for porting to other boards.

The source code lives here:
https://github.com/bboozzoo/zephyr/tree/bboozzoo/stm32f103 in
bboozzoo/stm32f103 branch.

Obligatory video: https://goo.gl/photos/AGhfXYvv8CswjRRu7 (sorry for the
background sound and overall potato quality). In the vide I flash the
firmware through STLink, the board resets and starts the hello world
sample. The output is received via a USB RS232 adapter. The sample
program has been also modified to print an increasing loop counter, just
to make sure we're not looping the same content.

If anyone feels like this is worth working on I might be able to try and
clean it up a little bit and push out to Gerrit (once I get my access
issues resolved). I also have a couple of boards with STM32F3xx and
STM32L4xx MCUs so I might give these a try, unfortunately all of these
are Cortex-M4 based.

Has anyone looked at ports to Cortex-M0?

Cheers,
--
Maciek Borzecki


Re: Pinmux driver model: per board vs. unified

Vinicius Costa Gomes
 

Hi,

Dmitriy Korovkin <dmitriy.korovkin(a)windriver.com> writes:

On 16-02-25 02:05 PM, Vinicius Costa Gomes wrote:
Hi Dmitriy,

Dmitriy Korovkin <dmitriy.korovkin(a)windriver.com> writes:

It would be good to have design changes for pinmux outlined in one
text. Are we talking about code consolidation for Quark SE/D2000 or
the global change for all pinmuxes? Are we touching the part referred
as "PINMUX_DEV"?
Good idea, this is going to be useful to see if what I have in mind is
aligned with what other's have.

This is a rough sketch of what's I am working on:

* Code organization:
drivers/
pinmux/
pinmux_arduino_101.c
pinmux_arduino_due.c
pinmux_galileo.c*
pinmux_galileo_priv.c
pinmux_galileo_priv.h
pinmux_quark_d2000_crb.c
pinmux_quark_se_dev.c
pinmux_dev/
pinmux_dev_quark_d2000.c
pinmux_dev_galileo.c
pinmux_dev_atmel_sam3x.c

* Galileo is a special case, and to avoid copied functions in the
pinmux_dev driver, '_galileo_set_pin()' will be made available to both
the "board" driver and "dev" driver via the 'pinmux_galileo_priv.h'
header.
I agree, Galileo is a special case and it's initialization code may/will
share enough code with development part. I think, pinmux_galileo_priv.c
will implement those common functions, am I right?
Exactly, from what I can see, it will be only one common function.


The drivers in 'pinmux' will have only the equivalent of
'_pinmux_defaults()' part of the 'board/*/pinmux.c' files.

The drivers in 'pinmux_dev' will provide the pinmux reconfiguration part that
you refer below.

If we are just changing code for two SoCs, I have no problem with it
at all. If we are changing the architecture, we really need the new
approach clean, as the following concerns come up: - pinmuxing may be
implemented on a SoC or on a board level (Quark SE vs. Galileo), as
well as other architectures may implement it on a different way (FRDM
k64F, which is coming).
At first what comes to mind is that we could have a common header that
provides functions that are used by a family of boards. Or are you
talking about something else? (I don't know anything about FRDM k64F)
As far as I see, FRDM k64f looks like something in between Galileo and
Quark SE in terms of complexity.
I see. I wouldn't like that these _priv.{c,h} idiom would become the
norm, but two instances may be acceptable. If there are more cases like
this, I would consider providing a pinmux library, as was suggested
earlier in the thread, but this is better left for when this becomes a
real issue.


- reconfiguring pinmux from an application is not usual practice, but
quite possible. Cutting this functionality off may make problems in
case of "we have this pinmux configuration by default, but for this
particular sample project we need to change it".
We will provide the pinmux_dev driver for applications that wish to do this.

- pinmux_initialize() may and sometimes should not be implemented by
calling set(), get() and other API functions, but implemented
individually, just not to slow down the booting process.
The board drivers (in 'pinmux'), in the common case, will write directly
in the registers, configuring multiple pins at the same time,
maintaining what we have right now in Zephyr.
Agreed,
Regards,
Dmitriy


Cheers,
--
Vinicius

Cheers,
--
Vinicius


[RFC] Nanokernel timers rework proposal

Dmitriy Korovkin
 

Problem: there are two similar mechanisms in nanokernel: nano_timers and
nano_timeouts. In order to optimize codeand space it's better to have one
mechanism for both.

Proposal: Implement nano_timer through timeout mechanism. This aproach
allows to get rid of heavier nanokernel lifo component in favor of more
lightweight nanokernel timeout implementation.

The _nano_timeout structure gets two additional arguments: void
*user_data_ptr and bool expired, the flag that is set to true when the
timeout is expired.
_nano_timeout structure now can be safely renamed to nano_timer, as it
has everything required by nano_timer API.
In this case, if a function like fiber_sleep() is invoked, the
user_data_ptr is set to NULL.
For the nano_timer API user_data_ptr is used to store the user data
pointer. When the nano_timer_init() function is called, it gets the
_nano_timer structure and initializes it as before. On the
nano_timer_start() call the nano_timer structure is being added to the
sorted list via _nano_timeout_add() function.
nano_timer_test() checks the expired flag of the nano_timer structure.
if it is true, the function just returns the user_data_ptr, otherwise,
if the timeout_in_ticks is not TICKS_NONE, it puts the fiber or task to
sleep by calling _Swap().

Question: is it needed to wait for a specified timeout, if
timeout_in_ticks argument is neither TICKS_NONE nor TICKS_UNLIMITED?

_nano_timeout_handle_one_timeout(), in turn, sets the expired flag to
true and if fiber or task is waiting, marks it runnable.
fiberRtnValueSet is used to set the return value to user_data_ptr.


Problem: in microkernel system clock ticks are processed in the k_server
fiber, which does not allow using timeouts during the initialization
before k_server fiber starts.

In order to allow using timeouts during the system initialization
_do_sys_clock_tick_announce pointer has to be modified to point at the
_nano_sys_clock_tick_announce() until the microkernel _k_server() fiber
starts. This way the _do_sys_clock_tick_announce may be initialized as a
pointer to
_nano_sys_clock_tick_announce() routine by default.

This modification needs to be done with changing priority of the driver
initialization routines that use timeout. Such routines need to be
invoked not on PRIMARY, but on NANOKERNEL initialization level.

--
Dmitriy Korovkin


Re: Pinmux driver model: per board vs. unified

Dmitriy Korovkin
 

On 16-02-25 02:05 PM, Vinicius Costa Gomes wrote:
Hi Dmitriy,

Dmitriy Korovkin <dmitriy.korovkin(a)windriver.com> writes:

It would be good to have design changes for pinmux outlined in one
text. Are we talking about code consolidation for Quark SE/D2000 or
the global change for all pinmuxes? Are we touching the part referred
as "PINMUX_DEV"?
Good idea, this is going to be useful to see if what I have in mind is
aligned with what other's have.

This is a rough sketch of what's I am working on:

* Code organization:
drivers/
pinmux/
pinmux_arduino_101.c
pinmux_arduino_due.c
pinmux_galileo.c*
pinmux_galileo_priv.c
pinmux_galileo_priv.h
pinmux_quark_d2000_crb.c
pinmux_quark_se_dev.c
pinmux_dev/
pinmux_dev_quark_d2000.c
pinmux_dev_galileo.c
pinmux_dev_atmel_sam3x.c

* Galileo is a special case, and to avoid copied functions in the
pinmux_dev driver, '_galileo_set_pin()' will be made available to both
the "board" driver and "dev" driver via the 'pinmux_galileo_priv.h'
header.
I agree, Galileo is a special case and it's initialization code may/will
share enough code with development part. I think, pinmux_galileo_priv.c
will implement those common functions, am I right?

The drivers in 'pinmux' will have only the equivalent of
'_pinmux_defaults()' part of the 'board/*/pinmux.c' files.

The drivers in 'pinmux_dev' will provide the pinmux reconfiguration part that
you refer below.

If we are just changing code for two SoCs, I have no problem with it
at all. If we are changing the architecture, we really need the new
approach clean, as the following concerns come up: - pinmuxing may be
implemented on a SoC or on a board level (Quark SE vs. Galileo), as
well as other architectures may implement it on a different way (FRDM
k64F, which is coming).
At first what comes to mind is that we could have a common header that
provides functions that are used by a family of boards. Or are you
talking about something else? (I don't know anything about FRDM k64F)
As far as I see, FRDM k64f looks like something in between Galileo and
Quark SE in terms of complexity.

- reconfiguring pinmux from an application is not usual practice, but
quite possible. Cutting this functionality off may make problems in
case of "we have this pinmux configuration by default, but for this
particular sample project we need to change it".
We will provide the pinmux_dev driver for applications that wish to do this.

- pinmux_initialize() may and sometimes should not be implemented by
calling set(), get() and other API functions, but implemented
individually, just not to slow down the booting process.
The board drivers (in 'pinmux'), in the common case, will write directly
in the registers, configuring multiple pins at the same time,
maintaining what we have right now in Zephyr.
Agreed,
Regards,
Dmitriy


Cheers,
--
Vinicius


Re: Pinmux driver model: per board vs. unified

Vinicius Costa Gomes
 

Hi Dmitriy,

Dmitriy Korovkin <dmitriy.korovkin(a)windriver.com> writes:

It would be good to have design changes for pinmux outlined in one
text. Are we talking about code consolidation for Quark SE/D2000 or
the global change for all pinmuxes? Are we touching the part referred
as "PINMUX_DEV"?
Good idea, this is going to be useful to see if what I have in mind is
aligned with what other's have.

This is a rough sketch of what's I am working on:

* Code organization:
drivers/
pinmux/
pinmux_arduino_101.c
pinmux_arduino_due.c
pinmux_galileo.c*
pinmux_galileo_priv.c
pinmux_galileo_priv.h
pinmux_quark_d2000_crb.c
pinmux_quark_se_dev.c
pinmux_dev/
pinmux_dev_quark_d2000.c
pinmux_dev_galileo.c
pinmux_dev_atmel_sam3x.c

* Galileo is a special case, and to avoid copied functions in the
pinmux_dev driver, '_galileo_set_pin()' will be made available to both
the "board" driver and "dev" driver via the 'pinmux_galileo_priv.h'
header.

The drivers in 'pinmux' will have only the equivalent of
'_pinmux_defaults()' part of the 'board/*/pinmux.c' files.

The drivers in 'pinmux_dev' will provide the pinmux reconfiguration part that
you refer below.

If we are just changing code for two SoCs, I have no problem with it
at all. If we are changing the architecture, we really need the new
approach clean, as the following concerns come up: - pinmuxing may be
implemented on a SoC or on a board level (Quark SE vs. Galileo), as
well as other architectures may implement it on a different way (FRDM
k64F, which is coming).
At first what comes to mind is that we could have a common header that
provides functions that are used by a family of boards. Or are you
talking about something else? (I don't know anything about FRDM k64F)

- reconfiguring pinmux from an application is not usual practice, but
quite possible. Cutting this functionality off may make problems in
case of "we have this pinmux configuration by default, but for this
particular sample project we need to change it".
We will provide the pinmux_dev driver for applications that wish to do this.

- pinmux_initialize() may and sometimes should not be implemented by
calling set(), get() and other API functions, but implemented
individually, just not to slow down the booting process.
The board drivers (in 'pinmux'), in the common case, will write directly
in the registers, configuring multiple pins at the same time,
maintaining what we have right now in Zephyr.


Cheers,
--
Vinicius


Re: Pinmux driver model: per board vs. unified

Dmitriy Korovkin
 

It would be good to have design changes for pinmux outlined in one text. Are we talking about code consolidation for Quark SE/D2000 or the global change for all pinmuxes? Are we touching the part referred as "PINMUX_DEV"?
If we are just changing code for two SoCs, I have no problem with it at all. If we are changing the architecture, we really need the new approach clean, as the following concerns come up:
- pinmuxing may be implemented on a SoC or on a board level (Quark SE vs. Galileo), as well as other architectures may implement it on a different way (FRDM k64F, which is coming).
- reconfiguring pinmux from an application is not usual practice, but quite possible. Cutting this functionality off may make problems in case of "we have this pinmux configuration by default, but for this particular sample project we need to change it".
- pinmux_initialize() may and sometimes should not be implemented by calling set(), get() and other API functions, but implemented individually, just not to slow down the booting process.


Re: Pinmux driver model: per board vs. unified

Andre Guedes <andre.guedes@...>
 

Hi all,

Quoting Vinicius Costa Gomes (2016-02-24 18:34:16)
After writing this mail, looking at the code again I have a alternate
proposal.

1. move the current pinmux drivers back into drivers with reasonable
names.

2. remove the API support from all the drivers and move it to a
quark_pinmux_dev driver that just provides the API if people really
need runtime control of the pin configuration they can build the
driver.

So all the replicated code moves to a single place where it is needed
and the remaining pimux driver only do init() and are done.
I like it.

The only thing I am thinking about is polluting the drivers/pinmux/
directory when there are more than a couple of board variants. But this
may not be a problem.

I would only propose to have a different directory for the 'pinmux_dev'
driver. From what I understand, there would be no code shared between
the pinmux "board" driver and the pinmux "dev" driver (the only
information needed seems to be what is already provided by
'include/pinmux.h').
Yes, I also like this proposal and I think we should move with it instead
of with the proposal I did.

I have just one comment regarding the 'pinmux board driver'. The way I see
it, what we are calling 'pinmux board driver' is more like a board-specific
initialization code than a driver per se. And, as a board-specific code, I
think we should land it in board/.

For 'pinmux dev driver', yes, it totally make sense to me that we should
land them in driver/ and the user can build it if his/her *application*
requires it.

Regards,

Andre


Re: RFC[2/2] Common logging infrastructure and API

Dirk Brandewie <dirk.j.brandewie@...>
 

On 02/25/2016 07:47 AM, Benjamin Walsh wrote:
On Thu, Feb 25, 2016 at 07:05:49AM -0800, Dirk Brandewie wrote:


On 02/24/2016 02:13 PM, Saucedo Tejada, Genaro wrote:
From 9baee79d211bfb94aeed970c55f31cd3c4b2a8ad Mon Sep 17 00:00:00 2001
From: Genaro Saucedo Tejada <genaro.saucedo.tejada(a)intel.com>
Date: Fri, 19 Feb 2016 17:10:28 -0600
Subject: [PATCH] Log macros unified in a common API

Introduces a header to concentrate logging macro definitions for all
code to
reuse, change aims to provide all currently existing logging
functionality so
every C file can replace it's compile-unit definitions by common code.

Later enhancements to log can now be performed in a single file.

Features:
* Optional printing of thread pointer
* Optional printing of colored messages
* Optional printing of a label to indicate logging level (info, error,
warning, debug)
* Caller function name printing
* Incremental log levels
* One point log disable
I like this in general we need a common set of debug output macros
that all drivers can use. Currently we have a *bunch* of different
versions of the same thing in use throughout the driver tree.

I don't like the naming, we already have a kernel event logging API
people may assume that the two facilities are connected based on the name.

Can we change the names to debug_* or something else?
Again, do we want to take over _another_ namespace ? Maybe it should be
sys_debug or sys_dbg or sys_dbg_log ?

The sample implementation is adding all these in logging.h, which is a
public API file:

DBG, ERR, INF, WRN, THREAD_FN_CALL, IS_LOGGING_ACTIVE

which are very generic names. Don't forget that the application writer
is operating in the same C namespace, and we have been trying to keep
the namespaces the kernel owns to a minimum to minimize the number or
potential clashes:
It's the MACRO names the need fixed up IMO. Any functions that are
added should be in the sys_* space sure. I didn't see any new C
functions being added.



See doc/collaboration/code/naming_conventions.rst.


Re: RFC[2/2] Common logging infrastructure and API

Benjamin Walsh <benjamin.walsh@...>
 

On Thu, Feb 25, 2016 at 07:05:49AM -0800, Dirk Brandewie wrote:


On 02/24/2016 02:13 PM, Saucedo Tejada, Genaro wrote:
From 9baee79d211bfb94aeed970c55f31cd3c4b2a8ad Mon Sep 17 00:00:00 2001
From: Genaro Saucedo Tejada <genaro.saucedo.tejada(a)intel.com>
Date: Fri, 19 Feb 2016 17:10:28 -0600
Subject: [PATCH] Log macros unified in a common API

Introduces a header to concentrate logging macro definitions for all
code to
reuse, change aims to provide all currently existing logging
functionality so
every C file can replace it's compile-unit definitions by common code.

Later enhancements to log can now be performed in a single file.

Features:
* Optional printing of thread pointer
* Optional printing of colored messages
* Optional printing of a label to indicate logging level (info, error,
warning, debug)
* Caller function name printing
* Incremental log levels
* One point log disable
I like this in general we need a common set of debug output macros
that all drivers can use. Currently we have a *bunch* of different
versions of the same thing in use throughout the driver tree.

I don't like the naming, we already have a kernel event logging API
people may assume that the two facilities are connected based on the name.

Can we change the names to debug_* or something else?
Again, do we want to take over _another_ namespace ? Maybe it should be
sys_debug or sys_dbg or sys_dbg_log ?

The sample implementation is adding all these in logging.h, which is a
public API file:

DBG, ERR, INF, WRN, THREAD_FN_CALL, IS_LOGGING_ACTIVE

which are very generic names. Don't forget that the application writer
is operating in the same C namespace, and we have been trying to keep
the namespaces the kernel owns to a minimum to minimize the number or
potential clashes:

See doc/collaboration/code/naming_conventions.rst.

7921 - 7940 of 8045