Migrating to a new version of AVR-GCC toolchain


I have posted in the past about migrating from AVR32 Studio to Atmel Studio 6. In that post, I mention that I am having issues with newer version of the toolchain. In this post I explain why that is so.

The first thing I did is upgrade the Atmel Software Framework (ASF). The version used earlier is 1.7.0, quite dated compared to version 3.15.0 that ships with Atmel Studio 6.2. Updating ASF version alone does not make our issue go away.

Our application uses a Synchronous Serial Controller (SSC) to transmit data. Data is continuously copied from SRAM using a Peripheral DMA Controller (PDCA). PDCA generates an interrupt when it has transmitted the specified data (triggered when TCRR returns to zero). The routine that handles that interrupt, sets the memory address (MARR) and size of data (TCRR) that will be transmitted next.

I got the first hints of where the problem could be when:

  • Debugging with JTAGICE mkII, I’d discover the processor hung at some exception handler (different each time application source is changed and recompiled) such as _handle_Instruction_Address, _handle_Data_Address_Read, _handle_Data_Address_Write etc. Upon looking for an answer, I realized that this is quite common when a stack overflow or buffer overflow has occurred.
  • Analyzing the data transmitted by the SSC using a Saleae Logic 16, I noted that only the first two DMA transfers were actually occurring. These were programmed at initialization, hinting at the fact that the interrupt handler is the source of the problem.

I got a hint for the solution from the AVR32006 : Getting started with GCC for AVR32 application note. Adding __attribute__((interrupt("full"))) to the function definition solves the problem. That tells the compiler to return from the function using the special rete instruction. You can also use the ISR macro to define the interrupt handler function. An example follows

__attribute__((interrupt("full"))) void pdca_interrupt_handler(void)
{
// rearm the PDCA
}

This is how the interrupt handler is registered.

INTC_register_interrupt( (__int_handler) &pdca_interrupt_handler, AVR32_PDCA_IRQ_1, AVR32_INTC_INT0);

Our application uses FreeRTOS, and that appropriately initializes the Interrupt Controller (INTC) and the EVBA system register.

Upgrading to a newer version of Atmel Software Framework


This post is a brief description of the procedure that I follow to upgrade to a newer version of the Atmel Software Framework (ASF).

I have now switched to newer ASF versions so often that it has become second nature. I create a new project from scratch and add the required drivers and services using the ASF Wizard, and copy my own code over to the new project. That is usually all that is required to perform the upgrade. Some project specific settings sometimes need to be copied over manually such as compiler settings and linker script modifications.

If I see any specific API changes, I start from an Example Project supplied with Atmel Studio, study the API using an Evaluation Kit board (EVK), and then change my code appropriately.

FreeRTOS task control block and stack in AVR32


FreeRTOS allocates memory for the task’s control block (TCB) structure (tskTCB type in tasks.c), followed by memory for its stack, when your code calls xTaskCreate to create a new task. To find the TCB of the currently executing task look at pxCurrentTCB in tasks.c. A color coded view of how the tskTCB structure looks in memory follows. What you see will vary based on which fields are enabled in your port.

  • Top of previous task’s stack is here (see pxPortInitialiseStack in port.c)
  • Fields of IDLE task’s TCB
    • Pointer to top of stack (higher memory)
    • xGenericListItem structure
    • xEventListItem structure
    • Task priority
    • Pointer to start of stack (lower memory)
    • Process Name (16 bytes)
  • Start of IDLE task’s stack is here (stack grows from top to start i.e. higher memory to lower)


0x00005CE0 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005CF0 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005D00 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005D10 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005D20 a5 a5 a5 a5 a5 a5 a5 a5 00 00 00 00 07 07 07 07 ¥¥¥¥¥¥¥¥……..
0x00005D30 06 06 06 06 05 05 05 05 04 04 04 04 03 03 03 03 …………….
0x00005D40 02 02 02 02 01 01 01 01 ff 00 00 ff 00 40 00 00 ……..ÿ..ÿ.@..
0x00005D50 80 00 5c 7c de ad be ef 00 00 00 00 0b 0b 0b 0b €.\|Þ..ï……..
0x00005D60 0a 0a 0a 0a 09 09 09 09 08 08 08 08 a5 a5 a5 a5 …………¥¥¥¥
0x00005D70 6c 80 5b a3 00 00 00 49 00 00 61 78 85 ec bc 8d l€[£…I..ax.ì..
0x00005D80 00 00 18 04 00 00 18 04 00 00 5d 78 00 00 17 fc ……….]x…ü
0x00005D90 00 00 00 08 d5 b6 4a 10 b0 b0 4d 2b 00 00 5d 78 ….Õ¶J.°°M+..]x
0x00005DA0 00 00 00 00 00 00 00 00 00 00 5d c0 49 44 4c 45 ……….]ÀIDLE
0x00005DB0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 09 …………….
0x00005DC0 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005DD0 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005DE0 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005DF0 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005E00 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005E10 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005E20 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005E30 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005E40 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005E50 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005E60 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005E70 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005E80 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005E90 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005EA0 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
0x00005EB0 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥

Measuring data rate of ASF USB Device CDC example


Atmel Studio 6.1 provides an example project for Atmel Software Framework (ASF) 3.12.1, called USB Device CDC Example – EVK1101. EVK1101 is an evaluation kit for the AT32UC3B0256 part, that has 256 KB of flash memory. The example though is equally valid for other variants of that part, with more or less flash memory.

I modified the sample code so that

  • It can be programmed to part AT32UC3B0512 (used by my target board)
  • Code in callback uart_rx_notify of uart_uc3.c is commented out so it does nothing
  • The while loop in main.c echoes back characters received over USB, as shown below
