Take 2: starting M0 halts M4

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

Take 2: starting M0 halts M4

1,021 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Fri May 30 21:27:20 MST 2014
I've been waiting over a week for NXP support to utter a single word, so I'm giving the forum another shot.

Attached is my current test source.  The 4350m0 directory contains a very simple program that does nothing except periodically update one of the SCT match registers.

The 4350m4 directory contains a setup program that configures the SCT to do PWM output to the red LED on the Hitex board (CTOUT3), then copy the M0 code over into SRAM and start it.

When I run this (.gdbinit autoloads and runs the binary), I end up with the LED stuck on (which indicates that the SCT crashed!) and gdb says I'm at 0x000000cc [ResetISR] in the M4.

I have no idea what's wrong, and NXP apparently doesn't either because they're not answering any of my emails or calls.  Hopefully someone else here has any clues.

Original Attachment has been moved to: 4350-fail.zip

Labels (1)
0 Kudos
19 Replies

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DF9DQ on Tue Jun 03 08:48:22 MST 2014
I did not use the cr_start_m0.c file at all. I modified your original code.

After adding an event that uses MATCH2, I can now see the M0 sweeping through a range of duty cycles periodically on output 2.
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Tue Jun 03 05:46:22 MST 2014

Quote:
Based on your code I found attached to this thread, I modified the start_m0 and halt_m0 code so that M0 starts without resetting SCT.



Do you mean you replaced my original code with cr_start_m0.c verbatim, or you had to alter that code as well?
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DF9DQ on Tue Jun 03 00:46:01 MST 2014
Based on your code I found attached to this thread, I modified the start_m0 and halt_m0 code so that M0 starts without resetting SCT.

The M4 code just sits in a while(1) loop after initial SCT setup. The M0 code updates MATCHREL2 continuously, the output of the SCT changes accordingly, and everything is working fine.

I'm using a Lauterbach debugger for this, not GDB.

0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Mon Jun 02 15:10:45 MST 2014

Quote:
So the cr_start... files have solved the "M0 halts M4" problem for you, and what's left is an issue with GDB?



No, they haven't.  I initially got better results when I first put them in, but quickly discovered that it only partially helped.  See my previous post (#12) about what's currently going on, using cr_start_m0.  The M4 isn't necessarily halting, but GDB *thinks* it is, and the resulting effect on the LED (via SCT) from each core is not sane (and not yet fully characterized).

Unfortunately I just got handed a job interrupt, so I'll have to determine whether the cores are actually doing what they're supposed to independent of what GDB says, a bit later.
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DF9DQ on Mon Jun 02 14:34:46 MST 2014
So the cr_start... files have solved the "M0 halts M4" problem for you, and what's left is an issue with GDB?


0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Mon Jun 02 14:17:46 MST 2014

Quote:
The problem is in the M4 code that starts the M0:



I stopped using that code as soon as lpcexpresso-support posted the cr_start_m0.c and .h files.
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DF9DQ on Mon Jun 02 14:00:02 MST 2014
The problem is in the M4 code that starts the M0:

void halt_m0() {
  while (LPC_RGU->RESET_ACTIVE_STATUS1 & (1<<24)) {
    LPC_RGU->RESET_CTRL1 = LPC_RGU->RESET_ACTIVE_STATUS1 | (1<<24);
  }
}

void start_m0() {
  while (!(LPC_RGU->RESET_ACTIVE_STATUS1 & (1<<24))) {
    LPC_RGU->RESET_CTRL1 = LPC_RGU->RESET_ACTIVE_STATUS1 & ~(1<<24);
  }
}


At least one of the functions will write to RESET_CTRL1 with most bits set, and thereby reset many peripherals, including SCT.
It doesn't matter what code you run on M0.

0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Mon Jun 02 13:40:33 MST 2014

Quote:
My confusion would be where the cr_start_m0.c code I just put in place (replacing my broken M0 start) still would do the same?



I've analyzed the cr_start_m0 code and confirmed it's execution with the debugger: it reads 0xfeffffff from RGU_RESET_ACTIVE_STATUS1, determines that the core is in reset, and writes 0x00000000 to RGU_RESET_CTRL1.  Nothing more, nothing less.

The behavior I'm seeing is particularly strange:

I set up the M4 code to configure and loop-write to the SCT, and start the M0 except the M0 is nothing but a while(1) loop.  When I hard-reset the board then start GDB, two things happen:

- the attached LED starts flashing as expected with the M4's SCT loop
- gdb claims a SIGINT at ResetISR, with the address matching the M4's codebase

These two things should be mutually exclusive.

