Any interest in an example for FreeRTOS + Interrupt USB?

USB PICs and the UBW

Moderator: phalanx

Post Reply
ttabbal
Posts: 231
Joined: Wed Aug 15, 2007 2:28 pm

Any interest in an example for FreeRTOS + Interrupt USB?

Post by ttabbal » Mon Aug 24, 2009 9:35 pm

Because I'm insane, I wrote a test app for the UBW32 that uses FreeRTOS and the interrupt driven code from the latest Microchip USB stack. I plan to use it for a project I'm working on, but I thought there might be interest in this stuff in the community.

Right now, it uses a couple tasks and queues and just echos whatever it receives back to the USB UART. It would be simple to make it do other things as needed. The nice thing about all this is that you no longer have to worry about your code stalling the USB bus. You can write all the crazy long delay ridden code you want, and the FreeRTOS kernel or the interrupts will boot your code out of the way to take care of business, and come back to it for you. This sort of thing is really more my style as I'm used to writing multi-threaded code for the day job. :D

Before someone asks, no, I don't intend to port it to the older UBW. I don't have time right now to mess with it. It should work without too much hassle, but you would have to reconfigure the project and FreeRTOS for the C18 compiler. The biggest bit I can see needing to change is the USB interrupt handler to use the C18 syntax.

So, if you want to see it, post up. I don't want to take the time to document and package it if nobody is going to use it. :lol:
------ Travis

ecat
Posts: 16
Joined: Mon Aug 31, 2009 2:45 am

Post by ecat » Tue Sep 01, 2009 6:33 am

<slight hiccup on my last post so forgive me if a similar message appears later>

I've been looking for a USB enabled, bootloader compatible scheduler for a short while now, this could be just what I'm looking for :)

Fishwaldo
Posts: 5
Joined: Thu Jan 08, 2009 7:25 pm

Post by Fishwaldo » Wed Sep 02, 2009 1:28 am

Very interested. Was about to start doing exactly the same thing myself. :)

ttabbal
Posts: 231
Joined: Wed Aug 15, 2007 2:28 pm

Post by ttabbal » Wed Sep 02, 2009 7:48 am

I'll get it packaged up. Probably post a link to it later today.
------ Travis

ttabbal
Posts: 231
Joined: Wed Aug 15, 2007 2:28 pm

Post by ttabbal » Wed Sep 02, 2009 9:07 am

The code can be downloaded here:

http://www.tabbal.net/cdc/UBW32%20FreeR ... 20Demo.zip

I included all the source you need to build.

In main.c you can see where I create the tasks for FreeRTOS.

In user.c you can see the USB interrupt handler and the USB task and queues. It flashes some LEDs and echos all the data from the USB UART back out the USB UART. It should be a great base to build more tasks and such on.

I am happy to answer any questions you may have, just post on the forum. Consider any code I wrote to be under the same license as the UBW32 source. The FreeRTOS is Modified GPL, and Microchip has their own license. I believe it's permissible to distribute the Microchip USB stack code with the project like this. If someone tells me otherwise I'll remove it and direct users to the Microchip site to download it.
------ Travis

ecat
Posts: 16
Joined: Mon Aug 31, 2009 2:45 am

Post by ecat » Wed Sep 02, 2009 10:51 am

Excellent :)

Demo hex file worked without issue. A quick code change and a rebuild worked first time. This has saved me so much time, thank you :)

Now to learn a bit more about FreeRTOS and get those nasty delays out of my ds18b20 code :twisted:

ecat
Posts: 16
Joined: Mon Aug 31, 2009 2:45 am

Post by ecat » Sat Sep 05, 2009 10:00 pm

Well, that's a few good days worth of messing around and from what I've seen:

FreeRTOS works fine.
Interrupt USB, once I worked out the tx polling, is smooth as silk.

