Skip navigation

Blog

1 2 3 Previous Next

Software Development Tools

156 posts

This blog is an update of one I wrote a couple of years ago, referencing the latest FVP models provided with DS-5 (v5.24 at time of writing) and the latest pre-built Linaro distributions. It is intended for users new to DS-5 and/or users on Windows platforms, as the Linaro distributions assume a Linux host. Note that the pre-built images do not contain kernel debug information. If you wish to enable kernel awareness, you will need to rebuild appropriately. Application debug and other Linux aware features do not require this.

 

You should first download the appropriate pre-built software stack and file system to match your needs. For the below I downloaded fvp-latest-oe-uboot.zip and the OpenEmbedded LAMP filesystem. Unzip these files to your host machine.

 

Open the DS-5 Eclipse GUI, and select Run → Debug Configurations, to set up the debug session. Select DS-5 Debugger from the list on the left hand side, and click on New launch configuration. You can name this configuration to anything suitable. Locate the Base_AEMv8Ax1 (or Base_AEMv8x4) FVP (use Filter platforms text box to help), and drill down to the Debug ARMAEMv8-A level. If you have kernel debug symbols available I recommend selecting from the Linux Kernel and/or Device Driver Debug branch (more on this later).

 

dc1.png

We now need to use the Model parameters to instantiate the model appropriately for the Linaro images. Within the packages you downloaded above, you will find a run_model.sh script which is a Linux host script for launching this model stand alone with these files. We will use this as the basis for the parameters that DS-5 will pass. You can simply copy and paste the below to a text editor, fix the paths to the appropriate files to match their location on your host, to then paste to the Model parameters field. For more information on these options, see the FVP documentation.

 

--parameter bp.secure_memory=0

--parameter cluster0.NUM_CORES=1

--parameter cache_state_modelled=0

--parameter bp.pl011_uart0.untimed_fifos=1

--parameter bp.secureflashloader.fname="\\path\to\bl1.bin"

--parameter bp.flashloader0.fname="\\path\to\\fip.bin"

--data cluster0.cpu0="\\path\to\\Image"@0x80080000

--data cluster0.cpu0="\\path\to\\fvp-base-gicv2-psci.dtb"@0x83000000

--data cluster0.cpu0="\\path\to\\ramdisk.img"@0x84000000

--parameter bp.ve_sysregs.mmbSiteDefault=0

--parameter bp.virtioblockdevice.image_path="\\path\to\\<filesystem>.img"

--parameter bp.smsc_91c111.enabled=true

--parameter bp.hostbridge.userNetworking=true

--parameter bp.hostbridge.userNetPorts="5555=5555,8080=8080,22=22"

 

Go to the Debugger tab, and select Connect Only. If you have debug symbols available for the image, I recommend loading the symbols via the Execute Debugger Commands panel. Note that the kernel runs at Exception Level EL1, and so the symbols need to be loaded to this level. To do this, use the command:

 

add-symbol-file "\\path\to\vmlinux" EL1N:0

 

You should now be able to launch the model (by clicking on Debug). Click the run button, and the model should boot directly into Linux.

 

linux.png

 

Features such as Kernel Awareness (if kernel symbols loaded), Remote System Explorer (RSE) View, and Application Debug will be available, just as per my previous blog. I would also highlight some general improvements we have made to the GUI since that blog was written. Note for using RSE, you need to first set a password for root ("passwd root" on the Linux command line), then create an RSE Linux connection to "localhost", configured for ssh files.

 

rse.png

For the impatient

 

If you ever had to do with CMSIS RTOS API and did not enjoy it, or if you felt it like a straitjacket compared to your native RTOS, well, rest assured, your're not alone. The good news is that your experience matters and you can help improve CMSIS RTOS API. Go to GitHub Issues and comment on any of the existing issues, or open new ones.

 

Screen Shot 2016-04-17 at 20.18.18.png

 

The story

 

ARM, thumbs up for the CMSIS RTOS idea!

 

First of all I have to confess that I was a big supporter of the general idea of a common CMSIS RTOS API, from the moment I first read about it. However, as big as my expectations were, as big was my dissapointment when the specs went out.

 

Some CMSIS RTOS API considerations

 

From my point of view, the main problems with the CMSIS RTOS API are:

 

  • no POSIX compliance
  • not C++ friendly

 

Please note that I did not ask for C++ APIs, the plain C APIs should be perfectly fine, I just prefered the APIs to be designed by someone who thinks in C++, not in C (and as such knows how to avoid the usual mess that unstructured C programs bring, especially in the embedded world); unfortunately ARM seems to have no C++ specialists in their design teams.

 

The CMSIS++ proposal

 

Given this situation, and seeing that ARM had no plans for a C++ redesign, by the end of 2015 I started to think of CMSIS++, as a C++ POSIX compliant proposal for a future generation of CMSIS. In March 2016 the project was publicly announced in the ARM Connected site.

 

Some CMSIS RTOS API issues

 

The initial CMSIS++ attempt was to simply rewrite the original CMSIS RTOS API in C++. However, while starting to walk on this path, I encountered many problems, and noticed many differences from the POSIX and ISO C/C++ specs. At a certain point I realised that the current design is broken beyound repair, and a reset is required, otherwise the approach will not work.

 

Restarting from scratch, the focus moved from CMSIS to POSIX and ISO.

 