However, when I re-run gdb without a hard reset, it pushes the code into RAM again and soft-resets the core, and then "runs" perfectly fine from then on out without any faults.
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Mon Jun 02 13:16:42 MST 2014

Quote:
Your code to start the M0 core resets the SCT!



OK, that sounds reasonable, I'll chase it down here in a second.  My confusion would be where the cr_start_m0.c code I just put in place (replacing my broken M0 start) still would do the same?  I'll work my way through it in detail and see where I get.
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DF9DQ on Mon Jun 02 11:09:24 MST 2014
Your code to start the M0 core resets the SCT! This happens when you write to the RESET_CTRL1 register. Since most bits in the RESET_ACTIVE_STATUS1 register are set, writing that pattern to RESET_CTRL1 has this effect!

And the SCT is just one of these peripherals. You are also resetting timers, UART's, and more.

Neither M4 nor M0 core can use the SCT anymore once you have started the M0 using that code.
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Mon Jun 02 11:00:35 MST 2014

Quote:
This is the moment where the SCT stops working...



Well, sortof.  My immediate goal is to get the M4 to set up the SCT, then have the M4 loop setting MATCHREL1 (CTOUT3, red LED) at one flash speed, while the M0 sets MATCHREL2 (CTOUT2, green LED) at a different speed.

I'm still trying to get a handle on exactly what's going on (between other jobs and housework...), but whether the M4 ends up in ResetISR seems to depend *heavily* on what core is doing what to the SCT.  I may just have to make a table of who's doing what in order to find some kind of pattern.

Are there any known issues with both cores accessing registers in the same peripheral?  I haven't seen any warning to that effect but I also am only a few weeks into using ARM at all, so I may not even know where to look.
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DF9DQ on Mon Jun 02 10:52:31 MST 2014
Check your start_m0() and halt_m0() functions.
You read the ACTIVE_STATUS1 register, modify one bit, then write it to the CTRL1 register. Unfortunately, these registers use different polarity: A running peripheral (no reset) has its bit set in the ACTIVE_STATUS register, but writing a 1 to a bit in CTRL1 resets the corresponding peripheral!

This is the moment where the SCT stops working...
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Mon Jun 02 09:12:11 MST 2014

Quote:
I suspect an issue with your code to start the m0. I don't have time to debug your code, so attached is our known working code for booting the m0



Woot, that did it!  I guess I'll have to recheck what I did with my start code and figure out what the difference is.

Thanks!
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Mon Jun 02 07:58:11 MST 2014
I don't have your setup, so I plugged your SCT code (M4 and M0) into a known working example and I see no such problems.

I suspect an issue with your code to start the m0. I don't have time to debug your code, so attached is our known working code for booting the m0
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Mon Jun 02 07:35:37 MST 2014
Of course the forum only alerts me once per night about posts and thus I missed your first set of questions.


Quote:
Which toolchain are you using? What debug probe? What board?



Toolchain - CodeSourcery arm-2013.11-24-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
Board - Hitex 4350
Debug probe - Olimex ARM-USB-TINY w/OpenOCD 0.7.0, config file says "include arm-usb-tiny, include lpc4350" files straight from distro

Build process:

cd 4340m0
make
cd ../4350m4
./mkimage ../4340m0/gcc/RTOSDemo.bin m0image > m0image.c
make



Quote:
How are you downloading the two applications?



cd 4350m4
gdb


The m0 code is copied (as per the m4 main.c) from the m0image into 0x10080000 and run with no debugger or jtag intervention.
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Sun Jun 01 12:58:52 MST 2014
So, what about the other questions I asked?
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by omegahacker on Sat May 31 07:09:43 MST 2014
The .gdbinit script in the M0 directory is *not* used, it is just copied over with the rest of the files from the M4 codebase.

The only instance of GDB is the one running the M4, which loads the M0 code and runs it without any JTAG interference.
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Sat May 31 01:49:00 MST 2014
I just had a look at your two .gdbinit scripts - and that is where your problem is.

The M4 script issues a "monitor reset" command to your debug probe. That is OK.
The problem is that your M0 script does too...

A reset will reset *both* cores. Hence, when you start your M0 debug session, you issue the reset which will cause the M4 to reset and thus start at ResetISR again.

You will need to change your M0 .gdbinit to attach to a running system. You will need to consult your debug probe documentation for how to do this.
0 Kudos

965 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Sat May 31 01:04:00 MST 2014
Which toolchain are you using? What debug probe? What board?

How are you downloading the two applications?

Give us some information so that we can try to understand what you are doing and how. (A brief look at your zip file indicates you are using a standalone GCC toolchain)
0 Kudos