Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CMSIS-Core headers #21

Closed
flit opened this issue Jan 26, 2021 · 27 comments · Fixed by #384
Closed

Add CMSIS-Core headers #21

flit opened this issue Jan 26, 2021 · 27 comments · Fixed by #384
Assignees
Labels
Milestone

Comments

@flit
Copy link

flit commented Jan 26, 2021

Please add standard CMSIS-Core headers and register definitions. Ideally these would replace the bespoke headers to avoid fracturing of the ecosystem.

The common CMSIS header files are here. It's not uncommon to include the entire CMSIS_5 repo as a submodule, and it's just as common to copy the headers into your SDK.

CMSIS-Core documentation

CMSIS-standard register definitions can be generated with the SVDConv utility.

@ghollingworth
Copy link

We're unsure of the viability or value of such a change to the Raspberry Pi Pico SDK, you say 'fracturing the ecosystem' but I'm unsure which ecosystem it would be fracturing?

Can you explain what it is that cannot be done with the SDK without using the core_cm0plus.h from the CMSIS-Core rather than our own m0plus.h

@JonatanAntoni
Copy link

Hi @ghollingworth,

I am wondering if we can join efforts to maintain a common core_cm0plus.h.

While this single file on its own is not huge stuff the CMSIS project offers a lot more. There is an RTOS kernel, as well as DSP and Neural Network libraries optimized for Arm Cortex-M controllers. Projects pulling in such libraries in turn will pull in CMSIS-Core which contains the core_cm0plus.h. Having a separate m0plus.h leaves the user with two similar headers in parallel.

Cheers,
Jonatan

@flit
Copy link
Author

flit commented Jan 27, 2021

A big part of the reasoning is familiarity and existing documentation and tutorials. Another is for enabling existing projects and libraries to be run on Pico.

Pico users new to embedded can easily find material describing how to use the M0+ core, most often written with CMSIS definitions in mind. For experienced Cortex-M developers, having the standard CMSIS headers which they are know is important.

There is a huge amount of open source Cortex-M example code, projects, and middleware libraries, that depend on the CMSIS-Core headers. The optimized CMSIS DSP and NN libraries rely on CMSIS-Core. (You can do a surprising amount of DSP on an M0+. 😄)

@flit
Copy link
Author

flit commented Jan 27, 2021

This document coincidentally was posted yesterday, and gives a good introduction to the what and why of CMSIS components: https://community.arm.com/developer/tools-software/tools/b/tools-software-ides-blog/posts/which-cmsis-components-should-i-care-about

@usedbytes
Copy link
Contributor

+1

Isn't there an intrinsic value in consistency and standardisation? CMSIS-Core would help make the platform more familiar for people coming from other Cortex-M platforms, and help with code portability.

Keil has quite a nice summary of points: https://www.keil.com/pack/doc/CMSIS/Core/html/index.html

CMSIS-Core (Cortex-M) implements the basic run-time system for a Cortex-M device and gives the user access to the processor core and the device peripherals. In detail it defines:

  • Hardware Abstraction Layer (HAL) for Cortex-M processor registers with standardized definitions for the SysTick, NVIC, System Control Block registers, MPU registers, FPU registers, and core access functions.
  • System exception names to interface to system exceptions without having compatibility issues.
  • Methods to organize header files that makes it easy to learn new Cortex-M microcontroller products and improve software portability. This includes naming conventions for device-specific interrupts.
  • Methods for system initialization to be used by each MCU vendor. For example, the standardized SystemInit() function is essential for configuring the clock system of the device.
  • Intrinsic functions used to generate CPU instructions that are not supported by standard C functions.
  • A variable to determine the system clock frequency which simplifies the setup the SysTick timer.

@conkerkh
Copy link

conkerkh commented Feb 2, 2021

I implemented some basic functionality (Pico boots up, blinks and prints out Hello World) and ported to CMSIS. I'm planning to implement couple of drivers using CMSIS standards. Boot Stage 2 is written in C based on assembly files. Currently I need to focus on PLL and Clocks as it's not implemented at all apart from setting XOSC as a clock source. You can have a look here: https://gitlab.com/khockuba/cmsis-pi-pico keep in mind this is WIP

