Just recently I came across a bug in my ctxLink Wireless Debug Probe. I was doing some testing with a large project, something I had not really done extensively, occasionally during loading the code for flashing into the MCU the probe would crash. More careful exercising of the code revealed the crash occurred on the fourth load command! When I ran the code using the VSCode debugger I discovered the MCU was looping in the libOpenCM3 “blocking handler” and the stack trace revealed a failure deep inside the Wi-Fi interface driver for the WINC1500 module.

Hours of searching and testing were not revealing the issue, so, since the debugger in VSCode is missing some of the more sophisticated debugging techniques, like data breakpoints, I switched to using Visual Studio 2017 with the Visual GDB extension. Surprisingly the fault changed, the exception was no longer generated, the load just prematurely ended. My first test was to check that the level of optimization between the VSCode and VS2017 builds were the same, they were not, and when the VS2017 build was made the same as the VSCode build the exception returned.

Another several hours of fruitless debugging and the situation was starting to look dire. The crowd funding campaign launch process is inexorably moving towards the launch date and we had a serious bug!

After taking a break from the project, which often seems to help clear the brain, I returned to the issue. During one session I noticed that a test flag I had put in to detect input buffer overflow had a strange value. Instead of being true or false, it had a value of “6”. Finally, here was something the Visual GDB debugger could work with. I set a data-write breakpoint on the address of the flag and ran my test. The debugger breakpoint halted the MCU and the stack trace revealed the culprit writing over the boolean flag:

    Counts[countIndex++] = len;

The above line was doing an unbounded write to the array “Counts”. This code was used some time ago to chase a network packet issue in ctxLink. At the time, the issue being chased only occurred upon startup of ctxLink and the array was sized appropriately for that test. Unfortunately, once ctxLink was handling many, many packets the above line began writing over other variables in the code.

This one line, added to chase a bug, is without doubt responsible for several strange and unpredictable problems seen with ctxLink. If there i one lesson to be learned here it is that once a piece of test code has served its purpose, DELETE IT!

Happy debugging and please check out the Crowd Supply pre-launch page for ctxLink.

Tagged with: ,

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:

android.useAndroidX=true
android.enableJetifier=true

I hope this short blog helps others save a little time getting past this frustrating build issue.

Sid

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.

The Samsung SSD is available at Amazon with Prime shipping.

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!

Sid

Tagged with: ,

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.

Sid

#codinginflow @codinginflow @sjp_software

Tagged with: , , , ,

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.

Sid

Tagged with: , ,

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.

void platform_request_boot(void)
{
    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 */
    cm_disable_interrupts ();
    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");
    cm_enable_interrupts ();
    JumpAddress = *((uint32_t *) (ApplicationAddress + 4));
    Jump_To_Application = (pFunction) JumpAddress;
    /*
         set up the stack for the bootloader
     */
    __asm__ ("mov sp,%[v]" : : [v]"r"(addr));
    Jump_To_Application ();
}

Noted that above code is for the GCC ARM compiler and also uses the libOpenCM3 library.

Sid.

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.

Sid

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.

Happy debugging!

Sid

#AndroidDev #GrowWithGoogle #Android #AndroidStudio