Remote Debug on Raspberry Pi by PyCharm

pycharm

Recently I’ve been getting into embedded Linux, particularly the Raspberry Pi and have consequently been learning Python. I really don’t like programming directly on these small devices since the environment is typically spare and slow.

What I really needed was something that I could work on in my main dev environment but deploy and execute on the RPi. It also needed to be able to run as root because all RPi GPIO requires root privileges.

Most importantly, PyCharm has a remote debugging feature which coupled with automatic deployment makes everything super easy.

Setting Up Remote Debugging

Below is how I set up my environment. Much of this is found in the PyCharm help documentation. You can find how to set up remote debugging particularly the section on setting up a remote interpreter via SSH.

Automatic Deployment

First we need to setup automatic deployment of our files to the RPi. This part isn’t strictly required but if you don’t do it you’ll have to manage uploading your changes.

  1. Important: The login you use here is the credentials that the remote process will be run as. You can use the “pi” user, as we have another way of gaining root privileges to access GPIO detailed below.

Run Configuration

Still with me? Now that we’ve got deployment set up and an interpreter that will use our remote virtual environment, the final step is to create a run configuration to actually run a script.

  1. Create a simple python script and call it hello_world.py. Give it the following contents.
    • import RPi.GPIO
    • print “hello world!”
  2. Click in the upper right of the main window and choose “Edit Configurations…”.
    rd3-01 Run Configuration
  3. Click the plus button and choose Python.
    rd3-02 Add Python Interpreter
  4. Give the new configuration the name “hello_world (remote)”. For the script, choose the script we just created. For Python interpreter, choose the remote interpreter we created in the last section.
    rd3-03 Run Configuration
  5. Now add a path mapping to map from your local project path to the remote path. This lets the interpreter find the source file for what’s executing remotely.
    rd3-04 Edit Path Mappings
    rd3-05 Run Configuration With Paths
  6. Save the new configuration and click the run button. You should see PyCharm connect and the hello world print on the debug console.
    rd3-06 Run Success

Running as Root

Rather than enabling logging in as root over SSH, there’s another approach that will work without opening that security hole. Using permissions, we can cause our python interpreter to simply run as root.

  1. Reconnect using PuTTY and navigate to the project root folder.
    cd /home/pi/remote_debug/remote_debug_ex
  2. Change ownership of the python interpreter to root and cause it to be executed as its owner whenever it’s run.
    • sudo chown -v root:root venv/bin/python
    • sudo chmod -v u+s venv/bin/python

This will cause pip to act a bit funny when you want to install anything later on so just reverse the above changes from step 2 as needed. Just use the same commands but with pi instead of root and with u-s.

I have a couple of scripts that I keep in the project root for just this purpose. You can use below:

python_as_pi.sh 

#!/usr/bin/env bash

DIR=$(dirname $(readlink -f "${BASH_SOURCE}"))

if [ ! -f $DIR/venv/bin/python ]; then
  echo "This script should be located in the project root directory"
  echo "and the virtual environment should be created."
else

    # Change python back to run as pi
    sudo chown -v pi:pi "$DIR/venv/bin/python"
    sudo chmod -v u-s "$DIR/venv/bin/python"

fi

python_as_root.sh

#!/usr/bin/env bash

DIR=$(dirname $(readlink -f "${BASH_SOURCE}"))

if [ ! -f $DIR/venv/bin/python ]; then
  echo "This script should be located in the project root directory"
  echo "and the virtual environment should be created."
else

    # Change python to run as root
    sudo chown -v root:root "$DIR/venv/bin/python"
    sudo chmod -v u+s "$DIR/venv/bin/python"

fi

Conclusion

Now you have a way to remote debug your RPi with the interpreter running as root, allowing access to the Pi’s GPIO. You can do this with multiple projects and even have multiple projects or instances of projects open and debugging remotely.

PyCharm is a great IDE and I encourage you to look into using it to improve your development environment. For example, check out Zeal and the Dash plugin that will cause PyCharm to perform a documentation lookup when you press Ctrl+Shift+D. There are also plugins to provide support for Markdown and bash scripts.

Ethernet JTAG Adapter with Raspberry Pi

jtagpi

 I recently wanted an ethernet JTAG adapter for a project I was working on. Unfortunately ethernet JTAG adapters can cost upwards of $300, and even then they can be specific to particular chipset and toolchains.

However, were already using OpenOCD with ST-LINK/V2 programmers to communicate with out hardware, and it turns out that it’s very easy to set up OpenOCD on the Raspberry Pi. You can then plug the programmer into the Pi, connect a debugger (gdb in our case) to the OpenOCD instance, and debug your firmware remotely!

