jameswalmsley
Posts: 35
Joined: Thu Nov 08, 2012 3:26 pm

FreeRTOS Sucessfully Ported

Thu Nov 08, 2012 3:43 pm

Hi All,

This is my first post to raspberrypi forums, but I've been watching for a while. One of the requests amongst bare-metal programmers is for a port of FreeRTOS.

Well over the last few days I've managed to create a functioning port. Which I shall provide source-code for shortly.

The main delay for source release is that its closely coupled with my own OS, and therefore I need to remove those dependencies. Basically I used my own API's to configure interrupts, and the timer etc.

One problem I had was that I used a previous port to ARM11, which didn't work properly. This made some function calls in the vTickISR like:

volatile __asm("bl vTaskIncrementTick");

However this seemed to result in the LR being modified on entry to the function to be = PC, which is obviously wrong.

Changing the call to simply vTaskIncrementTick(); fixed the problem.
I have no idea why, because the actual instructions should be the same. I'll investigate some more, but just wondered if anyone had seen this?

Please let me know how interested people are to get the fully functioning port, and I'll publish it ASAP.

Thanks,

James Walmsley (author FullFAT - www.fullfat-fs.co.uk).

jameswalmsley
Posts: 35
Joined: Thu Nov 08, 2012 3:26 pm

Re: FreeRTOS Sucessfully Ported

Thu Nov 08, 2012 4:46 pm

I worked out the problem with the bad branching I mentioned!

If all function calls in a function are made through inline assembly the compiler doesn't know to push the LR to the stack on function entry. Therefore we end-up corrupting the LR by making a function call.

I imagine the reason the ARM11 port I was using did this, is that their vTickISR() function was called directly by the ARM on ISR entry, and therefore this corruption wouldn't have mattered.

In my port this does matter, as I use bottom half IRQ handler to find the actual IRQn that has triggered first.

In anycase, now I know the reason for me pulling my hairs our for a while!

Below are some listings for the curious!

Broken code:

Code: Select all