During the design and development phases, I kept a log of issues that I identified and addressed in the CMSIS++ proposal.

 

Some were difficulties in understanding the CMSIS RTOS API, due to documentation issues, some are functional issues that make using the original API not very convenient, and some are suggestions for missing features.

 

The POSIX compliance issues are:

 

  • Use POSIX error codes (#65)
  • Use explicit separate calls for different waiting functions, like lock(), try_lock(), timed_lock() (#45)
  • Add normal (non-recursive) mutex (#53)
  • Add a mechanism to wait for a thread to terminate (#50)
  • For message queues, make the message size user configurable (#70)
  • For message queues, add message priorities (#72)
  • Make osSemaphoreWait() return errors, not counts (#56)
  • Deprecate or remove the unused thread_id parameter in osMessageQCreate()/osMailQCreate() prototypes (#61)

 

Other functional issues are:

 

  • Avoid the heavy use of macros (to define objects and to refer to them) (#36)
  • Do not mandate the use of a dynamic allocator (for stack, queues, etc) (#37)
  • Add support for critical regions (interrupts & scheduler) (#38)
  • Avoid mixing time durations (in milliseconds) with timer counts in ticks (#39)
  • Add a separate RTC system clock (#40)
  • Add os_main() to make the use of a main thread explicit (#41)
  • Add support for a synchronised public memory allocator (#42)
  • Avoid returning agregates (like osEvent) (#43)
  • Extend the range for osKernelSysTick() (#44)
  • Make the scheme to assign names to objects more consistent (#46)
  • Add missing destructor functions to all objects (#47)
  • Extend the range of priority levels (#49)
  • Add a mechanism to enumerate all registered threads (#51)
  • Allow to explicitly define the semaphore max count (#55)
  • Add a method to wait for a memory pool block to become available (#57)
  • Fix non-portable message type in osMessagePut() (#60)
  • Fix osMessagePut()/osMailPut() inconsistent error when called from ISR (#62)
  • Mail queues, as separate objects, are redundant (#63)
  • Add typedefs for all different types used in prototypes (#66)
  • For all objects, add reset functions to return the object to initial status (#67)
  • For mutex, add a method to get the owner thread (#68)
  • For memory pools, add more accessors to get pool status (#69)
  • For message queues, add more accessors to get queue status (#71)

 

The documentation issues are:

 

  • Explain that thread functions can return (#48)
  • Explain the mutex behaviour (recursive vs normal) (#52)
  • Clarify the specs for binary vs counting semaphores (#54)
  • Fix the data type used in osMessageQDef() example (#58)
  • Fix misplaced thread id parameter for message queue (#59)

 

CMSIS RTOS API v2

 

Somehow acknowledging the initial design problems, ARM announced working on CMSIS RTOS API v2. To my pleasant surprise, ARM seems to have deprecated the initial macro based object creation mechanism (probably one of the most annoying features of the RTOS API v1).

 

In the new proposal ARM also gave up returning aggregate objects, extended the priorities range, added explicit normal/recursive mutex objects, renamed some objects and generally kept very few features from the initial specification, so a design reset seems possible.

 

However, based on the CMSIS++ experience, there are still more design decisions required to bring the new RTOS v2 closer to POSIX and ISO, for example using the POSIX error codes, using the POSIX explicit separate calls for different waiting functions (like lock(), try_lock(), timed_lock()), etc.

 

Feedback welcomed

 

So, if you would like to express your support for POSIX compatibility, or generally to have a better CMSIS RTOS API, please go to GitHub Issues and comment on any of the existing issues (especially those marked with Help Wanted), or open new tickets with your own suggestions.

 

More info

 

CMSIS is an ARM technology, now also available as a GitHub project.

 

CMSIS 5 announcement.

 

CMSIS++ is an open source project, maintained by Liviu Ionescu.

The main source of information for CMSIS++ is the project web.

April 2016 indeed came with some nice surprises related to project downloads (probably not exactly in the spirit of the previous post related to the project future): the SourceForge statistics revealed more than 3.200.000 files downloaded since the project revival, in the second half of 2013:

 

201603-3.2M-SF.png

The counters include all downloaded files, with the Eclipse updates (which accounts to multiple files for one update) taking the largest share, but also counting the packed archives, and the additional tool packages (Windows Build Tools, OpenOCD, QEMU, etc).

 

On the other hand, it should be noted that, considering the project migration to GitHub in Sep. 2015, the actual figures might be even higher (but this cannot be quantified, since GitHub does not provide any download statistics).

 

Otherwise the project is fine, with many amazing features planned for 2016 (mainly related to extending the use of software packages, both in the Packs Manager and in a future project wizard to use the packs content, and the integration with CMSIS++).

 

Many thank to all those who use, appreciate and support the project!

Considering the recent download trend, after a long and difficult consideration, the decision that it is no longer worth to further maintain the GNU ARM Eclipse project was finally made, and all future development activities will inevitably come to an end. The decision will be effective immediately, as of today, April 1st, 2016.

 

All Eclipse users are sincerely advised to switch to Keil MDK or IAR Embedded Workbench, definitely the best development environments available in the industry.

 

The unfortunate Linux and OS X users are advised to seriously consider migrating back to Windows 10, the best operating system ever.

 

Very Truly Yours,

 

Liviu

This blog was written by paulblack to explain some of the new features in DS-5 Development Studio v5.24.

 

In DS-5 v5.24, we’ve made changes to some of the debugger views. These changes are mostly designed to reduce the amount of non-essential information that the debugger shows, whilst providing easier access to information that is less frequently needed.  This results in a clearer debugger display and a significant boost in debugger performance, caused by reading less information from the target each time the display is updated.

 

We’ve also added a new script management system, which enhances the existing DS-5 scripting capabilities. It’s now possible to manage scripts in multiple named lists, provide multiple entry points in each script, and to create custom script configuration dialogs with named configuration profiles. This extends the powerful configuration methods that DS-5 already supports for debug and trace configuration and enables significant advances in DS-5 functionality, flexibility and usability. A small selection of example scripts is included in DS-5 v5.24. In future releases we’ll be significantly expanding the range of scripts to give enhanced debugger functionality.

 

Of course, DS-5 Ultimate Edition continues to provide support for the very latest ARM IP. In this release we have added support for Cortex-R8, Cortex-A32 and Cortex-A35, as well as support for generic ARMv8-M cores. We have also packaged the LDRAlite MISRA conformance tool, extended our Streamline templates and added two new example projects with bare-metal start-up code for Cortex-A72 and Cortex-R8. With the other changes that we have made in this release, DS-5 is now faster, more functional and easier to use than ever before.

 

This blog focuses on the enhancements we have made in the debugger views (changes to the Register view and the Debug Control view, with the addition of the new Stack view) and introduces our new script management system. For further information, please refer to the DS-5 Changelog.

 

Changes to DS-5 views

 

Debug Control View

In DS-5 v5.23, the Debug Control view showed core information for bare-metal connections and thread information for Linux kernel, RTOS support and Linux application debug. In v5.24 we’ve provided a new button at the left of the Debug Control view which lets you toggle between core and thread views whenever both types of information are available:

 

If you switch to the thread-based view, the current thread will be displayed along with closed lists for the active (scheduled) and non-scheduled threads:

 

However, all threads (scheduled and non-scheduled) can be displayed by opening the appropriate thread list:

 

Stack information has been moved out of the Debug Control view into a dedicated Stack view. You can open this view from the ‘Window->Show View’ Eclipse menu or you can right-click on a thread/core and select ‘Show in Stack’ from the pop-up menu:

 

The Stack view defaults to display only the highest 5 stack levels, but a single click will fetch additional stack frames:

 

A button at the top of the Stack view lets you configure the default number of stack frames to be displayed:

 

Registers View

In DS-5 v5.24 we’ve added two new buttons to the top of the Registers view. The first of these buttons opens an intelligent search box (also displayed using the keyboard shortcut Ctrl-F) which helps you to quickly and easily find any register. Double-click the register or register group that you want to display in the Register view:

 

The second of the new buttons (also available in the Variables and Expressions views) toggles all register values in and out of hexadecimal format:

 

 

This button has no effect on registers which are displayed in hexadecimal by default.

 

We’ve also provided an easy way for you to create custom register lists. You can create and manage custom register lists from the drop-down list box in the Registers view:

 

You can provide a descriptive name for each custom register list and add the registers that interest you:

 

When you select a custom register list from the drop-down selection, only the registers that you’ve added to the list will be displayed in the Registers view:

 

Use-Case Scripts

In DS-5 v5.24 we’ve introduced a new script management system to complement and extend the existing DS-5 scripting capabilities. The essential infrastructure and functionality is in place and we’ve provided a small selection of sample scripts to demonstrate the power, flexibility and ease of use of our new script manager. This is a brief introduction to the key concepts.

 

Our sample scripts can be found in the Scripts view. We call them “use-case” scripts because each script is focused on a particular “use-case”. Scripts contain configurable blocks of functionality aimed at specific tasks.

 

Each script can have multiple entry points, effectively multiple public functions. This lets you group related blocks of functionality into a single script. For each of our sample scripts we’ve provided documentation, including details of any configuration items. This documentation is taken from the script itself:

 

Each entry point can be associated with multiple configuration profiles. This is very similar to the configuration profiles that DS-5 already uses for debug connections. Right-clicking a profile lets you enter the configuration dialog:

 

The configuration dialog will look very familiar if you’ve already used the DS-5 DTSL configuration dialogs for debug and trace sessions. All of the controls in the dialog are soft-configured from the use-case script, so creating custom configuration panels is easy. The syntax used to create custom control dialogs is simple and easy to understand and is the same syntax that DS-5 already uses for DTSL configuration. It’s possible to create multiple named configuration profile for different use-cases:

 

Buttons at the top of the Scripts view let you create a new script, run a script entry point using a named configuration profile, edit an existing script, delete a script, refresh the scripts view, import scripts, create a new scripts directory and configure a profile. When you run a use-case script, the script is copied to the “Recent” area of the Scripts view. Output from use-case scripts appears in the Commands view.

 

DS-5 v5.24 is available to download now, we hope you enjoying using it! For any questions, comments or feedback please post below.

Considering the substantial interest that the initial CMSIS++ announcement stirred up, and the suggestions received, the project license was changed from the copyleft LGPL to the permissive MIT License.

 

This means you'll be able to use the CMSIS++ files in any commercial or open source projects without any limitations except preserving the included copyright and permission notice.

At embedded world 2016 ARM announced the smallest and lowest power ARMv8-A ARM Cortex-A32 processor, providing ultra-efficient 32-bit compute for the next generation of embedded products.

 

We also announced the latest high-performance real-time ARM Cortex-R8 processor, based on the ARMv7-R architecture. ARM Cortex-R8 introduces new features to meet the demands of next-generation storage device controllers and mobile communications with a particular focus on the upcoming 5G cellular wireless standard.

 

The ARM Compiler team has been working alongside the processor team to deliver the best compiler to support the new ARM Cortex-A32 and Cortex-R8. We're pleased to bring to you the ARM Compiler 6.4, which not only supports both new cores, but brings benefits to existing users with further performance improvements, full support for the Cortex-R family and enhance the support for ARMv8-M and ARMv7-M.

 

Full support for all ARM Cortex families

ARM Compiler 6.0 was introduced for the first time in April 2014, giving birth to the new LLVM-based ARM Compiler 6 series. The first release was limited to the ARMv8-A architecture and was mainly focused on partners working on cutting-edge technology. In July 2015, ARM Compiler 6.02 completed the support for ARM Cortex-A processors adding ARMv7-A. ARM Compiler 6.3, released last November, extended the list of supported devices to the ARM Cortex-M family.

 

Today, with ARM Compiler 6.4 supporting ARM Cortex-R, we are pleased to announce that the all three Cortex families Cortex-A,  -R and  -M are now fully supported!

Cortex-R8+Processor+Overview.png

The best class optimizer ARM Compiler and the new Cortex-R8 processor are the perfect combination to meet the performance requirements for the next-generation real-time applications.

 

Enhancing security with TrustZone® for ARMv8-M and XOM

Last November, ARM announced the introduction of the new ARMv8-M architecture for the next generation ARM Cortex-M processor family. ARM recognized the importance of security for ARM Cortex-M devices and made TrustZone available as a feature within the ARMv8-M architecture. TrustZone® creates two separate secure and non-secure worlds with the capability to quickly and efficiently switch between one and the other with a fine-grained control implemented at the hardware level.

ARM Compiler 6.4 fully supports the new TrustZone security extensions and it’s the ideal tool to develop secure software to protect your embedded or Internet of Things device.

Explore how to write secure code with ARM Compiler in the documentation.

Another important security feature implemented in some embedded devices is Execute-only memory (XOM). Execute-only memory allows only instruction fetches and blocks any attempt to read and/or write the protected area. The main benefit is the ability to protect your Intellectual Property by preventing executable code to be read by users. For example it’s possible to place the secure firmware in execute-only memory and load user code separately; the user code won’t be able to read the protected firmware, enhancing the security of your device.

With ARM Compiler 6.4 it is possible to use the option –mexecute-only to generate code without any data access to the code sections: read more about this feature on Infocenter.

 

ARM Compiler 6.4 is available to download today from the new developer.arm.com website. Alternatively, ARM Compiler 6.4 will be integrated in the next release of DS-5 v5.24.

 

Do have any questions? Feel free to reply to this blog post or send me an email, any feedback is welcome!

 

Ciao,

Stefano

TASKING projects for examples in the STM32Cube embedded software libraries

 

TASKING - Support for C compiler for ARM Cortex-M Series (VX-toolset)

 

Download the correct archive for the STM32 series and STM32Cube version. Unpack the archive and copy the resulting tree with evaluation boards into the STM32Cube Projects directory.

 

Some projects have known issues needing small changes, or are depending on third party libraries. A readme in the root of the archive will list these issues and describe possible workarounds. An additional archive is supplied which contains copies of the relevant STM32Cube sources with those workarounds applied. Optionally unpack this archive and copy the resulting tree over the sources in the STM32Cube directory.

Overview

 

CMSIS++ is a portable, vendor-independent hardware abstraction layer intended for C++/C embedded applications, designed with special consideration for the industry standard ARM Cortex-M processor series. Read "CMSIS++" as "the next generation CMSIS", "CMSIS v2.0", or, more accurately, "C++ CMSIS".

 

Major features and benefits

 

Written in C++ but with C wrappers for full C support

 

The original ARM/Keil name stands for Cortex Microcontroller Software Interface Standard, and the CMSIS++ design inherits the good things from ARM CMSIS, but goes one step further and ventures into the world of C++; as such, CMSIS++ is not a C++ wrapper running on top of the ARM CMSIS APIs, but a set of newly designed C++ APIs, with C APIs supported as wrappers on top of the native C++ APIs.

 

Close adherence to standards (POSIX and ISO)

 

The first iteration of CMSIS++ was a direct rewrite in C++ of ARM CMSIS, but later most of the definitions were adjusted to match the POSIX IEEE Std 1003.1, 2013 Edition and the ISO/IEC 14882:2011 (E) – Programming Language C++ standards.

As such, CMSIS++ RTOS API is no longer a wrapper over Keil RTX (as ARM CMSIS unfortunately was), but a wrapper over standard threads and synchronisation objects.

 

Compatibility with existing ARM CMSIS

 

Although fully written in C++, the current CMSIS++ RTOS API, implemented on top of the FreeRTOS scheduler, and accessible via the C wrapper, was the first non-Keil RTOS that passed the recently released CMSIS RTOS validation suite.

 

The CMSIS++ RTOS APIs

 

There are many components in the original CMSIS, but the major ones that benefit from C++ are RTOS and Drivers. Since everything revolves around the RTOS API, the C++ RTOS API was the first CMSIS++ API defined and is presented here in more detail.

Under the CMSIS++ RTOS APIs umbrella there are actually several interfaces, two in C++, two in C and one internal, in C++. The relationships between them is presented below:

cmsis-plus-rtos-overview.png

 

The native RTOS C++ API

 

This is the native RTOS interface, implemented in C++, and providing access to the entire RTOS functionality.

The classes are grouped under the os::rtos namespace, and, to access them, C++ applications need to include the <cmsis-plus/rtos/os.h> header.

Objects can be instantiated from native classes in the usual C++ way, and can be allocated statically, dynamically on the caller stack or dynamically on the heap.

Inspired by the POSIX threads usage model, all CMSIS++ native objects can be instantiated in two ways:

 

  • a simple, minimalistic, default way, with a default constructor, or, if not possible, a constructor with a minimum number of arguments.
  • a fully configurable, maximal way, by using a set of specific attributes, passed as the first argument to a separate constructor.

 

For example, to create a thread with default settings, only the pointer to the thread function and a pointer to the function arguments need to be specified, while a thread with custom settings can also have a custom priority, a static stack, and possibly other custom settings.

 

Here is a short example with a thread that counts 5 seconds and quits:

 

#include <cmsis-plus/rtos/os.h>
#include <cmsis-plus/diag/trace.h>

using namespace os;

// Define the thread function.
// Native threads can have only one pointer parameter.
void*
func(void* args)
{
  for (int i = 0; i < 5; i++).
    {
      trace::printf("%d sec\n", i);

      // Sleep for one second.
      rtos::Systick_clock::sleep_for(rtos::Systick_clock::frequency_hz);
    }
  return nullptr;
}

// In CMSIS++, os_main() is called from main()
// after initialising and starting the scheduler.
int
os_main(int argc, char* argv[])
{
  // Create a new native thread, with pointer to function and no arguments.
  // The thread is automatically destroyed at the end of the os_main() function.
  rtos::Thread th { func, nullptr };

  // Wait for the thread to terminate.
  th.join();

  trace::puts("done.");
  return 0;
}

 

The native CMSIS++ thread is basically a POSIX thread, with some additional functionality (see the os::rtos::Thread reference page for more details).

Similarly, synchronisation objects can be created with the usual C++ approach; for example a piece of code that uses a mutex to protects a counter looks like this:

 

#include <cmsis-plus/rtos/os.h>

// Protected resource (a counter).
typedef struct {
  int count;
} res_t;

// Alloc the resource statically.
res_t res;

// Define a native mutex to protect the resource.
rtos::Mutex mx;

void
count(void)
{
  mx.lock();
  // Not much here, real applications are more complicated.
  res.count++;
  mx.unlock();
}

 

The ISO C++ Threads API

 

The CMSIS++ ISO C++ Threads API is an accurate implementation of the ISO C++ 11 standard threads specifications.

With the ISO standard threads defined as wrappers over POSIX threads, and with the CMSIS++ native threads functionally compatible with POSIX threads, the implementation of the CMSIS++ ISO threads was quite straightforward.

The classes are grouped under the os::estd namespace, and, to access them, C++ applications have to include headers from the cmsis-plus/iso folder, like <cmsis-plus/iso/thread>. The namespace std:: and the standard header names (like <thread>) could not be used, to avoid clashes with system definitions when building CMSIS++ applications on POSIX host systems. The e in estd stands for embedded, so the namespace is dedicated to embedded standard definitions.

 

A similar example using the standard C++ threads:

 

#include <cmsis-plus/iso/thread>
#include <cmsis-plus/iso/chrono>
#include <cmsis-plus/diag/trace.h>

using namespace os;
using namespace os::estd; // Use the embedded version of 'std::'.

// Define the thread function.
// Thanks to the magic of C++ tuples, standard threads
// can have any number of arguments, of any type.
void*
func(int max_count, const char* msg)
{
  for (int i = 0; i < max_count; i++).
    {
      trace::printf("%d sec, %s\n", i, msg);

      // Sleep for one second. <chrono> is very convenient,
      // notice the duration syntax.
      this_thread::sleep_for (1s);
    }
  return nullptr;
}

// In CMSIS++, os_main() is called from main()
// after initialising and starting the scheduler.
int
os_main(int argc, char* argv[])
{
  // Create a new standard thread, and pass two arguments.
  // The thread is automatically destroyed at the end of the os_main() function.
  thread th { func, 5, "bing" };

  // Wait for the thread to terminate.
  th.join();

  trace::puts("done.");
  return 0;
}

 

Most of the goodies of the C++ 11 standard can be used, for example RAII mutex locks, condition variables, lambdas:

 

#include <cmsis-plus/iso/mutex>
#include <cmsis-plus/iso/condition_variable>

using namespace os;
using namespace os::estd;

// Protected resource (a counter and a limit).
typedef struct {
  int count;
  int limit;
} res_t;

// Alloc the resource statically.
res_t res { 0, 10 };

// Define a standard mutex to protect the resource.
mutex mx;
// Define a condition variable to notify listeners and detect limits.
condition_variable cv;

// Increment count and notify possible listeners.
void
count(void)
{
  unique_lock<mutex> lck(mx); // Enter the locked region.

  res.count++;
  cv.notify_one();

  // No need to explicitly unlock, done automatically.
}

// Return only when count reaches the limit.
void
wait_for_limit()
{
  unique_lock<mutex> lck(mx); // Enter the locked region.

  cv.wait(lck,
          []{ return (res.count >= res.limit); }
  );
}

 

The new CMSIS++ RTOS C API

 

Although fully written in C++, CMSIS++ also provides a C API, to be used by C applications. Yes, that's correct, plain C applications can use CMSIS++ without any problems. Only that function names are a bit longer and some of the C++ magic (like running the constructors and the destructors) needs to be done by hand, but otherwise the entire functionality is available.

The C API is defined in the <cmsis-plus/rtos/os-c-api.h> header.

 

The same simple example that counts 5 seconds and quits, in C would look like:

 

#include <cmsis-plus/rtos/os-c-api.h>
#include <cmsis-plus/diag/trace.h>

// Define the thread function.
// Native threads can have only one pointer parameter.
void*
func(void* args)
{
  for (int i = 0; i < 5; i++).
    {
      trace_printf("%d sec\n", i);

      // Sleep for one second.
      os_systick_clock_sleep_for(OS_INTEGER_SYSTICK_FREQUENCY_HZ);
    }
  return NULL;
}

// In CMSIS++, os_main() is called from main()
// after initialising and starting the scheduler.
int
os_main(int argc, char* argv[])
{
  // Manually allocate space for the thread.
  os_thread_t th;

  // Initialise a new native thread, with function and no arguments.
  os_thread_create(&th, NULL, func, NULL);

  // Wait for the thread to terminate.
  os_thread_join(&th, NULL);

  // Manually destroy the thread.
  os_thread_destroy(&th);

  trace_puts("done.");
  return 0;
}

 

The ARM CMSIS RTOS C API (compatibility layer)

 

Even more, the CMSIS++ C wrapper also implements the original ARM CMSIS API. This is a full and accurate implementation, since this API already passed the ARM CMSIS RTOS validation test.

To access this API, include the <cmsis_os.h> header provided in the CMSIS++ package.

 

#include <cmsis_os.h>
#include <cmsis-plus/diag/trace.h>

// Define the thread function.
// ARM CMSIS threads can have only one pointer parameter.
void
func(void* args)
{
  for (int i = 0; i < 5; i++).
    {
      trace_printf("%d sec\n", i);

      // Sleep for one second.
      osDelay(osKernelSysTickFrequency);
    }
  // ARM CMSIS threads can return, but there is
  // no way to know when this happens.
}

// The unusual way of defining a thread, specific to CMSIS RTOS API.
// It looks like a function, but it is not, it is a macro that defines
// some internal structures.
osThreadDef(func, 0, 1, 0);

// In CMSIS++, os_main() is called from main()
// after initialising and starting the scheduler.
int
os_main(int argc, char* argv[])
{
  // Initialise a new ARM CMSIS thread, with function and no arguments.
  osThreadCreate(osThread(func), NULL);

  // Since ARM CMSIS has no mechanism to wait for a thread to terminate,
  // a more complicated synchronisation scheme must be used.
  // In this test just sleep for a little longer.
  osDelay(6 * osKernelSysTickFrequency);

  trace_puts("done.");
  return 0;
}

 

The CMSIS++ RTOS Reference

 

The entire CMSIS++ RTOS interface is fully documented in the separate site, available in the project web :

cmsis-plus-rtos-reference.png

More CMSIS++ components

 

In addition to the RTOS APIs, CMSIS++ also includes:

 

  • CMSIS++ Drivers - a C++ rewrite of CMSIS Drivers, with extensions;
  • CMSIS++ POSIX I/O - a layer bringing together access to terminal devices, files and sockets, via a unified and standard API, using open(), close(), read(), write() as main functions;
  • CMSIS++ Startup - a portable startup code, replacing non-portable vendor assembly code;
  • CMSIS++ Core - C++ API for the ARM Cortex-M processors core and peripherals;
  • CMSIS++ Diagnostics - a C++/C API providing support for diagnostics and instrumentation.

 

Conclusions

 

CMSIS++ is still a young project, and many things need to be addressed, but the core component, the RTOS API, is pretty well defined and awaiting for comments.

For now it may not be perfect (as it tries to be), but it definitely provides a more standard set of primitives, closer to POSIX, and a wider set of APIs, covering both C++ and C applications; at the same time it does its best to preserve compatibility with the original ARM CMSIS APIs.

 

Any contributions to improve CMSIS++ will be highly appreciated.

 

More info

 

CMSIS++ is an open source project, maintained by Liviu Ionescu.

The main source of information for CMSIS++ is the project web.

The Git repositories and all public releases are available from GitHub.

For questions and discussions, please use the CMSIS++ section of the GNU ARM Eclipse forum.

For bugs and feature requests, please use the GitHub issues.

 

Follow-ups

 

Christopher Seidl

CMSIS Version 5

Posted by Christopher Seidl Mar 2, 2016

CMSIS Version 5 - Status

 

CMSIS Version 5 will focus on improvements and further industry adoption. The license will be changed to the permissive Apache 2.0 license, to enable contributions from interested third parties.

 

Support for the new ARMv8-M architecture will be added as well as improvements for ARM Cortex-A/Cortex-M based hybrid devices (with a clear focus on Cortex-M interaction).

 

The CMSIS-RTOS API and RTX reference implementation with get several enhancements:

  • Dynamic object creation, flag events, C and C++ API, additional thread and timer functions
  • Secure and Non-Secure support, multi-processor support

 

CMSIS-Pack will get additions for generic example projects, project templates, and multiple download portals. It will also adopt the Flash loader technology from IAR Systems.

 

CMSIS Version 5 - Access

 

As announced on embedded world, the development repository of CMSIS Version 5 is now available on GitHub: https://github.com/ARM-software/CMSIS_5

 

ARM invites all interested parties to contribute and/or to provide feedback for the CMSIS project using GitHub.

 

Embedded

With ARM Development Studio, more commonly known as DS-5, ARM continues to extend support for the breath of advanced ARM based devices that are taking take the market by storm. One particular wave of innovation is an increase in heterogeneous CPU designs, where different classes of ARM processor are implemented on the same device. The NXP i.MX7 family of devices have such a design, implementing Cortex-A7 and Cortex-M4 CPUs, which DS-5 supports "out-of-the-box". In this blog, I will discuss the (simple) steps necessary to get the most out of DS-5 with i.MX7, but the information applies to most similar systems.

 

Compiling code depends greatly on the use case. Within DS-5, we provide two proprietary compilers, ARM Compiler 5, known as armcc, and the new ARM Compiler 6, known as armclang. Both are used for bare-metal or RTOS code (the freeRTOS example below builds with armcc). If building Linux, then gcc is used. Typically this is provided as part of the vendor BSP, else any other distribution, such as that provided by Linaro, While I won't dwell too much on the detail of building code, as this is generally closely linked to the code base itself, I link here (and here) to some related blogs from my colleagues.

 

For debug, we provide ready made configurations with DS-5 for i.MX7. Launch the DS-5 Eclipse GUI, and select (from the menu bar) Run → Debug Configurations... From there, highlight DS-5 Debugger on the left column, and click on the New Launch Configuration button. Give the configuration an arbitrary name for your convenience. You can use the 'Filter platforms' text box to search quickly for i.MX7. From there, select whether or not you want to connect to the Cortex-M4 or Cortex-A7 with this configuration. Let's select the Cortex-M4 first. Select your debug adapter (DSTREAM below), and then click the Browse button to locate your adapter (either on network or on USB).

 

m4_1.png

 

You will note the DTSL (Debug and Trace Services Layer) Options 'Edit...' button. This links to a pop-up to configure more advanced options of your debug session. Click this, and click the green + button to create a new set up. We recommend you create various different configurations for different use cases, to enable you to track your set up easily (you can give each a meaningful name).

 

For this platform, if you are connecting to a board fresh out of power up, you may need to select the "Release Cortex-M4 from reset" tickbox in the Cortex-M4 tab.  Conversely, if you are connecting to a system already running code on the Cortex-M4, this should not be set, as it will affect code execution. You can also optionally enable trace and other features here. Let's enable Cortex-M4 trace, and collect the trace into the ETF (Embedded Trace FIFO). Click OK to save.

 

m4_2.png          m4_3.png

 

Note the Debug Configurations pane tells you which DTSL set up you are using

 

m4_4.png

While in the Debug Configurations pane, in the Files tab, we can specify whether or not we are directly loading an image to the target (to execute from the beginning), or simply loading debug symbols to the debugger for code already running on the target. In this case, I am using the freeRTOS example provided by NXP.

 

m4_5.png

If loading directly, in the Debugger tab, select Debug from entry point, or Debug from symbol. If connecting to an already running target, select Connect Only

 

m4_6.png

 

Finally, if using an RTOS image, you can enable OS awareness from the pull down in the OS awareness tab (freeRTOS in this example)

 

m4_7.png

Click Apply to save, or Debug to connect as configured, and we should be able to debug from there. Note if you are debugging from main (or entry point) the RTOS is not yet initialized, so nothing is visible in the OS Data pane. Run further and stop and you will see this information populated. Below is an example of the type of views you can see in the debugger. If a certain pane is not visible (some of the below are not default), use Window → Show View.

 

m4_8.png

 

Similarly, we can repeat the above process to create a configuration for the Cortex-A7. For this CPU, the only real difference is if you wish to enable Linux kernel awareness, you select Linux Kernel and/or Device Driver Debug, rather than Bare Metal Debug, and selecting from the OS Awareness tab. You can see more information on the Linux awareness capabilities of DS-5 here. I would also highlight the MMU view, as being particularly useful for most Cortex-A7 debug use cases. However, what I really want to focus on is the capability DS-5 has to connect to both the Cortex-A7 and the Cortex-M4 simultaneously.

 

Above we created two independent debug configurations, one for the Cortex-A7, one for the Cortex-M4. We can connect the debugger to both at the same time. The only caveat is that both configurations need to have the same DTSL options selected, which makes sense, as that defines how the target is being set up. If you attempt to connect with different settings, you will get an error for incompatible configuration values. Once connected, you will notice that each view has a "Linked" icon. This means that the view is related to the currently selected connection in the Debug Control pane. You can click on this to select your connection (either Cortex-A7 or Cortex-M4 in this case), and lock the view to that CPU. For common views, such as Registers, we generally recommend opening two panes (via the New Registers View menu button within the pane), and lock one to each CPU. Below is an example screenshot showing such a set up. Note the memory view is set to Linked, and shows the Cortex-A7 memory view, as that is the connection selected in the top-left Debug Control pane

 

m4_9.png

 

By enabling simultaneous debug, you are better able to work out those challenging debug scenarios, where the behavior of one core affects the other. I hope this brief introduction shows you how to get started quickly and easily. For further reading I would also recommend the blogs of my colleagues Stephen and Jonathan.

Functional safety is a very important aspect for many industries and ARM DS-5 is the tool of choice for many partners working with safety critical products. The TÜV Certified ARM Compiler included in ARM DS-5 enables customers to develop safety-related software up to SIL-3 (IEC 61508) or ASIL-D (ISO 26262) without further qualification activities when following the recommendations and conditions documented in the Qualification Kit.

 

Originally established as collaboration between vehicle manufacturers, component suppliers and engineering consultancies, the Motor Industry Software Reliability Association (MISRA) guidelines have evolved as a widely accepted model for best practices by leading developers in sectors including aerospace, telecom, medical devices, defense, railway, and others. MISRA C and MISRA C++ are sets of software development guidelines for the C and C++ programming languages developed by MISRA with the aims to facilitate code safety, portability and reliability in the context of embedded systems.

 

LDRA and DS-5

Today at Embedded World, ARM announced the partnership with LDRA, member of the MISRA standard committee. The next version of DS-5 5.24 will integrate the MISRA checking tool LDRAlite™ for ARM® DS-5 software and will include a free 30 days evaluation version which can be extended to full version through LDRA.

The LDRAlite™ plugin integrates perfectly with the DS-5 development flow and it gives a powerful tool in the hand of the user who can perform analysis on the software project with just a few clicks, directly from the user interface.

LDRAlite™ gives also additional information on each violation found in the code; the MISRA rule is described with details and examples, simplifying the job of fixing the violation and improving the speed of development.

 

You can find more information on the LDRA website at http://www.ldra.com/LDRAlite-ARM: join the free Webinar on 22 March 2016 by registering on the link at the end of the LDRAlite page.

 

Are you at Embedded World 2016 in Nürnberg this week? Come and talk to us at the ARM Booth in Hall 5 / 338: You can find LDRAlite™ for ARM DS-5 Software and many other examples of ARM solutions.

 

Ciao,

Stefano

Join us for a webinar on 11th February on using STM32CubeMX with Keil MDK.

 

Abstract

STMicroelectronic's STM32CubeMX is a powerful graphical software configuration tool which enables users to generate C initialization code using a wizard interface. In this webinar, you can learn how to use it together with Keil MDK to set up and maintain projects for the STM32 microcontroller families.

STM32CubeMX_Keil_Webinar.jpg

Speaker Biography

This webinar will be presented by Matthias Hertal, Product Specialist MCU Development Tools. Matthias has a deep knowledge about Keil MDK, ARM's development suite for Cortex-M based microcontrollers. With 15 years of experience in the microcontroller tools market he knows a solution for almost every development requirement.

 

Details

Register here. You can join the session by using a Mac, PC or a mobile device.

 

  • Start Time:

    11-Feb-2016 16:00 GMT (Europe/Dublin)
  • End Time:

    11-Feb-2016 16:45 GMT (Europe/Dublin)

 

Using STM32CubeMX with Keil MDK

Join us for a webinar on 16th February on advanced debug and trace on NXP TWR-K64F120M using ULINKpro.

 

Abstract

NXP’s Kinetis K64 MCU Tower System Module features an ARM Cortex-M4 based low-power MCU with 1 MB Flash, 256 KB SRAM, USB and Ethernet MAC. In this webinar, you will learn how to use ULINKpro to debug and trace embedded applications on this powerful development board.

 

Webinar_banner_20160216.png

 

Speaker Biography

This webinar is presented by christopherseidl, Technical Marketing Manager at ARM. Christopher has over ten year experience in ASIC design and ARM cores and is now member of the technical marketing team for Keil MDK, ARM's leading software development environment for Cortex-M based devices.

 

Details

Register here. You can join the session by using a Mac, PC or a mobile device.

 

  • Start Time:

    16-Feb-2016 16:00 GMT (Europe/Dublin)
  • End Time:

    16-Feb-2016 16:45 GMT (Europe/Dublin)

 

Advanced Debug and Trace on NXP TWR-K64F120M using ULINKpro

Overview

 

The GNU ARM Eclipse project includes a set of open source Eclipse plug-ins and tools to create/build/debug/manage ARM (32-bits) and AArch64 (64-bits) applications and static/shared libraries, using the latest GNU ARM GCC toolchains.

 

Eclipse Marketplace

 

Aiming to further improve the user experience while installing/updating the plug-ins, the GNU ARM Eclipse project was registered to Eclipse Marketplace:

eclipse-marketplace-home.png

Benefits

 

The main advantage of using the Eclipse Marketplace is a simplified install procedure, no longer requiring to manually enter the update site address.

 

The Install button

 

The Eclipse Marketplace not only provides a centralised index to locate projects, it goes one step further and provides a drag-and-drop browser button.

eclipse-marketplace-button.png

As seen above, the button can be included in any web page.

 

To use it, just drag-and-drop the button to a running Eclipse, and the plug-ins to install/update will be automatically identified:

 

eclipse-marketplace-features.png

If, for any reason, this does not work, it is always possible to search the Eclipse Marketplace manually, from within Eclipse menus:

 

eclipse-marketplace-search.png

More info

 

For more details about the GNU ARM Eclipse project, please refer to the project site http://gnuarmeclipse.github.io/.

Filter Blog

By date:
By tag:

More Like This