Hello i.MX users, hello NXP,
currently there are more or less no development tools available for making custom SDMA scripts:
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:
For what use cases do I use the SDMA?
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
</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/
Hi kc Wong,
for modifying the SDMA firmware, you'll need the following:
Regarding the assembler/linker, I am still looking for a sponsor. I have invested multiple months of my private time for this and can not give this away for free for a commercial project. But if we can agree on a donation, I can send you the full source code.
The SDMA symbols are more or less the equivalent to header files in the C language. Most likely you'll want to link you own scripts against the existing ROM "library" in order to reuse common routines.
For debugging your SDMA scripts, you'll need a Lauterbach Trace32 debugger. Do you already own one?
If you like to avoid the effort of starting your own SDMA development, I can also offer to do the necessary modifications as freelance work for you.
If you like, we can also discuss the next steps in a private meeting (e.g. MS Teams). I am located in GMT+2:00 and can reserve some time in the morning or in the evening.
regards,
Christian
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
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.
Updated my first post and added what I did with the SDMA and why I made the port for GNU binutils.
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
Hi Sebastian,
thanks for you interest in my work! I've answered you with a private message.
regards,
Christian