There is one fly in the ointment, I cannot get the software reset into the bootloader to work. I don't know if the problem is FreeRTOS, interrupt USB or something else. I've set the key, checked the linker file and disabled everything I can think of before the software reset, still, every reset jumps through to the application :(

The reset code is a copy of the UB32 parse_BL_packet, in addition I've disabled everything I can think of. At the moment the code looks like:

Code: Select all

void KillAll( void ) {
     taskDISABLE_INTERRUPTS(); 
     vTaskSuspendAll ();
}

extern int SystemInitialised;          // attempt to stall USB ints during request Bootloader restart  

void parse_BL_packet(void)
{
    unsigned int dma_status;
    unsigned int int_status;
 
taskENTER_CRITICAL();
USBMaskInterrupts();
SystemInitialised = FALSE;          // attempt to stall USB ints during request Bootloader restart
CloseTimer1();
  DelayMs( 200 );     // No FreeRTOS here. Allow some down time for PC interface to prepare

USBDeviceDetach();

//U1OTGIE = 0;

  KillAll();

  DelayMs( 400 );     // No FreeRTOS here. Allow some down time for PC interface to prepare
  
  // Kill USB so that we always re-enumerate when we hit the bootloader
	USBModuleDisable();

	// Set the software key
	SoftwareKey = 0x12345678;   
  RCONCLR = 0xff;             // clear all reset bits so Bootloader takes notice
  
//  SoftReset();        // ecat, from the docs  
  
	// TEMP : For reset testing
	/* The following code illustrates a software Reset */
	/* perform a system unlock sequence */
    mSYSTEMUnlock(int_status, dma_status);
	
	/* set SWRST bit to arm reset */
    RSWRSTSET = 1;
   
    /* read RSWRST register to trigger reset */
    volatile int* p = &RSWRST;
    *p;
   
    /* prevent any unwanted code execution until reset occurs*/
    while(1);
}
Ignore the SystemInitialised variable, I'm no longer on that path.

Any suggestions would be most welcome :)

Edit:
The original D32.hex + bl command work as expected so the bootloader code is still intact.

ecat
Posts: 16
Joined: Mon Aug 31, 2009 2:45 am

Post by ecat » Sun Sep 06, 2009 7:55 am

Yay, got it :)

As the .ld files were identical I went off on a flight of fancy trying to track down some sort of residual interrupt or task switch that was somehow surviving and kicking the bootloader code back to the original app code, all to no avail. Of course holding the Prg button always worked, impossible.

In the supplied UBW32 code SoftwareKey resolves to address 0xa0001000. This is important as it must match the address used in the bootloader code.

Using as near an identical set-up as possible for a FreeRTOS + Interrupt USB derived system SoftwareKey resolves to address 0xa0007800.

I don't know enough about the Pic32 environment to comment, suffice for now

Code: Select all

unsigned int *pSoftwareKey;

	pSoftwareKey = (unsigned int *)0xA0001000;
	*pSoftwareKey = 0x12345678;
is working fine. It's not like we care about corrupting app memory right before a reset, still a more portable solution would be welcome.

Edit:
A terminal emulator with a working Bootloader button and USB auto recovery makes things so much easier :)

ttabbal
Posts: 231
Joined: Wed Aug 15, 2007 2:28 pm

Post by ttabbal » Mon Sep 07, 2009 8:39 pm

Interesting. I haven't tried to restart to the bootloader from software. Would you be willing to send me a patch for adding this to the existing code? Perhaps Embeddedman would be willing to chime in as well. He might be able to shed some light on why you need the little hack as well.
------ Travis

User avatar
EmbeddedMan
Support Volunteer
Posts: 1362
Joined: Sun Mar 05, 2006 9:23 pm

Post by EmbeddedMan » Mon Sep 07, 2009 9:10 pm

Yah, I've been looking into this. Something funny is going on.

I think it has to do with the line

Code: Select all

unsigned int __attribute__((section(".boot_software_key_sec,\"aw\",@nobits#"))) SoftwareKey;
This line needs to occur in the bootloader code (which it does) and the firmware application. Now, the current (v1.1) Firmware D example file has an error in this line. We have

Code: Select all

unsigned int __attribute__((section("boot_software_key_sec,\"aw\",@nobits#"))) SoftwareKey;
instead of the right code. Notice the difference? Yup, the period. Make sure your D32.c (or whatever) file has the period. If it doesn't, it will allocate space in a new section, instead of using the section defined in the procdefs.ld file.

When you do this, both map files (bootloader and firmware) should show the key section at 0xz0000000 as such:

Code: Select all

.boot_software_key_sec
                0xa0000000        0x4
 *(.boot_software_key_sec)
 .boot_software_key_sec
                0xa0000000        0x4 Objects\D32.o
                0xa0000000                SoftwareKey
not

Code: Select all

boot_software_key_sec
                0xa0001000        0x4
 boot_software_key_sec
                0xa0001000        0x4 Objects\D32.o
                0xa0001000                SoftwareKey
