SDMA port for GNU binutils (assembler/linker) + debugger

cancel
Showing results for 
Search instead for 
Did you mean: 

SDMA port for GNU binutils (assembler/linker) + debugger

493 Views
ceggers1
Contributor IV

Hello i.MX users, hello NXP,

currently there are more or less no development tools available for making custom SDMA scripts:

  • CodeWarrior for StarCore and SDMA [1] is not available anymore
  • Eli Billauers SDMA assembler (perl script) [2] offers only very basic support for this (e.g. no debugger / linker).

I have started some hacking on GNU binutils [3] trying to bring SDMA support into them. On the one hand this looks not so difficult as the SDMA has a quite straightforward instruction set. On the other hand, the binutils project seems to suffer from some amount of "historical ballast" which makes working on it quite time consuming.

Additionally I have started creating a debugger for SDMA. This work is based on a commercial JTAG debugger called "Trace32" from Lauterbach [4]. My extension for this debugger enables simultaneous debugging of the ARM (bare metal/Linux) and SDMA software within the graphical Trace32 IDE.

<Edit> As I did not get any answers to the original post, I will provide some more information:

Why am I writing this?

As I work with open source on a daily base, I want to contribute something myself. Additionally I would like to encourage other users to use the SDMA in a more "creative manner". Maybe we can manage to release a number of SDMA scripts under an open source license...

But each open source developer needs money to make ends meet. Porting binutils for SDMA was probably the most complicated thing I have ever done in my job. I assume that my tools are the best ones available for SDMA (presumably better than what NXP owns itself) and I would like to ask NXP politely to provide some support for my work.

What can I do with this software?

My tool chain makes it possible to develop (assemble/link/debug) own scripts for the SDMA controller found on most i.MX chips. The debugger provides easy stepping through your SDMA scripts and allows fixing bugs within a reasonable amount of time.

Using the SDMA can:

  • improve real time behavior
  • lower the interrupt load of the ARM CPU
  • extend the functionality of existing peripherals (but not as powerful as an FPGA)
  • increase the throughput

For what use cases do I use the SDMA?

  • ADC:
    • Autonomous "scanning" of multiple channels, checking measured values against user defined limits (similar as the "sequencer" and "analog watchdog" on STM32).
    • High speed data acquisition, two ADCs in parallel (planned feature).
  • EIM: Interfacing an FPGA (to be done).
  • I2C: Reducing the interrupt load (planned feature).
  • SPI: Improving throughput (the only place where I use the default scripts from NXP).
  • Timer: Low cost fan rpm monitoring (without external ICs).
  • UART: Reassembly of incoming data with different framing protocols (DMX/RDM and HDLC).
  • USB: Low cost implementation of USB-C (using an ADC for monitoring the USB-C CC lines, without external ICs).

My story:

The problem ("A new project...")
When we started development of our new product in mid of 2018, I was looking for a way to receive and send DMX/RDM messages with an i.MX6 processor. These protocols use a UART at 250 kBit/s. The baud rate itself is not a big deal, but RDM requires answering frames within 2 milliseconds!

My first idea was to use the Cortex-M4 co-processor of the i.MX6 SoloX for this, but soon it turned out that there are not many SOMs (System On Module) with this chip out there. Then I was asked to investigate whether an i.MX6 UL could be used (we already had an eval board). Our SOM supplier told me that with an preempt-rt kernel this processor has an assured interrupt response time of less than 300 microseconds.

First contact with the SDMA (a possible solution):
For receiving and transmitting a RDM frame, these 300 µs would obviously NOT work, if this interrupt response time is required for every single byte of a frame. So I started looking whether the DMA unit of the chip could "assist" receiving frames a little bit. Reading the first page of the SDMA chapter in the reference manual made me very curious:

"It includes the custom RISC core along with its RAM, ROM, DMA units, and the scheduler."

Reading the over 200 pages of (very detailed) SDMA documentation again and again reinforced my hope that I could do the entire framing of incoming DMX/RDM frames on the DMA. With help of the SDMA I could probably reduce the number of required interrupts per frame to one!

Looking for more information (and tools):
When starting to gather more information from the internet, I first found the excellent SDMA articles from Eli Billauer [2] and Jonah Petri [5]. Eli provides a simple perl script which can be used to assemble own SDMA scripts. But for getting more in touch with the SDMA, I was mainly interested in the debugging capabilities I read about in the reference manual. I was always interested in the dark magic of (JTAG) debuggers, particularly in the hidden (existing, but broadly unknown) features of of Lauterbach Trace32. At this time I stumbled over a presentation about TRACE32-APU [6]:

API for Auxiliary Processing Unit – The sub-debugger in a debugger solution.

