For some time I have been working on a Wi-Fi connected Cortex-M debug probe and there have been several prototype PCBs designed and built. Last week I received the latest prototypes from PCBWay and the first of that batch of assemblies is testing and working.
The video below shows a short session using GDB to communicate with an STM32F4xx MCU. The Wireless Debug Probe (WDBP) is being powered by a LiPoly battery pack and the target MCU is powered by the WDBP. You will note that the initial scan to connect to the target fails because WDBP had not been configured to power it.
Also note, the report of the battery voltage in addition to the target voltage.
WDBP is based upon the Black Magic Probe (BMP) and implements all the features of BMP. In addition to the wireless connection WDBP offers a USB connection, just like the original BMP. WDBP is open source software and hardware, and the design will be published publicly on it is launched as a product.
A crowd funding campaign is being prepared to launch WDBP.
Flutter is a new mobile application development framework, it is open source, and provides a common codebase for both Android and iOS development. I have a project that was originally started with Android Studio and Java, just for the Android platform. However, since I didn’t want to have to learn a completely new framework for iOS I decided to rewrite the app using Flutter.
The app requires authentication of users and the Java version used Firebase-Auth. My initial challenge with starting to build the app with Flutter was to write the code to sign up and login users using Firebase-Auth. This proved much more challenging than expected, after adding the Flutter Firebase-Auth dependency to the project it failed to build, giving many errors like “cannot find symbol import androidx.annotation.NonNull”.
Searching revealed a proposed solution,use the Android Studio “Migrate to AndoidX” feature. Unfortunately, this did not resolve the issue. In fact the migration process failed, reporting, “No Usages Found in the Project”.
After several hours of research and code changes it became apparent that the migration wizard was failing because there were no references in the project that needed migrating. When comparing a previous project where the migration had worked I found that there were a couple of options not setup in the “gradle.properties” file. The following entries were made and the project built correctly:
One of the issues I have encountered when testing circuit boards is finding where on the board a particular part is located. Typically I open the PCB layout (Kicad PCBnew) on my computer and use the zoom feature to scroll around to find the part I am looking for. One can also use the find feature of the layout editor, however, I find that doing doesn’t always give you a wide enough view of the board, the tool focuses in on the part found.
Also, if you are assembling a PCB and want to know the location of all the 1K resistors it is difficult to do with the layout editor.
Both of the above were why I was so pleased to discover this excellent plugin for Kicad’s PCBnew. It is an open source plugin available for download from Github. If you are a Kicad user give it a try … I think you will love it!
All developers spend large amounts of time waiting for their projects to compile/build. If you are an Android developer then you are probably acutely aware of this. Build times for Android apps can take a long time once the app grows in complexity and size.
Over the last several months I have visited the idea of replacing the hard disk on my development computer with a Solid State Drive (SSD), however, I backed off from doing it because in the past changing the boot drive of a computer has proven to be a painful and time-consuming experience. Having just finished my capstone project for my Android Developers Nanodegree it seemed like an opportune time to take the leap and purchase an SSD.
The first step was to read the reviews for the best SSDs of 2018, from the articles I found it was apparent that the market leader is Samsung. I chose the Samsung 860 EVO, a 1TB drive.
As I mentioned earlier was concerned about swapping out the main hard disk on my development computer, however, after a little research I discovered that Samsung has a Data Migration application for Windows boot drives. I downloaded both the software and the user guide.
Following the wizard-style dialogs in the migration software was simple and while it took several hours to perform the migration it went without any issues. All that remained was to swap the boot drive and SSD cables and the computer booted (very quickly) from the SSD. The overall speed of the computer was very much faster, I have a large number of services and background applications that need to be started and this typically meant leaving the computer for several minutes after a boot for it to “settle down.” Not so with the SSD.
A final test was to move one of my VMWare virtual machines onto the SSD and fire it up. Once again the boot time and the responsiveness of the VM were noticeably improved.
In closing I would say that if you are a serious developer then investing in an SSD will improve your productivity, although, beware it may reduce the time you have to pour another coffee during builds!
When trying to learn about new features and components that are available for Android development a search of YouTube reveals hundreds, if not thousands of video tutorials. Unfortunately many are of such poor quality they are just noise hiding the best videos. Often, these so-called video “tutorials” are simple screen captures with either a bad audio track or no audio at all. A tutorial to be valuable must include context and background and reveal not only the “how” but the “why” of the principle being taught. These screen captures are often full screen videos of the user’s desktop, seeing and reading the text on screen is just about impossible.
One step up from this are the videos that overlay these captures with a window into which the “instructor” types what they are doing, again, not a tutorial in my opinion.
Imagine my pleasure when eventually I found what I believe to be one of the best series of Android video tutorials I have discovered. The channel is “Coding in Flow“, the author, Florian, also has a blog on their website. Not only is Florian an excellent instructor, his videos are of outstanding quality and clarity. While using Android Studio the video pans and zooms so that it is absolutely clear which menu or button is being used. Florian explains each step of the process clearly, or, if a technique is a little too deep for the current video, he refers to other videos in his channel.
I cannot recommend this YouTube channel strongly enough, please take a look today.
While working on my Udacity Android Developer Nanodegree recently I ran into an issue with the widget that was required as a part of a course project design. The app being developed was a recipe app and part of the requirements was that it offered a widget to display the ingredients of a selected recipe. The app was developed using Android Studio and the built-in debugger and access to many different device emulators made the initial debug of the app and the widget straight forward. However, just prior to submitting my project for review I was doing some final testing, checking for as many edge cases as possible and I ran into an exception when the widget was added to the home screen.
The scenario causing the exception was the instantiation of the widget when the app was not running. This presented a big problem from the debugging perspective because in order to attach the debugger to the code some process that is a part of the code base needed to be running, a chicken and egg situation for sure!
After much Internet searching I finally found a solution that enabled me to debug the widget under this condition. The technique exploits the fact that when any part of a project is loaded and running on a device/emulator, the whole code base is available to be debugged. The trick was to get the project code loaded onto the device/emulator without starting the main app activity. Once one is aware of that requirement is fairly easy to image how to arrange this … create a new empty activity and set in as the startup activity in the project manifest. When the app is then run on the device/emulator it is possible to set breakpoints in the widget startup code and when the widget is instantiated the breakpoints will be triggered and allow the controlled debug of the exception.
In my case the widget was making assumptions about some data that were only valid when the main app was running. Once identified the solution was easy and the original main activity could be re-enabled as the startup activity in the app manifest.
The STM32 range of Microcontrollers have a built in bootloader that may be used to update the firmware running on the MCU. Depending upon the STM32 variant being used this update may be done using a USART, USB, or SPI interface. The usual way of triggering the bootloader is by using the BOOT1 and BOOT0 pins of the MCU:
Typically the BOOT1 pin is held high on the hardware and bootloader mode is controlled by a hardware jumper on BOOT0. These pins are sampled upon restart of the MCU and require access to a reset button (or power-cycle) and the BOOT0 jumper.
For devices that are deeply embedded in a system accessing the a hardware jumper for the BOOT0 control may not be practical. Indeed, on some systems where General Purpose Input/Output pins are at a premium, the designer may require the BOOT0 pin for GPIO.
What is required in the above situations is a means of forcing the MCU into system bootloader mode from the resident firmware. The following code snippet enables the system bootloader to be accessed from the main firmware and possibly triggered by a USB or USART command.
typedef void (*pFunction)(void);
const uint32_t ApplicationAddress = 0x1FFF0000;
register uint32_t JumpAddress = 0;
register uint32_t addr = 0x20018000;
static pFunction Jump_To_Application;
/* We start here */
uint32_t value = 0 - 1;
NVIC_ICER (0) = value;
NVIC_ICER (1) = value;
NVIC_ICER (2) = value;
NVIC_ICPR (0) = value;
NVIC_ICPR (1) = value;
NVIC_ICPR (2) = value;STK_CSR = 0;
/* Reset the RCC clock configuration to the default reset state ------------*/
/* Reset value of 0x83 includes Set HSION bit */
RCC_CR |= (uint32_t) 0x00000082;
/* Reset CFGR register */
RCC_CFGR = 0x00000000;
/* Disable all interrupts */
RCC_CIR = 0x00000000;
FLASH_ACR = 0;
__asm volatile ("isb");
__asm volatile ("dsb");
JumpAddress = *((uint32_t *) (ApplicationAddress + 4));
Jump_To_Application = (pFunction) JumpAddress;
set up the stack for the bootloader
__asm__ ("mov sp,%[v]" : : [v]"r"(addr));
Once again I find that the best technology doesn’t always prevail. In the mid-1970s Sony launched the Betamax video format into the consumer marketplace and the “Videotape Wars” began; in spite of the superior quality of the video recordings made with the Betamax format, VHS prevailed and won the battle.
There have been many similar examples of products performing up-to and beyond competing products and still failing to win a significant market share. Such is the case of Windows Phone; I have been a Windows Phone user for quite a few years, all the way up until this last week when I finally jumped to the “Dark Side” and purchased a Google Pixel phone with its Android operating system. Windows phone is/was a great product, the almost seamless integration with the Windows desktop and tablet ecosystem reflected a well conceived and designed system. In the latest version of Windows Phone (Windows 10) that ecosystem-wide integration is outstanding. So, why did it fail so badly to win a significant market share? The answer, as in all previous technology/product wars is simple … marketing, the art of creating desire for one product over another through brand recognition in the phone case. Apple did a superb job of creating a hip, vibrant image for their products. Google took another approach, ensuring that phone manufacturers had easy access to Android and allowing them the freedom to create products that reflected the phone companies image. Meanwhile, Microsoft had a weak, often confusing marketing approach that just didn’t win the hearts and minds of the phone manufacturers or the consumer.
So, what does this have to do with embedded systems and software? It is a cautionary tale, just because you have the best product in its category, or even establish a new, potentially exciting category, it will only succeed if people know about it. Technology and performance short-falls do not appear to be a gating factor in new product successes. Promotion is a significant factor in a product’s success.
Next time you have that brilliant idea bear this in mind. Identify the demographic of your potential customers and prepare to market to them. Plus, in this age of social media, live streaming, podcasts, and blogs it is valuable to establish a reputation, one that may be transferred to your eventual product release.
As a part of my Grow with Google Nanodegree I submitted my latest project for review yesterday. Imagine my surprise this morning when the reviewer rejected it because it crashed on startup. How could that be? I mean, if it crashes on startup I wouldn’t have been able to test it at all.
In situations like this my experience tells me the issue must be related to the environment in which the app was being run. What is the difference between my setup and that of the reviewer. There was no more detailed feedback from the reviewer other than a stack trace of the crash. It looked like a null object exception, again, why wasn’t I seeing it?
Based upon my experience I realized that the issue was probably due to the fact that the reviewer was running my app for the first time on his computer, whereas it had been run many times on mine. For testing I use the Android Studio device emulator (AVD), I used AVD to wipe all the data from the emulated device in order to get my setup as close as possible to that of the reviewer. Once I did that I was able to reproduce the exact problem reported. Not only that, I was able to fix the issue in a few minutes and re-submit it for review.
The takeaway of this exercise is that even experienced programmers sometimes forget that the testing of apps needs to be done in a way that gets as close as possible to the end users “first contact” with it. A small error on my part, introduced several revisions ago, turned out to be a “ticking bomb” when the app was installed on a device for the very first time.
The Black Magic Debug Probe (BMP) v2.1 was launched through a Kickstarter campaign. It is an Open Hardware, Open Source device that enables attachment of a source-level debug tool to an embedded Cortex-M MCU using either JTAG or SWD. The software for the device has a comprehensive build system that allows building for multiple platforms in addition to the Blacksphere v2.1 hardware. However, if one is a Windows-centric developer building the code can be challenging. This article aims to detail the process for building the BMP software on a Windows development computer.
Installation of required tools.
Since the build system for BMP requires some Linux features the first prerequisite is the Cygwin Linux-like environment for Windows. It may be downloaded from cygwin.com and installed by following the instructions on the web site. In addition to the default packages installed also select and install:
make: The GNU version of the ‘make’ utility
BMP makes use of the Open Source Cortex-M3 hardware abstraction library libOpenCM3, a submodule of the BMP repository. This library has some dynamic file generation that requires Python, it may be downloaded and installed from the python.org web site. Note that it is recommended to use v2.7 of Python. There may be issues using v3.x. Once Python is installed add the path to “python.exe” to your system path so that it is found when executed from the Cygwin terminal. TO test this open the Cygwin terminal and execute “python –version”:
If you do not already have git installed go to the git web site and download and install it. When the installation is complete you may test it by entering the command “git –version”:
Finally the GNU ARM Embedded Toolchain should be installed from the developer.arm.com web site. When the installation completed dialog appears make sure to check the “Add path to environment variable” option. Once the installation is complete, start the Cygwin terminal and execute the command “arm-none-eabi-gcc –version” to check the installation:
Getting the source code.
I like to keep my project files under a single root folder to make backup a little easier, rather than having to backup multiple locations. This folder is named “C:\DataRoot\Projects” and I cloned any Github repositories into this folder. This requires and extra step or two to have the project source available to the Cygwin terminal, this is described below.
The source code for the BMP is hosted on GitHub. The recommended procedure to acquire the source is to following these steps:
Clone the repository, or fork and clone. If you are using git on the command line it would be something like:
Initialize the libOpenCM3 sub-module using the following steps:
Set you current working directory to the root of the BMP source, e.g. <path to the root>/blackmagic.
execute -> git submodule init
execute -> git submodule update
If you cloned the BMP repository into the Cygwin file structure you are ready to begin the build process. If however, you have the source outside the Cygwin file structure you will need to mount it for Cygwin to work with it. My BMP repository is cloned into “c:\DataRoot\Projects\blackmagic” and I use the following commands in Cygwin to mount the source:
In spite of using the Cygwin environment there is still an issue with the environment that does not allow the building of all of the various libOpenCM3 MCU libraries using the Makefile supplied. The following procedure is based upon information gleaned from the article “Install libopencm3 for Cygwin” on the CompuSilli blog. I would love to directly cite the author but so far have been unable to identify them.
For the build procedures described below I will use “<project root>” to indicate the folder into which the BMP repo was cloned. On my computer that would be “c:\DataRoot\Projects\blackmagic.”
Start by running the Cygwin command to open a Cygwin terminal window. In order to access the BMP repo it is necessary to mount the repo in the Cygwin environment, I chose to create a folder in the Cygwin home folder called “projects” and to create a folder inside that called “blackmagic.”
Next, mount the actual “blackmagic” repo on the Cygwin “home/projects/blackmagic folder just created:
mount <project root> ~/Projects/blackmagic
The main makefile of the BMP build runs some Python scripts that generate some header files required for the libOpenCM3 builds. This presents a small “catch 22” scenario because the main makefile will not run to completion without the library files being built for the chosen platform. However, the main makefile does the script running first and therefore we can run it just to generate the header files required. So, even though it will result in an error do the following next:
change to the root folder of the repository
In my case ~/projects/blackmagic
Now we need to choose the library to build for the platform supporting the BMP. If you are building software for the BMP v2.1 hardware you will need to build the library for the STM32F1xx; use the following commands to build the library.
To build the “native” BMP software for the v2.1 hardware use the following commands:
To build for a different platform, for example the Nucleo STLinkV2 replace the last line above with:
Flashing the new software onto the BMP
Updating the firmware on Windows requires a driver installation and the use of a tool called DF-Util.
The driver (on Windows 10) is installed using a utility from http://zadig.akeo.ie/. Black Magic Probe uses a driver called libusbK, a selection offered by the Zadig tool.
Place the BMP into DFU mode by cycling the power while holding down the small button on the probe. If the probe enters DFU mode all three LEDs will flash. Then in a command window enter the following command: