A week with CrossWorks

Do you not use Windows but OS X or Linux? Do you use Windows but find the old tools expensive and terrible to deal with? Are you a hobbyist who doesn't have $2000 and an annual fee to spend on a toolset you don't like?

I am some of those things. I'm an OS X user, I don't love using parallels unless I can't help it, I find Keil to be a pretty poor product (sorry Keil but I do) and way beyond what I'm prepared to spend to fund a hobby.

I came to Nordic because they support open source tools, at least a bit, thank you Nordic, this is one of the reasons I love you. I can use Makefiles and gcc but it's not the easiest way to develop, especially when it comes to debugging.

There's Eclipse. Eclipse is ok, yes I've read the 'kill it until it's dead" thread, I think it's better than that. You can get the GNU Arm plugin and all the C development stuff and it's fairly usable. Thing I don't like about it, I never found the UI totally intuitive, importing code via a variable substituted code path is possible, but it's a bit of a pain, I want to set $NORDIC_SDK_ROOT and pull code in from there, you can do it, it's not very maintainable. And finally debugging .. ah .. even though the author of GNU Arm plugin has a much better driver than the Eclipse standard one debugging is still done by starting JLinkGDB server and using a 20 year old TCP protocol to talk between the debugger and the chip. That it works at all is amazing, but it's the equivalent of taking two supercomputers and having them talk via a wet piece of string.

Why is this by the way, it's because the JLink DLL is a licensed product, we all have the DLL on our machine, but to write code which uses it directly, you have to buy a license from Segger. JLinkGDB is kindly provided by Segger for free, so that's what free tools usually use.

I read about CrossWorks by Rowley associates. I took a look at the site, it's cross platform, good, I downloaded it and asked for a trial 30 day license. Actually I asked for 2, one for my main machine and one for my laptop, that's my workflow, to flop between machines. Trial licenses are machine locked, the real one are per user and you can use them on the machines you own. They happily gave me both licenses, that was a good start.

There is no such thing as a zero-learning curve IDE. I spent a couple of days mashing buttons and sort of getting it, then I did the tutorial and read the manual and it all started to become clear. CrossWorks has great documentation, Nordic has great documentation, CrossWorks is as good. I started to understand how to navigate it and understand the flow, and it made sense. This IDE was designed for C/C++ programmers on embedded devices so all the things you want are there, and the things you don't need, are not.

There's a Nordic module, it's for the PCA10001 or bare bones for the nrf51822. It took very little work to start with that and import 'blinky' from the nordic kit. Oh and you can define your NordicSDKRoot variable, say that it's a source path and when you import files it automatically makes them relative, that was handy.

The IDE is designed with multiple levels of configuration. At the solution level, the project level, the source file level, you can define and redefine options. Debug and Release are just two slightly different configs and they layer on to make a Thumb Debug and Thumb Release target. I added a Nordic config and put all the Nordic-specific stuff in there, very simple. You can always find out exactly what you're building with and where each individual entry came from (users of Xcode will know how you have default, config, project and target settings, it's like that, on steroids).

There's a property for everything. I don't even know what some of them do, but you have hooks for pre and post operations. You can define levels of includes and libraries and ... everything. I may eventually find something I can't do, but it's going to be a while.

Once you've built a product it's even better. There are views and more views. Each input file has dependencies and output files. Click a .o file to see it disassembled. Click the .ld file (auto generated), look at the map file, see the disassembled, commented elf file.

Or if you like go by memory, you can see how big everything is in flash, or in RAM, and drill down to every single symbol, where it is, how big it is. It's a great way to see what your code looks like in the final executable. Rowley provides the usual .s and .c files, I find theirs much clearer than the gcc ones which get linked in, and shorter, much shorter, they are very close to the CMSIS templates.

Or use the source navigator to find functions, users of functions, explore your code however you want. The tools for doing this were first rate.

And then it came time to debug. I hesitated because debugging is normally fraught with pain. I picked the Segger J-Link target and it connected to my Segger. f5 to debug and no JLinkGDB was launched, the code was downloaded to the chip, it connected, it stopped in main, I had registers and memory dumps and watchpoints and disassembly if I wanted it and it all worked perfectly. This product connects directly to your Segger and drives it, it has the full resources of the JLink DLL at hand. I single stepped code, assembly, watched memory, the debugger was faultless. This was a proper debugging experience.