which is what happens without the little period.

I'm not quite sure how this ever worked - I must have gotten lucky with the address or something. But make sure your two definitions of SoftwareKey match exactly (bootloader and firmware) and check both map files, and you should be OK. If it's not being allocated at 0xA0000000 (and instead at 0xA0001000) then something's wrong.

Hope this helps. I'll update the UBW32 website with this information.

BTW, a HUGE shout out to Robert Vogt IV who clued me into this mistake.

*Brian

ecat
Posts: 16
Joined: Mon Aug 31, 2009 2:45 am

Post by ecat » Tue Sep 08, 2009 7:39 am

Thanks Brian, I can think of few things worse than trying to track down a single missing '.'

I'll give this a go tonight :)

ecat
Posts: 16
Joined: Mon Aug 31, 2009 2:45 am

Post by ecat » Thu Sep 10, 2009 2:01 am

Hum...

With '.', not working

Code: Select all

unsigned int __attribute__((section(".boot_software_key_sec,\"aw\",@nobits#"))) SoftwareKey;

73:                  	SoftwareKey = 0x12345678;                 // for now this links to an incorrect address
9D00F98C  3C03A000   lui         v1,0xa000
9D00F990  3C021234   lui         v0,0x1234
9D00F994  34425678   ori         v0,v0,0x5678
9D00F998  AC620000   sw          v0,0(v1)
Without '.', not working

Code: Select all

unsigned int __attribute__((section("boot_software_key_sec,\"aw\",@nobits#"))) SoftwareKey;

73:                  	SoftwareKey = 0x12345678;                 // for now this links to an incorrect address
9D00F98C  3C03A000   lui         v1,0xa000
9D00F990  3C021234   lui         v0,0x1234
9D00F994  34425678   ori         v0,v0,0x5678
9D00F998  AC627000   sw          v0,28672(v1)

Nasty, but working direct pointer manipulation

Code: Select all

35:                  unsigned int *pSoftwareKey;

74:                  	pSoftwareKey = (unsigned int *)0xA0001000;
9D00F99C  3C02A000   lui         v0,0xa000
9D00F9A0  34421000   ori         v0,v0,0x1000
9D00F9A4  AFA20018   sw          v0,24(sp)
75:                  	*pSoftwareKey = 0x12345678;   
9D00F9A8  8FA30018   lw          v1,24(sp)
9D00F9AC  3C021234   lui         v0,0x1234
9D00F9B0  34425678   ori         v0,v0,0x5678
9D00F9B4  AC620000   sw          v0,0(v1)
This forces the use of 0xA0001000, as the code works this must be the location used by the Bootloader (?). I've had no reason to re-flash the Bootloader since purchase <shrug>

Edit:
I guess the problem is in the linker or the memory allocation or the way I have things setup, most likely the latter!

Indeed I have procdefs.ld under 'Other Files' as this appears to work, I'd forgotten about this :oops: . Moving procdefs.ld to 'Linker Script' gives me errors (undefined reference, relocation truncated to fit etc). Anyway I'm happy with my fix for now :)

bobby
Posts: 1
Joined: Thu Aug 15, 2013 4:19 am

Re:

Post by bobby » Thu Aug 15, 2013 4:25 am

ttabbal wrote:The code can be downloaded here:

http://www.tabbal.net/cdc/UBW32%20FreeR ... 20Demo.zip

I included all the source you need to build.
Is this demo code still available anywhere? I cannot get the link to work.

ttabbal
Posts: 231
Joined: Wed Aug 15, 2007 2:28 pm

Re: Re:

Post by ttabbal » Thu Aug 15, 2013 12:21 pm

bobby wrote:
ttabbal wrote:The code can be downloaded here:

http://www.tabbal.net/cdc/UBW32%20FreeR ... 20Demo.zip

I included all the source you need to build.
Is this demo code still available anywhere? I cannot get the link to work.

I'll see if I can get it uploaded. I have been changing things around on the host and forgot to put some of the files back apparently.
------ Travis

ttabbal
Posts: 231
Joined: Wed Aug 15, 2007 2:28 pm

Re: Any interest in an example for FreeRTOS + Interrupt USB?

Post by ttabbal » Fri Aug 23, 2013 3:58 pm

OK. It should be available now.
------ Travis

Post Reply