int value;

while (true) {
	if (udi_cdc_is_rx_ready()) {
		value = udi_cdc_getc();
		if (!udi_cdc_is_tx_ready()) {
			// Fifo full
			udi_cdc_signal_overrun();
		}
		else
		{
			udi_cdc_putc(value);
		}
	}
}

I then compiled the code and programmed it to my target using a JTAGICE mkII. Connecting the target to a Windows PC results in creation of a serial port on the PC. A driver is provided with the example. If you use Windows 8, you’ll require a (self-)signed driver, that is, if you haven’t disabled that check.

Measuring data rate is then a matter of sending a known amount of data and dividing it by the time required to send it. Since I’m echoing back data, I divided that result by 2. Just to be sure that my code modifications were reliable, I compared the echoed back data with the original. To communicate over the serial port, I used a handy tool called SerialTool I created a while back (requires .NET framework 4.5 or mono 3.2.x).

The average data rate that I was able to measure is in the range of 3200 bytes per seconds or just shy of 26000 bits per second. Pretty lame, I think.

Improving data rate

The trick to improving the data rate is to use alternate functions that receive/transmit multiple bytes per read/write. Atmel’s AVR4907 application note hints to the existence of these functions in udi_cdc.h.

The modified while loop in main.c produces a much more respectable 458000 bytes per second or 3664000 bits per second. That too while debugging using JTAG.

int len;
const int BUF_SIZE = 10;
char buf[BUF_SIZE];

while (true) {
	if (udi_cdc_is_rx_ready()) {

		// blocks until BUF_SIZE bytes are received
		len = udi_cdc_read_buf(buf, BUF_SIZE);

		if (len == BUF_SIZE) continue;

		while (!udi_cdc_is_tx_ready()) {
			// Fifo full
		}

		udi_cdc_write_buf(buf, BUF_SIZE);
	}
}

The echo logic above has a slight design flaw. If data is not a multiple of 10 bytes, the code will be stuck in the call to udi_cdc_read_buf towards the end of the data. I chose 10 quite arbitrarily.

async await


That title is intentionally short. Those two short words make asynchronous programming tremendously easy, that is, if you are a .NET programmer. It has taken me a while to get around to learning to use them. I wanted to share their power with a simple example, based on a Windows Forms app that has just two buttons. One button does something, the other cancels it. Here’s the source code in C# before we go on further.

CancellationTokenSource source;

private void doSomethingButton_Click(object sender, EventArgs e)
{
    source = new System.Threading.CancellationTokenSource();
    CancellationToken token = source.Token;
    DoSomethingAsync(token);
}

async void DoSomethingAsync(CancellationToken token)
{
    // invoke not required, we are still in the main thread
    doSomethingButton.Enabled = false;

    // do other quick work here...

    int count = 0;

    // this is where we depart from the main thread
    await System.Threading.Tasks.Task.Run(delegate
    {
        for (count = 0; count < 1000000000; count++) 
            if (token.IsCancellationRequested) break;
    });

    // invoke not required, we are back to the main thread
    MessageBox.Show(String.Format("Counted till {0}", count));
    doSomethingButton.Enabled = true;
}

private void cancelButton_Click(object sender, EventArgs e)
{
    source.Cancel();
}

Clicking on doSomethingButton invokes event handler doSomethingButton_Click, where we create a CancellationTokenSource and pass its CancellationToken to method DoSomethingAsync. The latter is adorned with async. In it, we create a long running Task (worker thread) at some point, that will end either when we are done, or when cancellation is requested by clicking cancelButton. The method itself returns to doSomethingButton_Click at the point it encounters the await keyword. An interesting bit of trickery happens at that point. All the statements that follow await will run in the original (main) thread when the Task is done.

Pretty neat, isn’t it? If you want to convert your synchronous code to asynchronous I recommend reading these Best Practices in Asynchronous Programming.

Monthly news review


This post begins a new series of monthly posts where I’ll review news of the month that has passed.

Facebook releases Paper for iOS

Before Paper, I was spending less time in Facebook and more time in FlipBoard. After Paper, I am spending less time in FlipBoard. FlipBoard still gives me more (still relevant) news than Paper, such as new and on-sale app recommendations. One curious fact, the Paper app was designed using a prototyping toolkit called Origami.

Google releases Cast SDK

This was also the month I bought a Chromecast, my first Google device purchase.

Here’s what I like about it:

  • Price
  • Ease of use
  • Cast content of any tab in Chrome, including videos, using the Google Cast extension
  • Over the air updates

Here’s what I don’t like about it:

  • Doesn’t ever go into sleep mode, so it is sucking power all the time
  • Not as many apps as there should be, but that should change quickly now

Telerik Platform

It’s a comprehensive platform for building cross-platform native, hybrid, and web applications. Developers can use Visual Studio, or a web-based IDE.

MasterCard and Visa endorse Host-based Card Emulation (HCE)

With this endorsement payment card information can now be stored in the cloud. An Android app can then communicate that information to a NFC reader.

Atmel releases beta of Atmel Studio 6.2

Atmel is steadily improving its unified IDE for AVR and ARM MCUs. This release improves debugging and tracing capabilities. I’ve been using the IDE on a continuous basis for AVR and Arduino-based projects, and find it to be quite a productive tool.

Broadcom releases source code of VideoCore driver stack

VideoCore is also used in their SoC that runs the Raspberry Pi. Releasing the source code should allow community driven improvements and fixes to proliferate.

Nokia releases an Android-based device

It doesn’t sport the Google Play store though. They are reportedly porting Windows Phone apps to Android using Xamarin. I love how Xamarin has been enabling .NET for cross-platform development.