Their flash code loader is slightly unusual. Instead of using the JLink to dump code in flash, it uploads a small loader to RAM and then drives it with JLink, setting the PC and registers and running it, very cool idea. I had some problem because my chip had previously been used with a softdevice and code in RAM can't write to flash in code region 0. Rowley were super helpful and got me going and I learned about the loader in the process (it's documented) and even wrote my own to be softdevice-aware.

Which leads me to the last three points.

Support. I asked ton of stupid questions, I got great support on every one. The guys know their product, their product works, it can do the thing you want to do and they will tell you how to do it. I must have come across as Mr Dumb from Dumbville, and every question was answered, and every time I learned something. The documentation is great, probably should have read it before asking some of my questions. They've helped me learn the product so I can get the most out of it.

Pricing. CrossWorks is not free, it's not free because it's worth something. I'm now 10x more productive than I was messing about with Eclipse, 20x, 30x, I have no idea. And there is tiered pricing, if you are a hobbyist like me it's $150, it's worth that to me. If I get to the point I make something I think I can sell I will happily purchase a full license for about $1500. That's a similar price to the other windows-only toolkits but this one, is really good. Hats off to Rowley for understanding there is a hobbyist market out there and giving you a full spec product at a hobby price.

The rest. There's a realtime OS in there, a C library, a whole load of other things, many of them source-level. I haven't even scratched the surface yet.

If you are hobbyist who is prepared to spend a little money on a development platform which makes your hobby actually fun, I'd give this a go. If you are commercial, even on Windows, but find the tools you're using are from the dark ages, try this.

If you are Nordic, please talk to Rowley. They're shipping a great development environment your users may love. I'd be very happy to see a 'cwx' directory containing the CrossWorks solution in your example code.

  • I've come to like Crossworks even though getting started with their Tasking lIbrary on the Raspberry Pi wasn't as easy as I thought it should be. For the $150 personal license it's a good deal, however be prepaired to spend a couple of intense weeks getting your application to run. I succeeded. Following are some things Rowley marketing doesn't tell you:

    1. Their Raspberry Pi Board Support Package (BSP) targets the RPi Model A that is no longer in production. I got a Model A on Ebay for simplification. You'll have to change at least the GPIO base memory address in software when targeting other RPi Models.

    2. Their documentation does not tell you anywhere that you must import and build the Crossworks Tasking Library (CTL) into your project to use it. I found a 2011 discussion about this requirement that still is not in their documentation (2016).

    3. Their code is sparcely commented. Some pages have none. You're on your own figuring out how to change the GPIO base address, for example, to run on a RPi Model B+. Recommend getting up and running on a Model A, first.

    So yes, the provided BSP with CTL can save a lot of development effort from scratch. However, you'll have some pain to go through figuring out the instructions they left out and apparently no intention to improve. Regardless, it's a nice clean tool that has worked flawlessly for me. No compiler to install or configure, or make files, or linker files to worry with. It's all nicely hidden and easy to use. Love it.

  • I just got the license and starting to like many features in it. The import project became much easier now, probably because CrossWorks is starting to identify nRf5x targets.

  • I have been testing out Crossworks and yesterday I was able to port SDK projects over from Keil to Crossworks and get them working, both for nRF51 and nRF52. The procedure is shown in this post (the last 4 points can be skipped if using nRF51). Please feel free to check if you also are able to do this, and make suggestions to improve the answer.

  • Their flash code loader is slightly unusual. Instead of using the JLink to dump code in flash, it uploads a small loader to RAM and then drives it with JLink, setting the PC and registers and running it, very cool idea. I had some problem because my chip had previously been used with a softdevice and code in RAM can't write to flash in code region 0. Rowley were super helpful and got me going and I learned about the loader in the process (it's documented) and even wrote my own to be softdevice-aware.

    I think I am running into the problem you mentioned here. I will flash the soft-device using nRFGo Studio, then flash my program to 0x18000 using CrossStudio, but any soft-device function will fail. I have the same code, compiled with Keil uVision, and the soft-device code works fine. But as soon as I port it over to CrossStudio it does not work. I have read some topics on nRF51 and CS, but nothing is working. How did you get around this issue?

  • @RK

    How exactly did you get the Nordic blinky example working in crossworks?