@michael-ring
Copy link

I would also love to see more CMSIS compatibility. Main Point for my are Interrupt Handlers, there are standards in CMSIS about the naming of Interrupt/Interrupt Handlers:

https://www.keil.com/pack/doc/CMSIS/Core/html/group__NVIC__gr.html

Following those rules should not be difficult and it helps porting third party software.

@HeadBoffin
Copy link

As there is an SVD file, could you not generate the CMSIS core from that?

@WestfW
Copy link

WestfW commented Feb 19, 2021

+1.
I don't much care about the other parts of CMSIS, but I can't think of a reason for not including the ARM core_m0plus.h

@ehughes
Copy link

ehughes commented Feb 19, 2021

At least include the header file for the registers macros. There is a lot of existing ARM CM0 project code that references NVIC, Systick, etc.

@flit
Copy link
Author

flit commented Feb 19, 2021

As there is an SVD file, could you not generate the CMSIS core from that?

When we talk about CMSIS-Core headers, we're talking primarily about the standard headers for system registers and compiler polyfills. These headers provide a consistent and familiar interface for managing the NVIC and other core peripherals.

You are correct that there is an SVDConv.exe tool that can generate standard CMSIS-format register headers from an SVD file.

@kilograham
Copy link
Contributor

kilograham commented Feb 21, 2021

One option might be to add a cmsis_core_headers library to the SDK. What exactly would that include? is there a clean delineation between hardware accessors, and CMSIS Core runtime? I haven't looked closely but saw some mention of board.h (which seems to be required)... is it OK for the library to include that or does that break actual usages of the headers?

(edit:) note we don't have to include the board.h but would then require the user to if they pull in cmsis_core_headers

@flit
Copy link
Author

flit commented Feb 21, 2021

The typical way CMSIS-Core is intended to work is that the silicon vendor will customize with the templates. The template documentation describes how they are supposed to be edited.

In short, there is usually a <device>.h header that looks like this. The most important thing is that it defines a number of macros to set the core type and features, then includes the appropriate CMSIS-Core cpu header, and either inlines or includes device register definitions.

These are the full set of core feature macros (only those used in the cpu header need to be defined, see ARMCM0plus.h for example):
https://github.com/ARM-software/CMSIS_5/blob/9f524153122d10a42d5e770904e5a488471fdd4d/Device/_Template_Vendor/Vendor/Device/Include/Device.h#L105-L119

There is also a system_<device>.h header which declares some common functions and globals. This header is normally included by the <device>.h header to the definitions are always available.

In addition to the headers, there are some source files with standard naming. These include standard-form vector tables and startup code. The source files are intended to be copied into user projects, but in practice silicon vendors usually provide standard files that are unmodified except in rare cases.


From a user perspective, the most important bits are:

  • Weak exception and external IRQ handlers with standard naming like HardFault_Handler or LPUART0_Handler.
  • IRQn_Type enum of exception and external IRQ numbers, again with standard naming like HardFault_IRQn and LPUART0_IRQn.
  • Intrinsics, such as those in cmsis_gcc.h.
  • Standard core peripheral register definitions and functions. These are in the core_cm0plus.h header mentioned above.
  • startup_<device>.c (and/or the asm versions) that defines the vector table. Normally developers don't have to worry about it, but if they need to customize it, it's in a standard, familiar form.
  • SystemCoreClock global, used a lot in drivers and sometimes middleware
  • SystemInit(), SystemCoreClockUpdate() functions.

For RP2040, there are two basic options:

  • Use Arm's Cortex-M0+ files as-is. These are a full set of the CMSIS-Core files for a generic M0+ core. The ARMCM0plus.h device header can be used directly, though you may want to customize it a bit. Or maybe add a cmsis.h header that includes it and your existing device register headers (quite common structure). The downside is that it wouldn't have
  • Customize the vendor templates. The minimal would be just the device header, without including or defining system_RP2040.h. The more the better, but this would go a long way.