The Raspberry Pi is also a very convenient platform for adding additional interfaces to your hardware. For our project, we have FTDI serial cables and some ADC’s connected to ours as well. This lets us flash and debug our hardware, communicate with it over serial (forwarded over a socket), and continuously monitor power consumption of key components on our board. And we can do it from anywhere with an internet connection. It’s basically magic.

1. Acquire a Pi

First you’ll need a Rapsberry Pi and an SD card with the Raspbian installed on it. You can get a Raspberry Model B Starter Kit from Newark. This comes with a power adapter and an SD card with Noobs (which can automatically install Raspbian for you) pre-installed and is probably the easiest way to get started.

2. Install a Recent Version of OpenOCD

There is a version of OpenOCD already in the package database for Raspbian, but it’s version 0.6.1, which was too old for our platform. Fortunately it’s quite easy to install the latest OpenOCD from scratch. There are pretty good instructions on how to do this at SourceForge. But specifically for the Pi you can just do the following:

From your Pi:

sudo apt-get update
sudo apt-get install libtool libusb-dev libusb-1.0 autoconf automake texinfo

And then:

git clone git://git.code.sf.net/p/openocd/code openocd-code
cd openocd-code/
./bootstrap
./configure

This should spit out a bunch of stuff and then if everything worked you should see this at the end:

OpenOCD configuration summary
--------------------------------------------------
MPSSE mode of FTDI based devices        yes (auto)
ST-Link JTAG Programmer                 yes (auto)
TI ICDI JTAG Programmer                 yes (auto)
Keil ULINK JTAG Programmer              yes (auto)
Altera USB-Blaster II Compatible        yes (auto)
Segger J-Link JTAG Programmer           yes (auto)
OSBDM (JTAG only) Programmer            yes (auto)
eStick/opendous JTAG Programmer         yes (auto)
Andes JTAG Programmer                   yes (auto)
Versaloon-Link JTAG Programmer          yes (auto)
USBProg JTAG Programmer                 yes (auto)
Raisonance RLink JTAG Programmer        yes (auto)
Olimex ARM-JTAG-EW Programmer           yes (auto)
CMSIS-DAP Compliant Debugger            no

Make sure support for the programmer you are using is enabled, and then type make. Once that finishes, type sudo make install.

Now OpenOCD should be installed and ready to go!

3. Run OpenOCD

Now you can run OpenOCD. For example, if you were using an F4 discovery board, you could so something like this:

sudo openocd -f board/stm32f4discovery.cfg

If it worked, you should see something like:

Info : stm32f4x.cpu: hardware has 6 breakpoints, 4 watchpoints

Which means your programmer is ready to go!

You can then use telnet ip_of_pi 4444 to connect to your OpenOCD session and run OpenOCD commands. You can also connect to it with gdb. The most convenient way is to create a .gdbinit file with something like:

target remote my_pi_ipaddress:3333
file my_firmware.elf
monitor reset halt
load
And then you can type gdb (or in my case arm-none-eabi-gdb), and my_firmware.elf is flashed onto the hardware and is ready for debugging!

Reference: 
https://spin.atomicobject.com/2014/04/01/ethernet-adapter-jtag/

Open OCD bin compiled:

http://www.embeddedhelper.de/blog/raspberry-pi-openocd-binary/

A few minor corrections:

1. Using “extended-remote” over “remote” is recommended as it enables “run” and “start” GDB commands;
2. There’s no need to do “reset halt” before “load” with any >= 0.8.0 OpenOCD version;
3. To avoid typing “file” you can start gdb passing the filename as the first argument.

Configure Notepad++ to run a python

notepad_logo

Install python (3.4)

  1. Download the python 3.4(preferable 32 bit) windows installer from http://www.python.org/download/
  2. Run through the installer using the default settings for everything.  It should install python in the folder: C:\Python34.  If you’re using a different version of python, just substitute out the version number wherever you see 34.

Install Notepad++

  1. From http://notepad-plus-plus.org/download, download the Notepad++ installer.
  2. Run through the installer using the default settings for everything.
  3. Open Notepad++

Configure Notepad++ to run a python script

  1. Open up a command prompt
  2. Run the following command:
set PATH=%PATH%;C:\Python34

Note: If your version of python was installed in a different location, make sure to substitute out that location with the one in the command.

You can use the following command to make sure the python path was added to the PATH variable:
echo %PATH%

You should see the location of the python directory at the end of the output.

  1. Switch back to Notepad++, and go up to the menu bar, select Run, and then select Run… (F5)
  2. Insert the following in the text box that appears:
    C:\Python34\python.exe -i "$(FULL_CURRENT_PATH)"
  3. Click Save…
  4. Configure CTRL+R to be the command.  Give it a name, and press OK.
Now whenever you want to run the python script you’re working on, press CTRL+R and it will be executed.  Also you should see the window stay opened after command execution for debugging purposes because of the -i flag. Remove it if you don’t want that feature.