Linux+FreeRTOS early bootstrapping problems

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Linux+FreeRTOS early bootstrapping problems

1,070 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Sat May 10 18:14:43 MST 2014
Disclaimer: I'm just getting started on ARM finally, but I'm intimately familiar with bare-metal MCU development otherwise, specifically on AVR Xmega.

My end goal is to get a FreeRTOS build running on the M0 under the control of a ucLinux kernel on the M4.  I'm using Emcraft's BSP, which gets me to the point of being able to compile code and run it over NFS, no problems there so far.

At this point I'm just trying to get *anything* running on the M0.  I've written a trivial test program:

#include "lpc43xx.h"

void main() __attribute__ ((naked));
void main() {
  LPC_SCU->SFSPE_5 = 4;
  LPC_GPIO_PORT->DIR[7] |= (1<<5);
  while (1) ;
}


I compile and generate a *raw* binary image with:

arm-uclinuxeabi-gcc -O0 -I. -mcpu=cortex-m0 -mthumb -c test.c -o test.o
arm-uclinuxeabi-objcopy -O binary test.o test.bin


This results in the following assembly:

00000000 <main>:
   0:   4a06            ldr     r2, [pc, #24]   ; (1c <main+0x1c>)
   2:   4b07            ldr     r3, [pc, #28]   ; (20 <main+0x20>)
   4:   2104            movs    r1, #4
   6:   50d1            str     r1, [r2, r3]
   8:   4a06            ldr     r2, [pc, #24]   ; (24 <main+0x24>)
   a:   4906            ldr     r1, [pc, #24]   ; (24 <main+0x24>)
   c:   4b06            ldr     r3, [pc, #24]   ; (28 <main+0x28>)
   e:   58c9            ldr     r1, [r1, r3]
  10:   2320            movs    r3, #32
  12:   4319            orrs    r1, r3
  14:   4b04            ldr     r3, [pc, #16]   ; (28 <main+0x28>)
  16:   50d1            str     r1, [r2, r3]
  18:   e7f2            b.n     0 <main>
  1a:   46c0            nop                     ; (mov r8, r8)
  1c:   40086000        .word   0x40086000
  20:   00000714        .word   0x00000714
  24:   400f4000        .word   0x400f4000
  28:   0000201c        .word   0x0000201c


I've confirmed that the .bin file does indeed have those exact bytes in it.

In order to start up M0, I chose 0x10080000 as the memory I want it to run out of, and proceed to load that binary file:

  uint8_t *region = 0x10080000;
  fd = open("test.bin",O_RDONLY);
  read(fd,region,64);


I set LPC_CREG->M0APPMEMMAP to 0x10080000, then clear the M0APP_RST bit in LPC_RGU->RESET_CTRL1.  This *should* start up the M0 and then exit the program, while the M0 will light an LED on the board and spin forevermore.

Unfortunately, all it ends up doing is freezing the entire board.  I don't have JTAG hooked up yet because I have to find an openocd configuration that will do the trick.

Any hints on what's going wrong here?  I've looked at several dualcore examples from NXP and Keil etc, and I'm doing exactly the same as they are, except I'm doing it from within a compiled linux "application".  I have yet to see any hint that there's a reason why that shouldn't work, but like I said I'm new to the ARM stuff.

Help?
Labels (1)
0 Kudos
12 Replies

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by PaulEmmaMartha on Mon Jan 04 10:25:34 MST 2016
Hi,

I'm still facing out the same problem. Do you have a functional version in place and would like to share the code with me?

Cheers,

Andreas
0 Kudos

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by crchaves on Thu Nov 26 05:29:27 MST 2015
Hi bomellberg,

I had the same problem when I was working with Cortex-M0, and as I'm remember it was wrong defined the address of processor Cortex-M0. In fact it was the first step to boot the Cortex-M0 from Cortex-M4.

BR
0 Kudos

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Wed Nov 25 08:59:50 MST 2015
I'd guess you need to put .thumb_func in front of function entry points such as _start.
0 Kudos

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bomellberg on Wed Nov 25 08:45:04 MST 2015
Hmm. It so happens that this comment in some documentation:

"The Program Counter (PC) is register R15. It contains the current program address. On reset, the processor loads the PC with the value of the reset vector, at address 0x00000004. Bit[0] of the value is loaded into the EPSR T-bit at reset and must be 1."

made us try to hex-edit the binary file for the m0-core, forcing bit 0 of the reset vector to 1. Suddenly, the m0-core starts spinning.
0 Kudos

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bomellberg on Wed Nov 25 03:51:32 MST 2015
omegahacker,

I sent you an email, but I'm asking here as well.

I'm trying to run stuff in the M0 parallell to running uClinux in M4.

I load the code to 0x10080000, set the M0APPMEMMAP to 0x10080000, release the M0APP Reset and nothing happens. I have to reset the M0-core using J-link debugger to get it running.

This is my code for loading and storing the M0-code:
main()
{
// Testing to run code in M0
uint8_t *CM0image_start = (uint8_t *)0x10080000;

RGU_RESET_CTRL1 = (1u << 24); // Put the M0-core in RESET

int fd = open("m0.bin", O_RDONLY);
if (fd)
{
while (read(fd, CM0image_start, 256) > 0) // Read the executable into internal SRAM area
{
;
}
}

unsigned int *pCREG_M0APPMAP = (unsigned int *) 0x40043404;
*pCREG_M0APPMAP = (unsigned int) CM0image_start;
RGU_RESET_CTRL1 = 0x0; // Release the M0 core from RESET

while (1)
{
; // Halt here, and let M0 execute.
}
}



This is my M0-code, just toggling one of my event-lines, at GPIO3[8]:
#include <stdint.h>

#define GPIO_PORT3_DIR (*((volatile uint32_t *) 0x400f600c)) #define GPIO_PORT3_TOGGLE (*((volatile uint32_t *) 0x400f630c))

void main() __attribute__ ((naked));
void main(void)
{
GPIO_PORT3_DIR |= 0x0100; // Set 8th bit to output
while (1)
{
GPIO_PORT3_TOGGLE = 0x0100; // Toggle bit 8 on GPIO3.
}
}



My reset-vector is setup like this:
.syntax unified
.cpu cortex-m0

.thumb
.section resetvector
.word   0x10087ff0  /* stack top address */
.word   _start      /* 1 Reset */
.word   _start        /* 2 NMI */
.word   _start        /* 3 HardFault */
.word   _start        /* 4 MemManage */
.word   _start        /* 5 BusFault */
.word   _start        /* 6 UsageFault */
.word   _start        /* 7 RESERVED */
.word   _start        /* 8 RESERVED */
.word   _start        /* 9 RESERVED*/
.word   _start        /* 10 RESERVED */
.word   _start        /* 11 SVCall */
.word   _start        /* 12 Debug Monitor */
.word   _start        /* 13 RESERVED */
.word   _start        /* 14 PendSV */
.word   _start        /* 15 SysTick */
.word   _start        /* 16 External Interrupt(0) */
.word   _start        /* 17 External Interrupt(1) */
.word   _start        /* 18 External Interrupt(2) */
.word   _start        /* 19 ...   */

_start:
     bl main
     b hang

hang:   b .


And finally, my linker script:
SECTIONS
{
. = 0x10080000;
     .text : {
startup.o (resetvector)
*(.text*)
}
}



My problem is that the code execution wont start, even though I can verify that the M0-core is not in reset (by reading the RGU_RESET_ACTIVE_STATUS1 register) . The only way to start the code is to attach to the cpu using my J-Link debugger, and issuing a "reset and halt" (to step forward) or "reset and run" to run it.

If I exit my linux-app, the M0 code continues to run (if started as above), but as soon as I start my linux-app again, the execution of the M0-core stops.

If you have any pointers, please let me know.

Thanks,

/Bo
0 Kudos

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by crchaves on Thu Feb 19 06:11:59 MST 2015
Hi all,

I'm working with the same processor. Currently I try to boot de uClinux in the Cortex-M4 core but I haven't good results about it.
My idea is install uClinux in the cortex-M4 and then install freeRTOS in the Cortex-M0.
I'm using the kernel available for Emcraft systems but I'm not found a u-boot that booting the processor LPC4357.

omegahacker, Could you say me any advise for booting the microcontroller LPC4357?

Thanks in advance

Sincerely
Cristobal
0 Kudos

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Fri May 23 10:17:25 MST 2014
I know EmCraft touts their use of the MPU to add some basic memory protections, but when I look at the kernel config I think it's disabled by default.  Also, when I went to look at the MPU documentation, it sent me to a document that is not publicly available.

I'll do some digging around to try to make sure the kernel isn't using the MPU, if I can figure out what the registers are (in the kernel they tend to hard-code register addresses only in the files they actually need them in, which I guess is OK since things like the NVIC etc are all standard ARM parts at standard offsets) and whether they're actually being used.

[attempting to defeat spam filter...?]
0 Kudos

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Fri May 23 07:49:37 MST 2014
I started out by putting raw code at the beginning of the memory area, as that's how one would do it with e.g. an AVR where the reset vector is executable.  Once I started building up a proper environment with the right vector table (stack pointer, reset vector, rest of interrupts) and loading that, it worked fine.

Right now the M0 code is:

int main(void) {
  uint32_t i;

  LPC_SCU->SFSPE_5 = 4;
  LPC_GPIO_PORT->DIR[7] |= (1<<5);

  while (1) {
    LPC_GPIO_PORT->PIN[7] |= (1<<5);NOPx(10000000);
    LPC_GPIO_PORT->PIN[7] &= ~(1<<5);NOPx(10000000);
  }

  return 0;
}


A pretty standard ResetISR is in place, copied from existing FreeRTOS demos (the CORTEX_LM3S102_GCC example specifically) and updated to the M0APP's vector table.  I've tried commenting out the .data and .bss initialization routines from that function to no effect.  The only register accesses are the GPIO (LED) manipulations, and there's no memory usage outside what gets linked directly into the resulting binary.

The board is a Hitex LPC4350, with u-boot and Linux stored in NOR flash, loaded into 8MB DRAM at 0x28000000 (M4MEMMAP shows that value).  I can load the M0 codebase into 0x1000 0000, 0x1000 8000, and 0x2000 8000, but not 0x2000 0000.
0 Kudos

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by bavarian on Fri May 23 06:06:56 MST 2014
When you start the M0APP as you described, then there is no reason from M0 side to interrupt or stop the M4.
You said that you made comparisons between our dual core examples and yours, everything seems to be fine.

So let's concentrate on the element which is different:  the uC Linux running on the M4.

Maybe it uses the MPU to protect memeory areas which you use now with the M0. As the code is not very complex it can be the following memory:

[list]
  [*]  SRAM area 0x10080000
  [*]  register area (the few ones you modify in your M0 code)
[/list]

The MPU is part of the ARM system specification, details can be found in Cortex-M3/M4 documentation from ARM.

Regards,
NXP Support Team
0 Kudos

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by starblue on Fri May 23 00:54:06 MST 2014

Quote: omegahacker
I managed to get a viable image to boot the M0 with finally, on my way to getting a FreeRTOS build.  It has the appropriate stack pointer, reset vector, etc.  The code flashes and LED, and I have confirmed that it works.



How did you do fix it?

Can you share more details of your project, it looks very interesting (which board, how much memory, memory layout).

I'd also guess that the M0 is overwriting some M4 memory, as there's nothing magical about the M0 running (you don't run FreeRTOS on the M0 yet, I suppose).
0 Kudos

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Thu May 22 23:49:22 MST 2014
Most likely, your M0 is trashing memory for your M4 - heap/stack/program data.

The M0 and M4 share the address space, so you have to make sure you partition the memory for them. You should also make sure that they do not run out of the same flash bank, otherwise, you will get serious slow-down caused by memory contention.
0 Kudos

885 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Thu May 22 17:50:10 MST 2014
I managed to get a viable image to boot the M0 with finally, on my way to getting a FreeRTOS build.  It has the appropriate stack pointer, reset vector, etc.  The code flashes and LED, and I have confirmed that it works.

The problem now is that as soon as I start the M0, Linux halts (oddly, except for pings...).  I'm guessing it might be something to do with an unhandled interrupt on the M4, but I have no idea how to actually find out.  Also, the M0 code is way too simple to intentionally fire an interrupt at the M4, so it has to be something that's a side-effect of starting the M0, or my code.

Any ideas?
0 Kudos