@WestfW
Copy link

WestfW commented Mar 3, 2021

(Thanks @flit - that's a wonderful summary of how CMSIS-Core should/could work.)

A typical vendor will provide a single .h file that ends up including ALL the peripheral definitions. Ie Atmel has an include file structure similar to the RP2040, with separate "register" and "struct" based definitions for each peripheral, and then there's a "big" samd21xxx.h file that includes them all:

#include <core_cm0plus.h>   /* Common CM0+ definitions from ARM */

/* ************************************************************************** */
/**  SOFTWARE PERIPHERAL API DEFINITION FOR SAMD21G18A  (structs) */
/* ************************************************************************** */
/** \defgroup SAMD21G18A_api Peripheral Software API */
/*@{*/

#include "component/ac.h"
#include "component/adc.h"
#include "component/dac.h"
   :
/* ************************************************************************** */
/**  REGISTERS ACCESS DEFINITIONS FOR SAMD21G18A (individual registers) */
/* ************************************************************************** */
/** \defgroup SAMD21G18A_reg Registers Access Definitions */
/*@{*/

#include "instance/ac.h"
#include "instance/adc.h"
#include "instance/dac.h"
   : 

@kilograham
Copy link
Contributor

Please see #384, though until some other required PRs land you are better off just checking out the cmsis_testing branch

It would be great it anyone interested in this issue can give it a go to see how it works for their use cass; (note just add cmsis_core) to your target_link_libraries and include "RP2040.h"

@kilograham kilograham linked a pull request May 11, 2021 that will close this issue
@kilograham
Copy link
Contributor

merged into develop

@JonatanAntoni
Copy link

Hi @kilograham,

Just as a remark from me being the maintainer for CMSIS. Integrating CMSIS by copy into an SDK is not the recommended way. However, from legal point of view this is totally fine under Apache 2.0. It's just making maintenance a bit harder for users because they can't update software components, indepependently.

In CMSIS we recommend using CMSIS-Pack to distribute individual software components. I admit it doesn't play well with CMake, yet. But for the future you might want to take a look into it. I am happy to discuss this approach.

Cheers,
Jonatan

@kilograham
Copy link
Contributor

Ah from the original issue comment from @flit

The common CMSIS header files are here. It's not uncommon to include the entire CMSIS_5 repo as a submodule, and it's just as common to copy the headers into your SDK.

Note this is just the CMSIS core headers to make life easy compiling existing code. If people want to use CMSIS as a sub-module, or provide it externally, we should support that (in general we have the target item provide an "XXXImport.cmake" that the user can copy into their project which searches within the project tree, or via env or CMake vars to locate the code.

But yes, I also haven't really seen how people intend to use this, so somewhat an open question

@schreinerman
Copy link

I think its is easy to measure a real MCU company by checking how the company had understood the IP they had invested money into. In the todays world, hardware is just one pice. The other bigger portion of IP is software. If you implement a ARM Cortex M core IP into a product and you did not understood why CMSIS is a game changer on the market and why support of the MCU company is required for a correct CMSIS setup, you did not understood why using an ARM Cortex M core in an MCU and not a different core.

Unfortunately MCU "start-up" companies always trying to reinvent the wheel and don't care on the ARM Cortex M philosophy. First off all at the surface this looks great until real customers getting into mass production.

And that's why the Raspberry Pi MCU is a great marketing argument but for developers with experience a sign, the engineers at the Raspberry Pi foundation were not trained by ARM to setup everything correctly. If software is already in that shape, there is also potential the hardware could have the same issues.

And this lack on missing information at the Raspberry Pi foundation engineers you can't fix with just adding CMSIS core headers...

Its like you put an e-Bike Motor in a Ferrari, power it with a 9V block and drive it off-roads and the solution to fix everything is to turn on the auto-pilot.

Hey guys you did a fantastic job with Raspberry Pi and also for the Pico there is still some chance to get it on course. Maybe just ask at ARM for a CMSIS training. ARM did a lot to get all MCU companies at one table to have a profit for everyone. The result is CMSIS. Would be great if also the Raspberry organisation could use this network/pool of experience to understand the potential of CMSIS and what are a must have parts of CMSIS and what is optional for your product!

@WestfW
Copy link

WestfW commented Jul 21, 2021

That's a bit harsh. Nearly ALL of the vendors ignore CMSIS-Driver, for instance. It'd be easy to decide that CMSIS-Core (which is all we really care about here, I think?) is equally problematic, or so small that it's inconsequential.

@schreinerman
Copy link

Well I did not meant CMSIS-Driver. As I said: The engineers need a training to understand what is required and what is optional. CMSIS-Driver is in my eyes a point that is optionally. But to have the possibility to make a decision you need to understand what it is. And in my eyes that was not understood.

CMSIS Core is not just headers. CMSIS is a description which helps to get a smooth integration in the ARM Eco system.

And that's the point.

@JonatanAntoni
Copy link

Hi @WestfW,

As being the maintainer or CMSIS I'd like to learn about your concerns regarding CMSIS-Core. What do you think is problematic with it?

CMSIS-Core(M) wants to provide a common foundation to microcontroller software components to run on all Arm Cortex-M based devices. It basically offers compiler abstraction and core register access. Devices not being prepared to use CMSIS-Core(M) might cause hard times for users trying to reuse software components from other Cortex-M projects.

Todays main challenge for software vendors is scalability. As a vendor of software components for microcontrollers I cannot effort to port my component manually for each and ever new device (familiy). In turn, as a silicon vendor I can leverage tons of existing software components for my new device (such as RTOSes and communication stacks) right from the start by being CMSIS-compliant. I think this is what @schreinerman is refering to.

CMSIS-Drivers are another brick in that fundament. Such as CMSIS-Pack is for component distribution. Let me emphasis that we are in the process of feeding CMSIS-Pack technology into the new Linaro project Open-CMSIS-Pack.

I am happy to discuss pros and cons and learn about how CMSIS can be further improved.

Cheers,
Jonatan

@schreinerman
Copy link

@JonatanAntoni exactly. With an addition: You can only decide as a MCU vendor what you need and what is not essential for your product, if you get a training by the company from where you had bought the MCU core IP from. And that's in the today's world not only for chip designers, but for the software guys as well.

And as I know ARM is giving this training / assistance for free to MCU vendors, correct? They "just" need to get their engineers freed from daily work for some days, so they can do the training.

@WestfW
Copy link

WestfW commented Jul 21, 2021

being the maintainer or CMSIS I'd like to learn about your concerns regarding CMSIS-Core.

CMSIS-Core is fine. Well focused, and a good job of standardizing a bunch of the stuff that really ought to be standardized. I was shocked when my generic CM0 Systick code didn't compile in the Pico SDK, because that's exactly the sort of thing that CMSIS-Core is supposed to allow, and it does it well.

CMSIS-Driver seems to be a mess.
(It's a little hard to tell, because I don't think I've seen an implementation. But just looking at the documentation, it doesn't seem like something I'd be happy to use.)

I was just saying that it might be possible to look at CMSIS as a whole and get disillusioned WRT its usefulness, and thus omit even the useful parts (like Core.)

@schreinerman
Copy link

schreinerman commented Jul 21, 2021

@WestfW totally agree. Well ARM is very open in how they deal with feedback from the field. The problem is, very often there is no feedback from the field and everybody has his own style and philosophy. So freedom is a must, but a standard as well, so software development gets more agilely but in a professional shape. Arduino & co. are cool stuff for prototyping and hobbyists. The same for Raspberry Pico. But what is about the professional stuff?

At least for this reason ARM tries to get all parties at one table. CMSIS is not perfect and not the answer for everything. But it is already an answer for a lot of normally upcoming issues and can get even better with feedback which is often missing because there is no discussion between MCU vendor and ARM. I thought the Raspberry Foundation is different, because they are already very open and involved in a lot of discussions.

@teaalltr
Copy link

Any news?

@jptrainor
Copy link

Any news?

Fixed by #384

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.