Embedded IDE in VSCode¶
BEWARE: BIG BLACK RABBITHOLE AHEAD. TL;DR I could get it to work. ASF/CMSIS framework stuff and OpenOCD programmer issues.
Introduction¶
I wanted a way to get out of Arduino IDE. Even get out of Arduino libraries. I’m hoping that VS code is an option. I know you can use VScode to program using the Arduino libraries using the vscode extension for Arduino. And that works fine. But still Arduino :-).
I could have gone the platform.io route. I should have. But didn’t.
After researching the net I found https://em-ide.com/ which is an embedded IDE For VSCode (c/c++ development environment for mcs51/stm8/cortex-m/riscv microcontrollers). It works on Windows, Linux and MacOS and basically an extension for VScode, and provided under MIT license on github. It doesn’t do debugging but according to the devs it should be possible to get debugger capabilities from other plug-ins, like: Cortex-Debug, STM8-Debug.
Note: I want to program ATSAM-D chips which are ARM Cortex processors.
Installation¶
The developer has clear documentation how to set things up. find it here.
Gist of it: In VSCode Extensions marketplace do a search on “eide” and install.
Next you will be asked to configure the toolchain.
I installed GNU Arm Embedded Toolchain (arm-none-eibi-gcc) because this is open source.
Click “Online”:
Next install the Cortex-Debug plugin.
Create a project¶
In the VSCode main screen, you can see in the walkthroughs section that there is a Embedded IDE startup button. Click it.
Now click on New Project:
and create an empty project. As I want to work on SAM-D chips, I’ll select Cortex-M:
You’re asked to enter a project name and the location where you want to save it. When done, you’ll see this popup. Click Continue:
You’ll get lots of VScode extension recommendations now.
"cl.eide",
"keroc.hex-fmt",
"xiaoyongdong.srecord",
"hars.cppsnippets",
"zixuanwang.linkerscript",
"redhat.vscode-yaml",
"IBM.output-colorizer",
"cschlosser.doxdocgen",
"ms-vscode.vscode-serial-monitor",
"dan-c-underwood.arm",
"marus25.cortex-debug"
Just sift your way through it and choose wisely. Majority is about syntax highlighting for various files that are going to be used, e.g. assemly, hex, linkerscripts, etc. Remember to restart VScode.
Eide has a project toolbar that should be visible. It is recommended to move it to the right sidebar of VSCode so the layout is more compact.
Configure the project¶
Now some stuff needs to be configured. See getting started/new project for more info.
Main thing that you want to have configured is to tell:
- What microcontroller framework do you want to use (if any)
- What compiler are you going to use
- what flasher (programmer) are you going to use
CMSIS framework¶
As I’m going to use a Cortex-M microcontroller, I figured I can use CMSIS: chip support packages. CMSIS is for Cortex based microcontrollers only.
BUT WARNING! BIG BLACK RABBIT HOLE AHEAD!
The Common Microcontroller Software Interface Standard (CMSIS) is a vendor-independent abstraction layer for microcontrollers. CMSIS simplifies software reuse and reduces the learning curve for microcontroller developers. (source)
in other words:
The CMSIS is a set of tools, APIs, frameworks, and work flows that help to simplify software re-use, reduce the learning curve for microcontroller developers, speed-up project build and debug, and thus reduce the time to market for new applications.
CMSIS started as a vendor-independent hardware abstraction layer Arm® Cortex®-M based processors and was later extended to support entry-level Arm Cortex-A based processors. To simplify access, CMSIS defines generic tool interfaces and enables consistent device support by providing simple software interfaces to the processor and the peripherals.
CMSIS is defined in close cooperation with various silicon and software vendors and provides a common approach to interface to peripherals, real-time operating systems, and middleware components. It is intended to enable the combination of software components from multiple vendors. source
CMSIS is open-source and collaboratively developed on GitHub.
According to the Eide manual:
The CMSIS pack optimizes Eide’s builder configs, flasher configs, debugger configs, RAM/ROM layout and peripheral components so you don’t have to do that yourself.
In my wordings: CMSIS is similar to the Arduino framework but then not from Arduino, but from the manufacturer of the microcontroller.
One of the things is that CMSIS contain header files (.h
files) with definitions of registers that you can use in your project. These definitions are “human readable” names of registers that you’ll find in the datasheet of your microcontroller. The definition “converts” this human readable name into numbers that the microcontroller understands.
Actually the Arduino framework uses CMSIS itself to implement support for Cortex microcontrollers! For example for the STM32 boards.
The big issue with CMSIS is that it’s intended as standardization and so every manufacturer will NOT use it as intended. Some do it all the way, others only partially, others say they are “compliant”. See here for a 10 year old discussion.
Big black rabbit hole¶
TL;DR: ASF3 framework deprecated, ASF4 framework deprecated, start.atmel.com deprecated, Atmel Studio/Microchip studio deprecated, MPLab Harmony is a big mess so do not touch it even with a long stick.
Atmel¶
Atmel was a microcontroller manufacturer of popular controllers like the AVR series (since 1996) like AT90S series, ATtiny series, ATmega series, AT32 series). And one of the first to license the ARM architecture (like the Cortex M0 SAMD series that I use). Atmel had their own programming IDE: Atmel Studio.
AND Atmel had their own… another IDE? Called Keil. That’s a compiler as well by the way. And it’s still there.
To provide support for the Cortex family, Atmel created ASF: Atmel Software Framework. A set of source files, libraries and reference projects that aid in application development for Atmel microcontrollers.
Actually when Neil shows a blinking LED using the ATSAMD11C14 he is using this framework:
//
// hello.D11C.blink.c
//
// SAMD11C LED blink hello-world
//
// Neil Gershenfeld 11/29/19
//
// This work may be reproduced, modified, distributed,
// performed, and displayed for any purpose. Copyright is
// retained and must be preserved. The work is provided
// as is; no warranty is provided, and users accept all
// liability.
//
#include <samd11.h>
#define LED (1 << 5) // define LED pin
void delay(uint32_t n) {
uint32_t i = 0;
while (i < n) ++i;
}
int main(void) {
SYSCTRL->OSC8M.bit.PRESC = 0; // set OSC8M clock prescaler to 1
REG_PORT_DIR0 |= LED; // set LED pin to output
while (1) {
REG_PORT_OUT0 |= LED; // turn on LED
delay(1000000); // delay
REG_PORT_OUT0 &= ~LED; // turn off LED
delay(1000000); // delay
}
}
You can see an #include <samd11.h>
. This file is actually part of ASF and amongst others it defines for example what REG_PORT_DIR0
actually means.
In this screenshot of Neils console, you can actually see the reference to ASF:
So this is ASF version 3.47, released august 2019.
Microchip¶
In 2016 Atmel (microcontroller manufacturer of ) was bought by Microchip for 3.6 billion US dollar. Microchip had their own microcontrollers going: the PIC family like the PIC16 and the PIC18 series. Microchip had their own programming IDE: MPLab.
After the purchase of Atmel, Microchip rebranded everything. Atmel studio became Microchip Studio. Atmel Software Framework (ASF) became Advanced Software Framework (ASF). And so forth and so on. And this became a big mess. Almost no URL still works. 404 not found all over the place when you search for ASF on microchip website. You can’t even download it anymore.
http://www.microchip.com/asf -> 404
http://www.microchip.com/development-tools/atmel-studio-7 -> 404
ASF kept on going to version 4 after version 3 was deprecated after V3.52.0. But ASF version 4 is depricated now as well. To use ASF4, at least to my understanding, you had to use start.atmel.com: an online configurator. But that one is deprecated as well.
Microchip want you to use MPLab. The code configurator is called MCC: MPLAB Code Configurator. Which you can by the way use in Microchip studio, not just in MPLAB. And from MCC Classic, we go to MPP Melody and from there to MPP Harmony. And by the way, remember Keil? It’s still there. What? I’m totally lost. I just wanted to program my SAMD without Arduino framework.
Sources:
microchip and atmel SAM what a mess
transitioning from Arduino IDE2 to Microchip studio
Continue CMSIS¶
I downloaded the CMSIS .pack file for the SAMD11 from ARM official website as this supports my SAMD11C14.
Next click on the green + sign next to Chip Support Package in the EIDE projects toolbar, click “From disk” and select the pack file:
Interestingly, the file I downloaded had the extension .atpack
instead of .pack
so I had to rename it before I could select it. But it worked:
Next, click the device icon in the Chip Support Package that you just “installed” and select the microcontroller that you want to work with. I’m going to use the ATSAMD11C14A.
You’re not there yet. This only adds the CMSIS files of this specific microcontroller family. But you also need the core files. You install these by right-clicking Chip Support Package and select Install CMSIS Core Headers:
Now I can check the “startup” peripheral component that will automatically add sam.h
to my project. This header file contains a lot of #defines
for all registers and other stuff that the SAMD11C14A has:
So far this is looking good.
Adding main source file¶
Now its time to add some code. This is done in a C or C++ source file. Either create main.c
or main.cpp
to start with. I’ll make a main.cpp
by right-clicking the project main folder and selecting New File and calling it main.cpp
:
I also need to add this file to the eide project tree, by right clicking Project Resources and adding this file:
By the way, there’s a template in the .pack
file that you can find in the .pack folder -> microchip -> SAMD11_DFP.2.6.76->templates->main.cpp:
/*
* $projectname$.cpp
*
* Created: $date$
* Author : $user$
*/
#include "sam.h"
int main(void)
{
/* Replace with your application code */
while (1)
{
}
}
I copied this into my own main.cpp
.
I want to blink an LED. So I naively copy Neils blink code (based on ASF) to main.cpp:
/*
* $projectname$.cpp
*
* Created: $date$
* Author : $user$
*/
//
// hello.D11C.blink.c
//
// SAMD11C LED blink hello-world
//
// Neil Gershenfeld 11/29/19
//
// This work may be reproduced, modified, distributed,
// performed, and displayed for any purpose. Copyright is
// retained and must be preserved. The work is provided
// as is; no warranty is provided, and users accept all
// liability.
//
#include <samd11.h>
#define LED (1 << 5) // define LED pin
void delay(uint32_t n) {
uint32_t i = 0;
while (i < n) ++i;
}
int main(void) {
SYSCTRL->OSC8M.bit.PRESC = 0; // set OSC8M clock prescaler to 1
REG_PORT_DIR0 |= LED; // set LED pin to output
while (1) {
REG_PORT_OUT0 |= LED; // turn on LED
delay(1000000); // delay
REG_PORT_OUT0 &= ~LED; // turn off LED
delay(1000000); // delay
}
}
}
Of course this doesn’t build because Neil is using ASF 3.47 which has the samd11.h
file. Which is missing because I use CMSIS.
So let’s, naively again, change it to sam.h
:
Of course that doens’t work. All defines are different. Where Neil can use for example REG_PORT_DIR0
, I can’t because this isn’t defined in the CMSIS package.
So now I’m getting totally lost and want to get out of this rabbit hole. What about finding documentation? Maybe here at Keil website?. Auch, that is a lot to sift through.
You know what? Let’s just get rid of the LED and see if I can compile just an empty main() file. Basically a program that does literally nothing.
/*
* $projectname$.cpp
*
* Created: $date$
* Author : $user$
*/
#include "sam.h"
int main(void)
{
/* Replace with your application code */
while (1)
{
}
}
Let’s see if this can be build.
Building¶
this gave me an error that it couldn’t find the linker script. I didn’t put it there, but the software automagically added a placeholder. And it couldn’t find the placeholder. Because it is… a placeholder. Clearing this field fixed things.
Now building works properly:
Flashing to the microcontroller (uploading)¶
Next is to upload this program to my microcontroller. This is called flashing. The flasher is responsible for doing this, so this needs configuring. There are different programmers (the physical devices that you connect to your microcontroller that you use to upload your program). Choose the one you have:
JLink -> for Cortex-M chips, commercial, expensive, widely used.
STLink -> for STM32 chips, commercial, not that expensive.
pyOCD -> an open source Python based tool and package for programming and debugging Arm Cortex-M_ microcontrollers with a wide range of debug probes. So you still need to have a piece of hardware to use this (called a debug probe).
OpenOCD -> an open source software tool for programming and debugging. Again this is software only so you still need the debug probe.
pyOCD supports the following debug probes:
- CMSIS-DAP v1 (HID) or v2 (WinUSB), including:
- Atmel EDBG/nEDBG
- Atmel-ICE
- Cypress KitProg3 or MiniProg4
- DAPLink based debug probe, either on-board or standalone
- Keil ULINKplus
- NXP LPC-LinkII
- NXP MCU-Link
- WCH-Link (1a86:8011, 2a86:8011 and others)
- PE Micro Cyclone and Multilink
- Raspberry Pi Picoprobe
- SEGGER J-Link
- STLinkV2 or STLinkV3, either on-board or the standalone versions
OpenOCD supports a lot of debugging probes. OpenOCD is discussed in fabacademy. When you program a SAMD in the Arduino environment, your most probably using the ArduinoCore-fab-sam. This uses OpenOCD and works with the Quentorres. So I’m going to select this.
OpenOCD needs to be installed. Embedded-IDE will do this for you as soon as you hit the “Program Flash” button. If OpenOCD is not yet installed, it’ll do it for you:
Embedded-IDE needs a config file to be able to know what to do. See this part of their manual.
If openOCD is installed, you can select one of the config files that comes with openOCD:
I’m going to select the at91samdXX.cfg
because that’s my microcontroller family.
I will also have to select the interface (the type of debugger probe). I’m going to use the Quentorres that I’ve programmed to be a programmer. It’ll act as a CMSIS-DAP programmer (because it uses freeDAP):
And here the big brick wall. Programming fails. No clue why… I can see that the quentorres programmer is being addressed. I can see my samd board is reset. But then? A Verify failure? That is I think because it didn’t program it…
Open On-Chip Debugger 0.12.0-rc2-g7a1adfbec (2022-11-06-10:08)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Warn : Interface already configured, ignoring
Info : auto-selecting first available session transport "swd". To override use 'transport select
<transport>'.
none separate
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: JTAG supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Serial# = 2E56BCAA
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : Connecting under reset
Info : CMSIS-DAP: Interface ready
Info : clock speed 400 kHz
Error: BUG: can't assert SRST
Info : SWD DPIDR 0x0bc11477
Info : [at91samd11c14a.cpu] Cortex-M0+ r0p1 processor detected
Info : [at91samd11c14a.cpu] target has 4 breakpoints, 2 watchpoints
Info : starting gdb server for at91samd11c14a.cpu on 3333
Info : Listening on port 3333 for gdb connections
[at91samd11c14a.cpu] halted due to debug-request, current mode: Thread
xPSR: 0x81000000 pc: 0x00001aa4 msp: 0x20001000
** Programming Started **
Info : SAMD MCU: SAMD11C14A (16KB Flash, 4KB RAM)
Warn : no flash bank found for address 0x00008000
Warn : no flash bank found for address 0x0001817c
** Programming Finished **
** Verify Started **
Error: error executing cortex_m crc algorithm
Info : SWD DPIDR 0x0bc11477
Error: Failed to read memory at 0x00008000
embedded:startup.tcl:1516: Error: ** Verify Failed **
in procedure 'program'
in procedure 'program_error' called at file "embedded:startup.tcl", line 1577
at file "embedded:startup.tcl", line 1516
LOST.
AGAIN.
The end¶
This is how far I can take it now. Guess it’ll end here for now. Maybe I’ll get back to this. Maybe not. I want to get out of this rabbit hole. Right now.