Open forGGe opened 7 years ago
Working branch for this issue : https://github.com/forGGe/theCore/tree/g230_kinetis_ke02_exp_support
Hi there,
I'm interested to work on this issue. So what is the current state of KE02 support ?
Hi @iia ,
Currently we have the g230_kinetis_ke02_exp_support branch that pretty outdated and should be refreshed.
If you would like to contribute to this issue, I can guide you with steps required to bring KE02 alive and assist in development.
If you want me to implement KE02 support, I can rearrange priorities and complete the task.
Let me know what you think.
Hi @forGGe ,
I'm interested in contributing to this issue. So it would be great if you can provide with some assistance. To be more precise an overview of the project, the main parts and how they relate and connect among themselves. And of course what is involved to add support for new platforms.
Hi @iia,
I really appreciate your interest in contributing!
Below is an overview you requested.
theCore tries to provide a framework that consistent enough to make portable applications for different kinds of microcontrollers. "Portable" means that you just write your application code once and then compile it for every compatible device.
For example, an application code for reading humidity sensor and writing samples to the MicroSD card will be the same, no matter where you attached MicroSD card and humidity sensor - to STM32F4 or to TI TM4C microcontroller. In a some way, theCore looks like HAL-on-steroids.
(Besides just providing consistent APIs, theCore aims to be a full-featured framework, see Roadmap for more information)
To achieve that goal theCore provides different kinds of modules:
architecture modules - placed under arch
directory. The goal of architecture module is to provide the early startup and initialization code, shared by different microcontrollers. This is where your program starts. Architecture module then passes execution to the platform module, described below.
platform modules - most important and hard part. Placed under platform
directory. Goal of specific platform module is to initialize MCU (clock, watchdog, etc.) and give a user (and theCore) similar APIs for every supported periphery - UART, SPI, etc.
device modules - external device drivers, placed under dev
directory. Those modules provides support for things that are usually attached to MCU: LCDs, audio codecs, sensors, etc.
lib modules - various libraries, placed under lib
directory such as memory allocators, vendor-specific libs, FATFS and other stuff that does not fall in any of previous categories.
kernel modules - RTOS-related modules, placed under kernel
directory. Only FreeRTOS is really supported for now.
system module - placed under sys
directory - it is just a little part of theCore code that initializes theCore itself. There you will find runtime constructor calls and console greetings.
Besides just providing classes to access different devices or MCU peripheries, often it is required to additionally specify how those modules interacts with each other (say, you have attached LCD to MCU) or you need to configure specific module parameters (baud rate of UART console).
theCore gives you an option to specify that details in a JSON configuration file, rather than write C/C++ code that initializes each module in question in a required way (writing C/C++ code can be tedious and error-prone).
Part of theCore, responsible for such configuration is basically called the configurator.
Good example is TI TM4C configuration for LED demo. Path to that configuration file then passed to theCore in main project file
Essentially, theCore configurator is just a code-generation tool, which takes a JSON file and produces corresponding C/C++ definitions that you can use inside your application code
See the filesystem module example that shows how incoming JSON converted into the C/C++ code. Configurator is written using Python Cog utility. The aforementioned file system, Cog-based configurator can be found here.
Configuration based on JSON is somewhat described in the respective documentation page.
Generated code is available if to include ecl/core_generated.hpp
header.
Not much to say here, CMake is used everywhere. Where it cannot handle things like code generation, Python is used.
arch
and platform
are the only modules that interact directly. Arch module calls theCore main routine, theCore main routine then calls platform initialization code and user's main
All other modules sit aside and wait until they will be used by the configurator tool.
You will get more insights about specific modules while hacking KE02 platform.
I will take an action of refreshing the g230_kinetis_ke02_exp_support
branch and will send you more instructions about platform creation soon.
Let me know what you think about it.
Hi @forGGe ,
Thanks for the detailed overview. I'm ordering a KE02 dev board. Let me know after you have refreshed the branch.
Just for reference: The OpenSDA support, included by default in the KE02 MCU makes debugging really painful.
See also: https://www.eevblog.com/forum/microcontrollers/freescale-opensda-linux/
Right now, I'm debugging my fresh, new KE02 dev board by just uploading binaries via the virtual mass-storage that appears after I connect the board.
So, I will try to upload correct J-Link compatible MCU firmware, found at these pages: https://www.segger.com/downloads/jlink#JLinkOpenSDABoardSpecificFirmwares https://www.segger.com/products/debug-probes/j-link/models/other-j-links/opensda-sda-v2/
And I hope my board will stay functional :)
Hi @forGGe,
From where you ordered your board?
From where you ordered your board?
Aliexpress, but I can't find it there anymore. I'll try to check other suppliers.
@iia, branch g230_kinetis_ke02_exp_support
is updated.
Here is instructions of how to run simple demo on your KE02 dev board:
install JLink on your host system (it is not yet shipped with Nix)
download theCore
install Nix: https://forgge.github.io/theCore/guides/getting-started.html#using-nix
cd
to theCore directory
enter Nix shell:
nix-shell .
create build dir:
mkdir ke02_build && cd ke02_build
build a project:
cmake ../examples/ke02_hello -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=../toolchains/arm-cm0-plus-gnu.cmake
make
flash image w/ help of JLink.
Using GDB:
# Run JLinkGDB server
JLinkGDBServerCLExe -device MKE02Z64xxx2 -endian little -if SWD
# Run GDB in another console
arm-none-eabi-gdb ./ke02_hello -x ../scripts/ke02_jlink.gdbinit
# Flash image
(gdb) taget_load
Loading section .text, size 0x1958 lma 0x0
Loading section .data, size 0x14 lma 0x1958
Start address 0x58c, load size 6508
Transfer rate: 52064 bits in <1 sec, 2169 bytes/write.
Resetting target (Type = 6)
Writing register (SP = 0x20000C00)
Writing register (PC = 0x0000058D)
# Run image
(gdb) c
Using JLink itself:
# Run JLink
JLinkExe -device MKE02Z64xxx2 -if SWD -Autoconnect 1 -Speed 1000
# Sub-shell will be opened
# Download image
J-Link>loadbin ke02_hello.bin 0
loadbin ke02_hello.bin 0
Halting CPU for downloading file.
Downloading file [ke02_hello.bin]...
Comparing flash [100%] Done.
Verifying flash [100%] Done.
O.K.
# Restart and go
J-Link>r 6
J-Link>g
Also, check https://octopart.com/frdm-ke02z-nxp+semiconductors-70303061?r=sp&s=oR9dcxYPTvqj5TI7Sgx1Ug for list of available suppliers
@forGGe,
Thanks for all the info. I got the board today and everything worked and I could execute ke02_hello.bin. Since now I have a working setup I can take a better look on the whole system. BTW as much as I could figure out for today you are using the driver lib for KExx series which is posted here in the build system right?
Hi @iia,
Thanks for all the info. I got the board today and everything worked and I could execute ke02_hello.bin.
Great!
BTW as much as I could figure out for today you are using the driver lib for KExx series which is posted here in the build system right?
Yes, I also uploaded it to https://github.com/forGGe/kexx_driverlib
master branch contains a small fix. Not all files are used from there though. See kexx CMakefile for more info
theCore_get_thirdparty()
CMake routine is responsible for getting that dependency.
By default, thirdparty git tree is located ${CORE_DIR}/.thirdparty
directory, and worktree is placed in ${CMAKE_CURRENT_BINARY_DIR}/theCore_thirdparty_worktrees
:
You can control where to download the KEXX driver library. See https://forgge.github.io/theCore/guides/thirdparty-cache.html . (I see that text there is broken, will fix ASAP)
Now, let me give you some ideas about the platform you going to implement.
I recommend you to start with the UART driver and all the infrastructure required to configure it.
Here is the case: theCore platform must take the JSON file, defined in the application:
and then convert it to, say, uart_cfg.hpp
with approximately following contents:
#include <aux/uart.hpp> // Platform UART implementation
namespace ecl
{
using UART0_driver = uart<uart_channel::ch0>;
using platform_console = UART0_driver;
// I encourage you to place this definition in other file later, but for first steps, let it be here.
#define THECORE_CONFIG_USE_CONSOLE 1
}
Pay attention: the UART0
is included here as an example. FRDM-KE02 board's USB-to-UART is connected to the UART1
in fact
The uart_cfg.hpp
then must be included in the aux/generated.hpp
file, which is turn included by the ecl/generated.hpp
header.
(_Sidenote: if you feel that naming is not consistent, I feel it, too. You can rename all aux/generated.hpp
headers inside theCore to use correct namespace: core/platform_generated.hpp
The uart_cfg.hpp
file must be generated using Python COG and a template file. I prefer to name the template file as uart_cfg.in.hpp
.
See examples below.
The UART driver (uart.hpp
) is placed under platform/tm4c/export/aux
dir.
The template file for the UART configuration (uart_cfg.in.hpp
) is present in the TM4C templates
directory
The template file for the IRQ handlers (one of which is UART) is also present in templates
dir
Note: IRQ dispatching for TM4C happens in compile time. I.e. based on configuration given, we can be sure where to deliver an interrupt. I encourage you to use the compile-time dispatching for the KE02 as well. If you want the runtime dispatching - let me know, I will guide you how to use old, runtime IRQ manager in theCore
The template file for the pin configuration is also placed there.
All TM4C template files are then handled in CMakeLists.txt
of the TM4C platform:
Check that entire file to get more insights.
There is a little trickery for the UART driver used as a console output. The UART driver must be able to perform a low-latency output right in the platform periphery. Such shortcut is made in case we need to print something from IRQ context on in case of failed assertion.
It is called "bypass console" in terms of theCore.
You can check the TM4C platform files to see how it works:
Yet, I didn't say to you where to put the UART baud rate, stop bits, etc. Let's stick with 115200/8/1 default configuration and after the UART driver will be ready, I will guide you how to handle that configuration.
@forGGe,
Thanks again for the detailed explanation. Before I start with the UART driver I would like to explain my mental model of the overall system to verify if my concepts are correct.
I will try to represent my mental model of the system with a little ASCII art.
............................ [User Program] ............................ | USES |
---|
V .................................................................................... [Platform] Generated based on the JSON file to use the drivers .................................................................................... | USES |
---|
V ....................................................................................................................... [Drivers] Standard transparent interface to be used by the platform or user program. e.g, platform/tm4c/export/aux/uart.hpp ....................................................................................................................... | USES |
---|
V .............................................................................................................. [Vendor API] Platform specific API provided by the vendor e.g, KEXX_DRIVERLIB .............................................................................................................. | USES |
---|
V ..................... [Hardware] .....................
Is this correct?
BTW what does "ecl" stand for?
@iia ,
Your mental model is correct enough. To be more precise, let me add there one item:
............................
[User Program]
............................
| |
| | USES
| USES V
| ............................
| [External device drivers]
| E.g. LCD driver, RFID reader, etc.
| Also generated by JSON
| ............................
| |
| | USES
V V
....................................................................................
[Platform]
Generated based on the JSON file to use the drivers
....................................................................................
I though it is important to place external device block there, since without that part, user application can't do much (except blinking LED)
If you find that extended model confusing, please let me know. I will try to explain it in more detail.
Also, I'm using here (and across theCore) following convention for naming entities:
platform - from HW point of view, the platform is a specific MCU, and nothing beyond that. Kinetis KE02 MCU is a platform. FRDM-KE02 board is not a platform (see below). From SW point of view the platform is a set of drivers and utilities related only to specific MCU, and nothing beyond that. For example, driver for LCD controller inside STM MCU is part of the platform, while LCD driver for PCD8544 Nokia display is not a part of the platform
target - from HW point of view, the target is a specific board based on a specific MCU. STM32F4 Discovery board is a target. FRDM-KE02 board is another kind of target. If you connect temperature sensor to FRDM-KE02 board you will get a new target. From SW point of view, the target is a set of drivers and utilities, that covers specific board with all devices connected to MCU PLUS the corresponding platform.
JSON file laying in the root of example project is a specification of a target. That is, it specifies what MCU is placed on the board (and how it should be configured) and what hardware is connected to the MCU (and how it should be configured).
BTW what does "ecl" stand for?
ECL stands for "Embedded Core Library"
It is not so meaningful, but it has three required properties:
But I'm open for suggestions in that field :)
Hi,
Platform and target clarification was useful. Thanks.
Hi @forGGe,
Can you explain the bus architecture in device module? What I understand so far about it is that it is to provide an uniform interface to theCore applications to use peripherals that operate on a bus architecture e.g, SPI, I2C etc. It also seems that the platform serial driver must register to the bus so that UART becomes transparent to theCore applications.
Is my understanding correct? Can you provide a bit more detail of the bus mechanism e.g, how platform drivers register to the bus mechanism and how the bus mechanism is used?
Hi @forGGe,
Can you explain a bit more about compile time interrupt dispatching as you mentioned about TM4C platform ?
Hi @iia,
Let me reach my PC, I will answer your questions.
Regards, Max
On Sun, Apr 15, 2018, 3:05 PM Ishraq Ibne Ashraf notifications@github.com wrote:
Hi @forGGe https://github.com/forGGe,
Can you explain a bit more about compile time interrupt dispatching as you mentioned about TM4C platform ?
Can you explain the bus architecture in device module? What I understand so far about it is that it is to provide an uniform interface to theCore applications to use peripherals that operate on a bus architecture e.g, SPI, I2C etc. It also seems that the platform serial driver must register to the bus so that UART becomes transparent to theCore applications.
Is my understanding correct?
You are totally correct. In current state of things, all platform drivers that are capable of doing data transfers are compatible with dev/bus
abstraction.
Not only the bus module presents platform drivers in a common way, it is also extracts common functionality (to avoid duplication in every platform driver, obviously). Most notable is the thread-safety support. dev/bus
provides lock()
/unlock()
methods to protect against race conditions when accessing platform-level driver.
Can you provide a bit more detail of the bus mechanism e.g, how platform drivers register to the bus mechanism and how the bus mechanism is used?
Act of registering to the bus system is a simple composition between dev/bus
and corresponding platform driver.
Suppose we have platform UART driver, like that:
enum class uart_channel
{
ch0,
ch1,
// ...
};
template<uart_channel Ch>
class uart
{
// UART implementation ...
};
and dev/bus.hpp
class (simplified interface):
template<typename PlatformBus>
class generic_bus
{
// Generic bus implementation ...
};
Then theCore can combine (based on configuration JSON) them in following way:
using uart1_driver = uart<uart_channel::ch1>;
using uart1_bus = generic_bus<uart1_driver>;
Now, the uart1_bus
alias can be used in application level or in internal theCore machinery (i.e. in console subsystem).
Note that there are no run-time registering of the UART driver. theCore is aware which platform driver is used for which purpose, so it can directly aggregate common interface class and specific platform driver using C++ templates.
Here is the TM4C UART class:
Here is the TM4C UART generator (cog template in fact) (pay attention for #365 bug):
Here is the example JSON (related to the UART only) provided by user:
{
"platform": {
"name": "tm4c",
"console": "UART0",
"uart": [
{
"id": "UART0",
"alias": "test_uart",
"comment": "UART-over-USB console output"
},
{
"id": "UART1",
"alias": "another_uart",
"comment": "Example UART"
}
]
}
}
Here is what TM4C UART generator will generate in response to user JSON:
namespace ecl
{
// UART configuration ---------------------------------------------------------
/* UART-over-USB console output */
static constexpr uart_channel UART0_channel = uart_channel::ch0;
using UART0_driver = uart<UART0_channel>;
using platform_console = UART0_driver;
using test_uart = UART0_driver;
/* Example UART */
static constexpr uart_channel UART1_channel = uart_channel::ch1;
using UART1_driver = uart<UART1_channel>;
using another_uart = UART1_driver;
} // namespace ecl
And there is how theCore uses platform_console
alias in console subsystem:
Check also UART documentation for TM4C (again,pay attention for #365 bug): https://forgge.github.io/theCore/platform/ti-tivac-tm4c123g.html#uart
There is a less heavy abstraction that better suites for UART-based communications (and overall it is better for communication drivers that are not buses and shouldn't be shared in different modules) - https://github.com/forGGe/theCore/blob/develop/dev/bus/export/dev/serial.hpp#L25
So I want to rebase console driver from generic_bus
to serial
interface, i.e. instead current "chain":
static constexpr uart_channel UART0_channel = uart_channel::ch0;
using UART0_driver = uart<UART0_channel>;
using platform_console = UART0_driver;
using console_bus = ecl::generic_bus<platform_console>;
using console_driver = ecl::console_pipe<console_bus>;
use:
static constexpr uart_channel UART0_channel = uart_channel::ch0;
using UART0_driver = uart<UART0_channel>;
using platform_console = UART0_driver;
using console_bus = ecl::serial<platform_console>;
using console_driver = ecl::console_pipe<console_bus>;
But that's not related to your particular activity in KE02 platform implementation, it is just thoughts I"m sharing with you
Hope this shed some light on driver compositions in theCore.
Can you explain a bit more about compile time interrupt dispatching as you mentioned about TM4C platform ?
Considering our discussion above about driver composition and a purpose of the user config (in JSON form), we can state that theCore is fully aware about all drivers used in the application.
Or, in other words, user must list all drivers that he want to use in that JSON.
It means that theCore knows where to deliver a specific platform interrupt. It also means that the platform driver don't need to register for interrupts in runtime. theCore can generate IRQ handler for the specific interrupt that will call corresponding platform driver routine.
Here is how it looks in TM4C.
IRQ table:
IRQ handler generator:
That if UART0 is listed in JSON will generate code similar to this:
/* 21 UART0 */
extern "C"
void UART0_Handler()
{
ecl::uart_irq_proxy<ecl::uart_channel::ch0>::deliver_irq();
}
/* 22 UART1 */
extern "C"
void UART1_Handler()
{
ecl::abort();
}
Ideally is to have similar thing made for KE02 platform.
Let me know your feedback about it!
Hi @forGGe,
Thanks again for the excellent explanations. I added the UART driver for KE02 which registers to the bus system and used by iostream but can't test it as the compilation fails with the following linking error,
Scanning dependencies of target ke02_hello
[ 82%] Building CXX object CMakeFiles/ke02_hello.dir/main.cpp.obj
[ 83%] Building CXX object CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/platform/ke02/console.cpp.obj
[ 84%] Building CXX object CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/arch/arm_cm/execution.cpp.obj
[ 85%] Building CXX object CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/lib/types/err.cpp.obj
[ 86%] Building CXX object CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/lib/cpp/arm_eabi.cpp.obj
[ 88%] Building CXX object CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/lib/cpp/streams.cpp.obj
[ 89%] Building CXX object CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/lib/thread/no_os/mutex.cpp.obj
[ 90%] Building CXX object CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/lib/thread/no_os/semaphore.cpp.obj
[ 91%] Building CXX object CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/lib/thread/no_os/spinlock.cpp.obj
[ 92%] Building CXX object CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/lib/allocators/alloc.cpp.obj
[ 93%] Building CXX object CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/lib/newlib/stubs.cpp.obj
[ 94%] Linking CXX executable ke02_hello
CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/lib/thread/no_os/semaphore.cpp.obj: In function `std::__atomic_base<bool>::exchange(bool, std::memory_order)':
/nix/store/cmzy23dckxx052dq4lrh7vvfn3sqw09l-gcc-arm-embedded-5.4-2016q2-20160622/arm-none-eabi/include/c++/5.4.1/bits/atomic_base.h:413: undefined reference to `__atomic_exchange_1'
/nix/store/cmzy23dckxx052dq4lrh7vvfn3sqw09l-gcc-arm-embedded-5.4-2016q2-20160622/arm-none-eabi/include/c++/5.4.1/bits/atomic_base.h:413: undefined reference to `__atomic_exchange_1'
CMakeFiles/ke02_hello.dir/home/ishraq/git/theCore/lib/thread/no_os/semaphore.cpp.obj: In function `ecl::binary_semaphore::try_wait(std::chrono::duration<long long, std::ratio<1ll, 1000ll> >)':
/home/ishraq/git/theCore/lib/thread/no_os/semaphore.cpp:78: undefined reference to `SystemCoreClock'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/ke02_hello.dir/build.make:367: ke02_hello] Error 1
make[1]: *** [CMakeFiles/Makefile2:74: CMakeFiles/ke02_hello.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
As far as I can guess it seems like something about the std::chrono library.
Here is the patch.
Hi @iia,
Sorry for a late response.
Thanks for submitting a patch and for your feedback! I suggest you to open pull-request with [WIP] pefix in its name, so we can comment there and put backlinks in this issue.
About __atomic_exchange_1
:
As far as I know, M0/M0+ lacks atomic access commands. Thus, standard C/C++ library does not provide any simulating instructions for that.
You can find some info here: https://stackoverflow.com/questions/5745880/simulating-ldrex-strex-load-store-exclusive-in-cortex-m0
So you need to implement that __atomic_exchange_1
routine by yourself (or find another way to get that function, i.e. via some library). I suggest you to put it in platform.cpp
file.
As far as I can google it, it should have following signature (see https://developer.arm.com/docs/100073/0609/the-arm-c-and-c-libraries/iso-c-library-implementation-definition/standard-c-library-implementation-definition):
uint8_t __atomic_exchange_1(uint8_t *dest, uint8_t val, int model);
It is a specific version of the regular atomic_exchange
builtin, I guess. These builtins are described here:
https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
As for SystemCoreClock
you need to do two things:
platform.cpp
: uint32_t SystemCoreClock;
platform_init()
For that, I guess you need to check datasheet and examples of PLL configuration. I propose to stick with internal oscillator for now.
Also, support for external oscillator should be added in some point in time (and clock speed for that external oscillator must be provided via user's JSON), but you can postpone it for now. .
write clock value to the SystemCoreClock (funny that KE02 driver lib doesn't provide such functionality)
Or you can do a shortcut - if you know for sure clock configuration from a very start of the MCU, you can just set SystemCoreClock
to that value. And fix that later.
Hi,
In this case the system clock is meant to be the RTC of the MCU which is required for measuring time duration. Right?
Hi @iia ,
Sorry, was busy with my work, thus answered so late.
I'm actually talking about main processor clock.
If you check Figure 5-1 of the KE02 Reference Manual, you will see this picture:
The SystemCoreClock
must be equal to the clock on the line called "Core Clock" (see right side of the picture).
Core Clock can be supplied by the ICS (Internal Clock Source) module. The ICS description is located in the same datasheet, page 263.
It has different modes of operation, one of which is FEI: FLL engaged internal, is what we are looking for.
According to the reference manual:
In FLL engaged internal mode, which is the default mode, the ICS supplies a clock derived from the FLL which is controlled by the internal reference clock.
So idea is to remove current ICS code from platform.cpp
file (I have copied it from sysinit.c
file of KEXX driver lib) and configure ICS to work in FEI mode (or, as RM says, it works by default) and using RM calculate which clock frequency will be on the Core Clock line.
This frequency then must be assigned to the SystemCoreClock
variable.
Now, you are probably think how you going to test your assumptions about clock speed?
There is a function:
that you can use to measure delays. If your clock value is correct, then this function must do a delay with a right amount of milliseconds. Note that arch_spin_wait
is imprecise, so use large values, like 1000ms to measure delays.
Let me know your thoughts about it.
Hi @forGGe,
Thanks for the info on clock. But I couldn't manage to resolve the atomic exchange issue. I tried implementing the routing __atomic_exchange_1 with provided signature but with no luck. Ideas ?
Thanks for the info on clock. But I couldn't manage to resolve the atomic exchange issue. I tried implementing the routing __atomic_exchange_1 with provided signature but with no luck. Ideas ?
Hi @iia,
It is quite strange. Let me apply your patch and try implementing it, so I can play around with it.
I'll be back to you with results.
Regards, Max
Hi again, @iia ,
I'm sorry for late follow-up again, I'm busy these days due to my work schedule.
So, I was able to resolve link error, by using following signature:
extern "C"
uint8_t __atomic_exchange_1(volatile void *dest, uint8_t val, int model)
{
// ...
}
placed in platform.cpp
I suppose, implementation should be something like this (pseudocode!):
extern "C"
uint8_t __atomic_exchange_1(volatile void *dest, uint8_t val, int model)
{
(void)model;
disable_irq();
uint8_t *u8_dest = (uint8_t*)dest;
uint8_t old_val = *u8_dest;
*u8_dest = val;
enable_irq();
return old_val;
}
Note that I didn't test that implementation. Hope to hear your results!
Hi @forGGe,
No worries about late replies. I couldn't try the solution yet but will later today. I can already see the signature of the function is different from what I tried with according to the ARM documentation page. How did you figure out this working function signature?
Cheers.
Hi @iia,
Actually when I put into arch.cpp
:
extern "C" uint8_t __atomic_exchange_1(uint8_t*, uint8_t, int) { /* ... */ }
I got:
/home/user/projects/thecore/thecore/arch/arm_cm/arch.cpp:22:66: error:
new declaration 'uint8_t __atomic_exchange_1(uint8_t*, uint8_t, int)' ambiguates
built-in declaration 'unsigned char __atomic_exchange_1(volatile void*, unsigned char, int)' [-Werror]
So I just used that error as a guidance :)
Regards, Max
Hi @forGGe,
Just if I read the error messages a bit further! Thanks BTW.
@iia , looks awesome! Thanks! Do you want me to conduct a full code-review or just some particular part?
By the way, examples (along with main repo) should be moved under theCore-embedded organizatoin. Relevant task for KE02 example is #379 .
For now, one example is almost moved: https://github.com/theCore-embedded/example_cs43l22_audio and similar instructions I expect for KE02 examples as well.
Note that there is no hurry in 379, I suggest to merge/complete KE02 first, and then proceed with moving examples. Nevertheless, there is a challenge of automating the binary flashing into the KE02 FRDM board.
I.e. ideally, the user should be able to do following:
tcore bootstrap
tcore init <hello_world_example_link>
cd hello-world
tcore compile --target=frdm-ke02
tcore flash
And he will get the hello-world displayed in the minicom terminal
(of course, it assumes that you have desire to mess with python a bit :) let me know what you think about it)
Hi @forGGe,
A full code review would be nice.
Eventually moving the examples to "theCore-embedded" seems to be a good idea as it seem to unify the process even more. But I agree for KE02 this can be done eventually.
What would be the the next task for the KE02 port in your opinion?
Cheers.
Hi @iia,
I think what we left with (in this task) is to:
As for (1) - review is in process, as for (2) and (3) - I'm going to create the small doc page and the test suite by myself and I will send you details how to build/run/display doc and conduct tests. So in case you have something to add or change - you will be able to do so.
As for further work on KE02, I suggest following roadmap:
Let me know if you have suggestions for the roadmap.
Task is to integrate theCore with KE02 MCUs
Refs:
Must include