//void vTickISR( void ) __attribute__((naked));
void vTickISR( void )
{
   13608:	e52db004 	push	{fp}		; (str fp, [sp, #-4]!)     // Ooops no saving of LR
   1360c:	e28db000 	add	fp, sp, #0
	//__asm volatile( "bl vTaskIncrementTick" );
	//vTaskIncrementTick();
	__asm volatile("bl vTaskIncrementTick");
   13610:	ebfffc5c 	bl	12788 <vTaskIncrementTick>

	#if configUSE_PREEMPTION == 1
	__asm volatile( "bl vTaskSwitchContext" );
   13614:	ebfffd2c 	bl	12acc <vTaskSwitchContext>
	//vTaskSwitchContext();
	#endif

	pRegs->CLI = 0;
   13618:	e59f3014 	ldr	r3, [pc, #20]	; 13634 <vTickISR+0x2c>
   1361c:	e5933000 	ldr	r3, [r3]
   13620:	e3a02000 	mov	r2, #0
   13624:	e583200c 	str	r2, [r3, #12]
}
   13628:	e28bd000 	add	sp, fp, #0
   1362c:	e8bd0800 	pop	{fp}
   13630:	e12fff1e 	bx	lr
   13634:	000155a8 	andeq	r5, r1, r8, lsr #11

Code: Select all


//void vTickISR( void ) __attribute__((naked));
void vTickISR( void )
{
   13608:	e92d4800 	push	{fp, lr}                 // Note saving context of LR!
   1360c:	e28db004 	add	fp, sp, #4
	//__asm volatile( "bl vTaskIncrementTick" );
	vTaskIncrementTick();
   13610:	ebfffc5c 	bl	12788 <vTaskIncrementTick>
	//__asm volatile("bl vTaskIncrementTick");

	#if configUSE_PREEMPTION == 1
	__asm volatile( "bl vTaskSwitchContext" );
   13614:	ebfffd2c 	bl	12acc <vTaskSwitchContext>
	//vTaskSwitchContext();
	#endif

	pRegs->CLI = 0;
   13618:	e59f300c 	ldr	r3, [pc, #12]	; 1362c <vTickISR+0x24>
   1361c:	e5933000 	ldr	r3, [r3]
   13620:	e3a02000 	mov	r2, #0
   13624:	e583200c 	str	r2, [r3, #12]
}
   13628:	e8bd8800 	pop	{fp, pc}
   1362c:	000155a0 	andeq	r5, r1, r0, lsr #11

FreeRTOS
Posts: 1
Joined: Thu Nov 08, 2012 5:59 pm
Contact: Website

Re: FreeRTOS Sucessfully Ported

Thu Nov 08, 2012 6:09 pm

One of the requests amongst bare-metal programmers is for a port of FreeRTOS
...funny you should say that, I have lost count of the number of people that have requested I provide a port. As much as I would love to provide an official port, demands on my time just don't allow it at the moment, so I am very happy you have done this. I was wondering who would be the first.

I would really appreciate it if you could post your code, or a link to your code, in the FreeRTOS Interactive site. If there is enough interest I could create a Pi specific forum, for now the "any other" forum can be used.
Regards,
Richard.

+ http://www.FreeRTOS.org
Designed for microcontrollers. More than 7000 downloads per month.

+ http://www.FreeRTOS.org/trace
15 interconnected trace views. An indispensable productivity tool.

jameswalmsley
Posts: 35
Joined: Thu Nov 08, 2012 3:26 pm

Re: FreeRTOS Sucessfully Ported

Thu Nov 08, 2012 8:15 pm

Hi Barry,

Thanks for the amazingly fast response! I have just added a post to the FreeRTOS interactive also.
I still have to turn it into an easily compiled project, and make some clean-ups. But I should get that done over the weekend, and I'll post to github.

I'd appreciate it if you could merge this into FreeRTOS releases in the future for inclusion in the Demo folder. I'm also providing a simple interrupt manager, as its really required by the pi to work with FreeRTOS.

Kind regards,

James (CRTS alumni!)

jameswalmsley
Posts: 35
Joined: Thu Nov 08, 2012 3:26 pm

Re: FreeRTOS Sucessfully Ported

Sun Nov 11, 2012 7:28 pm

Hi All,

I've posted some initial working code here:

https://github.com/jameswalmsley/RaspberryPi-FreeRTOS

I'll add a README file soon, but it should be quite self-explanatory.
The included demo application will use 2 FreeRTOS tasks to flash the LED on and off.

This will build easily on Linux -- simply type make.
Also works on MSYS with Yagarto, note. You will need python for my build system to work.

Enjoy... :D

User avatar
poglad
Posts: 100
Joined: Tue Jul 31, 2012 8:47 am
Location: Aberdeen, Scotland
Contact: Website

Re: FreeRTOS Sucessfully Ported

Mon Nov 12, 2012 2:02 pm

Superb! Thank you.

theandfire
Posts: 6
Joined: Thu Oct 18, 2012 8:14 am

Re: FreeRTOS Sucessfully Ported

Mon Nov 19, 2012 8:47 am

Outstanding, good work mate.

gdhamp
Posts: 1
Joined: Wed Nov 28, 2012 1:38 am

Re: FreeRTOS Sucessfully Ported

Wed Nov 28, 2012 1:41 am

Fantastic!! I quite easily built and ran your demo.

What are your future plans for this and how can I help?

George

robu
Posts: 9
Joined: Sun Dec 02, 2012 7:26 pm

Re: FreeRTOS Sucessfully Ported

Mon Dec 03, 2012 2:29 pm

how can you change the system frequency using FreeRTOS?

wedgen
Posts: 1
Joined: Wed Dec 26, 2012 5:43 am

Re: FreeRTOS Sucessfully Ported

Wed Dec 26, 2012 5:46 am

Whats the .dbuild that was included in the git repo? I googled around but haven't found much.

Thanks!

jameswalmsley
Posts: 35
Joined: Thu Nov 08, 2012 3:26 pm

Re: FreeRTOS Sucessfully Ported

Sun Dec 30, 2012 1:00 pm

Hi Guys,

Sorry for lack of responses.
How to change the FreeRTOS system frequency?

I believe its currently set to 1000hz, you can reduce this by changing FreeRTOSConfig.h file.
Change the value of configTICK_RATE_HZ

Whats .dbuild??

Googling around won't help as I never really published it until now. Its basically a set of make files and python scripts I use to build complex projects. I just used it for this as well its convenient for me to get up and running.

I really just wanted to get FreeRTOS up and running on RaspberryPi, I am willing to maintain this as a package but I don't have much time currently.

I'm currently writing an OS framework around FreeRTOS which provides complete platform abstraction. My company is using this on Xilinx Zynq and cortex-m3 platforms, but I'm also porting to RaspberryPi as I get a chance.

Of course I'll be posting more information on here when I have something tangible.

Glad to hear some people got it working.

all the best,

James

sskabc
Posts: 3
Joined: Fri Mar 15, 2013 2:32 am

Re: FreeRTOS Sucessfully Ported

Fri Mar 15, 2013 2:55 am

Hello James

Firstly thanks for the effort.
I'm stuck. I'm able to build the port, and even load it to the SD card, but still no blinking LED. Could you venture a guess as to what I might be doing wrong?
==================================
ubuntu:~/RaspberryPi-FreeRTOS> make
Dark Builder - Unified Build Environment
Version (1.0.0 - Armstrong)
text data bss dec hex filename
17120 12 5080 22212 56c4 kernel.elf
ubuntu:~/RaspberryPi-FreeRTOS> sudo dd if=kernel.img of=/dev/sdb
97+1 records in
97+1 records out
49736 bytes (50 kB) copied, 0.032278 s, 1.5 MB/s
==================================

After this point, I remove the SD card, stick it into the RPi, and plug in the micro-USB. I see the red (PWR) light come up, but nothing else happens.

Thnx
Shreyas

tufty
Posts: 1454
Joined: Sun Sep 11, 2011 2:32 pm

Re: FreeRTOS Sucessfully Ported

Fri Mar 15, 2013 4:58 pm

sskabc wrote:Could you venture a guess as to what I might be doing wrong?
...
sudo dd if=kernel.img of=/dev/sdb
^
|
That's what you're doing wrong.

You need to FAT32 format the card, copy the various bits of GPU firmware on there, and then simply copy the kernel.img onto the card.

sskabc
Posts: 3
Joined: Fri Mar 15, 2013 2:32 am

Re: FreeRTOS Sucessfully Ported

Thu Mar 21, 2013 2:14 am

Yes. That was it. Was unfamiliar with the boot process before reading up on it.
Thank you
Sh

gin
Posts: 12
Joined: Tue Aug 28, 2012 5:52 am

Re: FreeRTOS Sucessfully Ported

Thu Mar 21, 2013 6:00 am

When you use asm statements you have to tell the compiler what is being read/written/trashed.

You want something like:

volatile __asm("bl vTaskIncrementTick" : /*in*/ : /*out*/ : /*trashed*/ "lr" );

Doing that it will know to push/pop the link register.

lula
Posts: 6
Joined: Tue Mar 19, 2013 1:17 pm

Re: FreeRTOS Sucessfully Ported

Thu Mar 21, 2013 5:22 pm

jameswalmsley wrote:Hi All,

I've posted some initial working code here:

https://github.com/jameswalmsley/RaspberryPi-FreeRTOS

I'll add a README file soon, but it should be quite self-explanatory.
The included demo application will use 2 FreeRTOS tasks to flash the LED on and off.

This will build easily on Linux -- simply type make.
Also works on MSYS with Yagarto, note. You will need python for my build system to work.

Enjoy... :D
great work, james! unfortunately, this code can't be compiled with support of VFP instructions. i have no idea, why, 'cause i included initialization of VFP11 coprocessor to startup.s, but no effect. anyone have some suggestions about situation?

sskabc
Posts: 3
Joined: Fri Mar 15, 2013 2:32 am

Re: FreeRTOS Sucessfully Ported

Fri Apr 05, 2013 6:03 am

Its mentioned in the code that GPU interrupts are not supported yet. Is there any specific reason why this is so? What steps would be required to implement this? Is there a cheap/easy workaround/hack to get one or two GPU interrupts going?

Sh

nigelfrost
Posts: 1
Joined: Tue Apr 09, 2013 3:29 pm

Re: FreeRTOS Sucessfully Ported

Tue Apr 09, 2013 4:12 pm

James,
Thanks very much for the port. Superb job. Worked first time.
Interestingly, when slowing the flashing rate down, you can see that the interval is not really consistent. That'll be the GPU I suppose.

I'd like to do some Ethernet comms on it, but I haven't a clue how to go about hooking up with eth0. Will this or your BitThunder port eventually have ethernet support?

raspPipt
Posts: 8
Joined: Fri Apr 12, 2013 9:48 am

Re: FreeRTOS Sucessfully Ported

Wed Apr 17, 2013 10:29 am

Hi all,

first of many thanks to James for the great work done in porting freeRTOS on Raspberry Pi.
Then, I would use the peripherals interrupts provided by the GPU. I saw that in the startup.s file provided together with the source code, in the _start section, there are some load operation concerning the interrupt vector table. In particular

Code: Select all

_start:
     ldr pc,reset_handler
     ldr pc,undefined_handler
     ldr pc,swi_handler	    
     ldr pc,prefetch_handler	
     ldr pc,data_handler		
     ldr pc,unused_handler	
     ldr pc,irq_handler		
     ldr pc,fiq_handler	
     ... 

Suppose that I would map the peripherals interrupt of the table in section 7.5 of the BCM2835 ARM Peripherals Manual. My question is: does IRQ 0-63 immediately follow the fiq load or not? Because I did not find a complete Interrupt Vector Table.

Thanks!

tufty
Posts: 1454
Joined: Sun Sep 11, 2011 2:32 pm

Re: FreeRTOS Sucessfully Ported

Wed Apr 17, 2013 5:43 pm

You have only two interrupt lines available, one IRQ and one FIQ. You can enable any (or all) of the 64 available interrupts to trigger an IRQ, and *one* of them to trigger an FIQ. Interrupt detection and vectoring happens within the IRQ handler itself - an example of how this should be done is contained in the peripherals datasheet.

Some of the 64 interrupts happen only on the GPU side, and should not be used on the ARM side, others (notably the USB side of things) have multiple sub-interrupts that have to be handled in the specific handler for the interrupt that's been triggered.

The ARM1176 *should* have a vectored interrupt controller, but this was apparently cut from the Broadcom silicon due to space constraints.

jameswalmsley
Posts: 35
Joined: Thu Nov 08, 2012 3:26 pm

Re: FreeRTOS Sucessfully Ported

Fri Apr 19, 2013 9:48 am

Wow, there's certainly a lot of interest in this.

Sorry I haven't been on here in a while, I've been very busy writing my BitThunder operating system.

I've now done the basic port to RaspberryPi, and of course its using FreeRTOS at its core.

However, I do need other people to make drivers, and create TCP/IP subsystems.

If anyone is interested in helping me, and learning about operating systems at a fundamental level, then please take a look at http://github.com/jameswalmsley/bitthunder

I shall write back next week with some instruction on how to get started.

I will also attempt to answer some of your other questions also.

Anyway, many thanks for the time you have all taken to try this out, and I look forward to working with you all soon.

James

raspPipt
Posts: 8
Joined: Fri Apr 12, 2013 9:48 am

Re: FreeRTOS Sucessfully Ported

Fri Apr 19, 2013 4:38 pm

Hi all,

I'm trying to use GPIO interrupt with freeRTOS. I would drive an input GPIO and make a toggle on a LED when an interrupt is generated. To do this I used the drivers provided together with the freeRTOS porting. In the main function I used:

Code: Select all

InitInterruptController();
EnableInterrupts();
EnableInterrupt(49);
EnableInterrupt(50);
EnableInterrupt(51);
EnableInterrupt(52);
After, I set the function selection for the pins (input source and LED) and the pull down mode on the selected input pin. Then, I enabled both rising and falling detection on the input source.
Finally I assigned to the interrupts a defined handler function in this way:

Code: Select all

RegisterInterrupt(49, handler, NULL);
RegisterInterrupt(50, handler, NULL);
RegisterInterrupt(51, handler, NULL);
RegisterInterrupt(52, handler, NULL);
where handler() toggle a led and clear the status bit (in the GPEDS register).

What I see is that I enter into the interrupt routine but I never exit.
Anyone could help me?

Thanks.

timr
Posts: 22
Joined: Wed May 30, 2012 10:11 am

Re: FreeRTOS Sucessfully Ported

Mon Apr 22, 2013 12:01 pm

Hi
I thought I'd have a look at FreeRTOS. I managed to build it ok, though I had some issues with libc, but I hacked around those.

I then looked at your question, and noticed:
You call e.g. EnableInterrupt(49) but EnableInterrupt() in interrupts.c appears to do nothing for iIRQ<64.

I guess the assignment below the if() block should actaully write to an enable register.

Also, in interrupts.c, line 86, isn't there a typo (+ should be =)?

And around interrupts.c, line 109, shouldn't the handler be called with irqNumber-lz, and g_VectorTable[irqNumber-lz].pParam ?

Now, I haven't looked at the processor doc before, and I'm not familiar with FreeRTOS at all, so I may have got stuff wrong, apologies if so

tim

raspPipt
Posts: 8
Joined: Fri Apr 12, 2013 9:48 am

Re: FreeRTOS Sucessfully Ported

Mon Apr 22, 2013 1:15 pm

Hi Tim,

you're right! As it is the function

Code: Select all

int EnableInterrupt(int nIRQ){...}
do nothing for nIRQ < 64. I forgot to point out that I implemented this function also for nIRQ less than 64, so that mine is now

Code: Select all

int EnableInterrupt(int nIRQ) {

	unsigned long	ulTMP;
	ulTMP = pRegs->EnableBasic;

	if(nIRQ >=0 && nIRQ <=31) {
		pRegs->Enable1 |= 1<< nIRQ;
	} else if(nIRQ >=32 && nIRQ <=63){
		pRegs->Enable2 |= 1<< (nIRQ - 32);
	} else if(nIRQ >= 64 && nIRQ <= 72) {	// Basic IRQ enables
		pRegs->EnableBasic |= 1 << (nIRQ - 64);
	}

	ulTMP = pRegs->EnableBasic;
	return 0;
}
so I consider the all the possible nIRQ.

Regarding the second point, yes line

Code: Select all

ulMaskedStatus + pRegs->Pending2;
should be replaced with

Code: Select all

ulMaskedStatus = pRegs->Pending2;
Bye

timr
Posts: 22
Joined: Wed May 30, 2012 10:11 am

Re: FreeRTOS Sucessfully Ported

Mon Apr 22, 2013 2:24 pm

Hi
Your EnableInterrupt() and DisableInterrupt() look like mine now! I modified them slightly to return -1 for invalid nIRQ, and I didn't OR the bits into the enable/disable registers, just wrote them straight in, but otherwise the same.

I think there is an issue on interrupts.c line 70 (in the github repo) because if one of the Pending1 or Pending2 bits is set, it will skip over the code that reads their registers, and I guess that will leave the interrupt asserted. I think that line could just be

Code: Select all

if(ulMaskedStatus & 0xff) {
unless I am missing something.
tim

Return to “Bare metal”

Who is online

Users browsing this forum: No registered users and 10 guests