My first own debugger...
With the help of the (existing) ARM debugger I made my first tries manipulating the debug registers of the SDMA. I learned that controlling a CPU via a debug interface is comparable with painting a room through a keyhole. I spent the following night writing my first disassembler and the following weeks working on the debug state machines and writing description files for the peripherals. With some help of Lauterbach regarding memory access, my debugger started to become usable.

The demand for debug information:
At this stage, the debugger was useful enough for stepping through my first scripts and monitoring changes in the registers of the SDMA CPU after each instruction (this is already well documented in the reference manual...). But as my first scripts started to grow, it became more and more difficult to keep the relation between my source code and the disassembly. Although the source code is also written in assembly, you usually have additional information such as comments or named labels which helps to keep track of the code.

First contact to GNU binutils:
In my previous work as an embedded software developer I had (of course) still used the GNU assembler (e. g. for ARM startup scripts). But I have never wondered about how these tools work internally. The GNU assembler looked promising to me for getting the "debug information" (however this may work) into the object file. On the net I found a guide for porting binutils to a new target architecture [7]. When I read the guide for the first time I understood almost nothing. If I had known at this stage how much time consuming the following process was, I would have stopped the project immediately!

The following nights and many weekends I spent on getting my binutils SDMA port running. The first months I didn't really know how to correctly implement the "special features" of the SDMA, so my implementation looked like Frankenstein did it.

Discovering the binutils testsuite...
About half a year later, my SDMA port looked quite good in shape (for me) and the goal of the original project (realtime processing of DMX/RDM) was already reached. Reading further in the binutils porting guide, I recognized that there is some "test suite" I should try before mainlining my work. The first test run was really disappointing, of approximately 100 test cases about 200 failed!

The next months I spent redesigning my port, so that as many test cases as possible could run out of the box. I came across with another bunch of functionality which I head never heard about before. For all remaining tests (still about 100!) I wrote architecture-specific replacements.

Current status

  • The original product (with DMX/RDM): In mass production and shipping.
  • binutils port for SDMA: Ready for mainlining (but not approved yet, as I am looking for sponsors)
  • Plugin for Lauterbach Trace32: Works fine (for me), but may need small fixes, documentation, Youtube demos, ... The screenshot below shows what already works. If somebody is interested, I could start working on an instruction tracer (requires external logic analyzer)...

Trace32-SDMA.png
</Edit>

Is possibly anybody (customers or NXP itself) interested in sponsoring this work and getting SDMA support into GNU binutils?

Regards
Christian

[1] https://www.nxp.com/products/no-longer-manufactured/codewarrior-for-starcore-and-sdma:STARCORE-AND-S...
[2] http://billauer.co.il/blog/2011/10/imx-sdma-howto-memory-map/
[3] https://www.gnu.org/software/binutils/
[4] https://www.lauterbach.com/frames.html?powerdebugusb3.html
[5] http://blog.petri.us/sdma-hacking.html
[6] https://www.yumpu.com/en/document/view/31874303/apu-api-quantum
[7] https://www.opensourceforu.com/2010/01/binutils-porting-guide-to-a-new-target-architecture/

 

5 Replies

63 Views
niklasbergdahl
Contributor I

Hi Christian,

this looks like a really good tool for sdma script development!

I hope that nxp will come up with some debugging tool soon or incorporate this one.

Br

 

Niklas

0 Kudos

75 Views
andrea_barisani
Contributor I

I think having such SDMA tooling as open source is quite interesting and would unlock a lot of use cases, I upvote NXP considering sponsoring it given their lack of valid open source tooling for SDMA use.

0 Kudos

420 Views
ceggers1
Contributor IV

Updated my first post and added what I did with the SDMA and why I made the port for GNU binutils.

0 Kudos

249 Views
sebsus
Contributor I

Hello Christian,

thanks for your great contribution!

Reading your description, your binutils port sounds very elaborate and more mature than Eli Billauer's [1] and Jonah's perl [2] assembler.

I am currently developing a custom SDMA script for my thesis, which will reframe incoming UART data for an open source realtime OS [3] developed at my university.

I'm curious to find out how your software toolchain might help me debug and assemble my own iMX6-SDMA driver. I would be glad to try it out and make good use of your ported programs.

It seems your post doesn't contain a download link. It might have been removed or made invisible. Is it possible for you to make your work available (again)?

Thanks a lot for your help and have a good time!

Sebastian

[1] http://billauer.co.il/blog/2011/10/imx-sdma-howto-memory-map/
[2] http://blog.petri.us/sdma-hacking/part-1.html
[3] https://gitlab.com/rodos/rodos

0 Kudos

232 Views
ceggers1
Contributor IV

Hi Sebastian,

thanks for you interest in my work! I've answered you with a private message.

regards,
Christian

0 Kudos