NXP Semiconductors logo
LPCXpresso Logo

Reply
 
Thread Tools
  #11  
Old 08-04-2012, 04:08 PM
graynomad graynomad is offline
Senior Member
 
Join Date: Aug 2011
Location: nr Bundaberg, Australia
Posts: 173
graynomad is on a distinguished road
Default

I think we are at crossed purposes here, I am not writing an exception handler, this is a system that records errors raised by functions, for example

Code:
someFunc(int pinNumber) {
   if (pinNumber >= MAX_PINS)
      SYS_ERROR (ERR_BAD_PIN_NUMBER | pinNumber);
  ...
}
So it's purely a software device to help detect and track dodgy parameters to functions, NULL pointers etc.

In the above example SYS_ERROR is a macro that records the address of the code then calls a raiseError() function that handles it.

As far as I can tell this is working and I've been using it for a few days now.

That said, now that I have another look at my get_PC() function I can't for the life of me see how it does work, and yet it appears to.

It's too late to investigate now, that's a tomorrow job.
__________________
Rob Gray, aka the GRAYnomad, www.robgray.com
Reply With Quote
  #12  
Old 08-04-2012, 07:28 PM
Brutte Brutte is offline
Member
 
Join Date: Jun 2011
Location: Poland
Posts: 37
Brutte is on a distinguished road
Default

Quote:
this is a system that records errors raised by functions, for example
What about assert.h?
Besides, what is the use of the PC in HLL? You need to pinpoint the bug in the source, not in the hex.

Quote:
Originally Posted by Target, complaining:
>>Oops, assertion failed in MyProject/src/foo.c in function boo(), at line 17, because somehow pinNumber >= MAX_PINS and you are kindly requested to fix that.
Besides, you can rw any register through SCB_DCRSR (0xe000edf4).
Reply With Quote
  #13  
Old 08-05-2012, 12:26 AM
graynomad graynomad is offline
Senior Member
 
Join Date: Aug 2011
Location: nr Bundaberg, Australia
Posts: 173
graynomad is on a distinguished road
Default

Quote:
What about assert.h?
Besides, what is the use of the PC in HLL? You need to pinpoint the bug in the source, not in the hex.
This is a single-chip embedded system with no standard IO, I need a simple 1-2 words that can be serially pushed out a spare pin and read with a logic analyser.

If I have the address I can look at the map file to find the culprit.

I haven't used assert for years, maybe it can be made to do this I'm not sure but certainly a nice human-readable error message is no good to this application.

Quote:
you can rw any register through SCB_DCRSR (0xe000edf4).
I can't find any mention of using the SCB for this in the UM or anywhere else and a Google of SCB_DCRSR only brings up a single page, this one Can you elaborate?
__________________
Rob Gray, aka the GRAYnomad, www.robgray.com
Reply With Quote
  #14  
Old 08-05-2012, 04:34 PM
Brutte Brutte is offline
Member
 
Join Date: Jun 2011
Location: Poland
Posts: 37
Brutte is on a distinguished road
Default

Quote:
This is a single-chip embedded system with no standard IO, I need a simple 1-2 words that can be serially pushed out a spare pin and read with a logic analyser.
An assert.h is a standard feature. Works great, from attinys to x86.
It is you who provide the implementation of the core of the assert().
I sometimes insert asm("bkpt 0x00"), sometimes asm("nop") and nothing stops you from providing a more/less advanced BSOD.

I wonder why cannot you use OCD for asserts? Why necessarily a blinking LED, a.k.a. logic analyser, when (most of) ARMs have full-blown features on-board?

But, if you really need that IO, unless it is tn4-ish "single-chip embedded system", I suggest a software driven UART tx on an arbitrary pin.

Quote:
If I have the address I can look at the map file to find the culprit.
Sure, you can find the file, function, the line and the cause. But that is what assert was made for. Finally, after 10 minutes of searching *.lst you will get to the conclusion:

Quote:
Originally Posted by Target, complaining
>>Oops, assertion failed in MyProject/src/foo.c in function boo(), at line 17, because somehow pinNumber >= MAX_PINS and you are kindly requested to fix that. PC is 0xef45c03 if that can help.
but looks like reinventing the wheel.

Quote:
I can't find any mention of using the SCB for this in the UM or anywhere else and a Google of SCB_DCRSR only brings up a single page
Quote:
Originally Posted by ARM ARMv7-M
Debug Core Register Selector Register (DCRSR)
The DCRSR write-only register generates a handshake to the core to transfer the selected register to/from the DCRDR. The DHCSR S_REGRDY bit is cleared when the DCRSR is written, and remains clear until the core transaction completes. This register is only accessible from Debug state.
(...)
[4:0] REGSEL:
00000: R0
00001: R1

01100: R12
01101: the current SP
01110: LR
01111: DebugReturnAddress()
10000: xPSR / Flags, Execution Number, and state information
10001: MSP (Main SP)
10010: PSP (Process SP)
10100: CONTROL bits [31:24], FAULTMASK bits [23:16],
BASEPRI bits [15:8], and PRIMASK bits [7:0]
Search CMSIS for "DCRSR" and I am sure you will eventually find it It belongs to System Control Block (SCB).

A Debug Return Address should give you a PC value.

As an alternative, you can also try reading DWT_PCSR.

Last edited by Brutte; 08-05-2012 at 05:50 PM.
Reply With Quote
  #15  
Old 08-06-2012, 11:16 AM
graynomad graynomad is offline
Senior Member
 
Join Date: Aug 2011
Location: nr Bundaberg, Australia
Posts: 173
graynomad is on a distinguished road
Default

I've had a good look at assert and remember now why I haven't used it in the past, the standard version chews too much program memory. Each assert eats about 40-60 bytes depending on the file name and the assertion text.

That said I like the idea of being more in line with the standard technique and with these chips maybe a few k used for that is a good trade off, so as you say I'm modifying the assert code to be a little less verbose and just print the file/line and maybe an error code.

Quote:
Why necessarily a blinking LED, a.k.a. logic analyser
Because I come from a blinking LED/logic analyser background and am having a hard time getting used to all the great debugging tools now available.

While developing of course I have the semihost serial connection, in the field these devices will be connected to a control network and I think it makes sense to have the production version of the assert code packetise the same string and send it to the network.

I grep'd "DCRSR" in both my project folder and the Xpresso install folder. The string only appears in two core_cm3.h files, I assume then that this is only available with an M3 and that's why I could find no mention of it in the LPC1227 UM.
__________________
Rob Gray, aka the GRAYnomad, www.robgray.com
Reply With Quote
  #16  
Old 08-06-2012, 01:02 PM
Brutte Brutte is offline
Member
 
Join Date: Jun 2011
Location: Poland
Posts: 37
Brutte is on a distinguished road
Arrow

Quote:
Each assert eats about 40-60 bytes
An asm("bkpt 0x00") adds exactly two bytes. An IDE will tell you when, what and where. You can provide just any implementation you like. From two bytes up to a nice BSOD with LPCXpresso logo.

Quote:
so as you say I'm modifying the assert code to be a little less verbose and just print the file/line and maybe an error code.
You didn't get the idea. An assert does not necessarily print out the strings. It is you who gives the implementation.
It just terminates the execution because the flow or timing didn't meet the expectation. All passengers are already dead so you do not need to be worried about other resources - the whole chip is yours.

Code:
__attribute__((noinline))
__attribute__((noreturn))
void assert_abort(char* file,char* fun, uint16_t line,...){

overtake_arbitrary_resources_and_shift_out_some_chars_out(SDIO); //or ethernet, or semihosting or blinking led if you like.

puts("Oops, assertion failed in ");
puts(file);
..
..
//if you really need that PC, push out lr 
..
puts(" and you are kindly  requested to fix that.\n");
shutdown();
}
#define assert(condition) if(condition){void(0)}else {assert_abort(__FILE__,__FUNC__,__LINE__)}//these are const strings in gcc, I hope.
This one will take exactly the same size per assert as your "less verbose".

Quote:
While developing of course I have the semihost serial connection
Then where did you take that logic analyser from? Semihosting while developing and a logic analyser in the field? Or are you using logic analyser as an alternative for semihosting?

Quote:
I grep'd "DCRSR" in both my project folder and the Xpresso install folder.
What about ARM infocenter and google?
Quote:
I assume then that this is only available with an M3 and that's why I could find no mention of it in the LPC1227 UM.
ARMv6 also have SCB (and DCRSR). Actually the register looks the same as in ARMv7.
Perhaps you should start with simpler PCSR:
Code:
my_program_counter=DWT->PCSR;
Make sure DWT is enabled at first, because it is disabled by default. Perhaps LPCXpresso does it implicitly because it constantly displays DWT->CYCCNT in a register view so it must have DWT on.

Quote:
in the field these devices will be connected to a control network and I think it makes sense to have the production version of the assert code packetise the same string and send it to the network.
AFAIK asserts are purely for development stage.
You should remove it in RELEASE because those consume CPU and rom. Perhaps you need something different than assert. Like log or something similar..
Reply With Quote
  #17  
Old 08-06-2012, 03:12 PM
graynomad graynomad is offline
Senior Member
 
Join Date: Aug 2011
Location: nr Bundaberg, Australia
Posts: 173
graynomad is on a distinguished road
Default

Quote:
It just terminates the execution because the flow or timing didn't meet the expectation. All passengers are already dead so you do not need to be worried about other resources
Not necessarily, a failed assertion can easily be non-fatal. For example in my situation a remote node may ask for the value of "input17" when I only have 16 inputs. This is a cock up on the part of the remote node but not my fault and certainly not an error that requires a shutdown.

In this case the error should probably be published to the network (on the assumption that there is a node somewhere that will record the event) then ignored.

If the error is internal then that's a different story, you probably have to assume that the ability to publish to a network is compromised, in this case I think the blinking LED/software serial option is the only thing to do. How that is read is another story, maybe a tech has to plug in a terminal.

Quote:
An asm("bkpt 0x00") adds exactly two bytes
But outside of a development environment doesn't actually tell you anything, OTOH the full standard assert tells you a lot but uses quite a lot of memory. I do get it, I'm just trying to reach a balance between using no resources and providing lots of information.

Quote:
Or are you using logic analyser as an alternative for semihosting?
I'm in the process of realising I have access to new tools, for years I've just toggled pins and looked at them with a LA. Features like semi-hosting have not been available on chips/environments I've been using so I still think in terms of toggling pins. That will pass.

There is still the issue of reading a fatal error code in the field, as I said maybe a terminal but an LA is also an option. Unfortunately no user is likely to have either so we're maybe back to the flashing LED.

Quote:
What about ARM infocenter and google?
All references I can find refer to the M3, I'm using the M0. Anyway I think I no longer need to know the PC after our discussion.

Quote:
AFAIK asserts are purely for development stage.
You should remove it in RELEASE because those consume CPU and rom. Perhaps you need something different than assert. Like log or something similar..
Correct, I can just retask the assert macro to work differently according to the definition of RELEASE. Out to semihost when debugging, out to network or flashing LED in the field according to the nature of the error.
__________________
Rob Gray, aka the GRAYnomad, www.robgray.com
Reply With Quote
  #18  
Old 08-06-2012, 04:31 PM
Brutte Brutte is offline
Member
 
Join Date: Jun 2011
Location: Poland
Posts: 37
Brutte is on a distinguished road
Default

Quote:
Not necessarily, a failed assertion can easily be non-fatal.
Typical implementation calls abort() so I guess the idea is it has to be fatal but you can make your own "sometimes non-fatal" version.

Quote:
for years I've just toggled pins and looked at them with a LA. Features like semi-hosting have not been available on chips/environments I've been using
Semihosting is a purely software thing. Nothing fancy really. AFAIK even PICs support it.

Anyway, toggling pins can be quite entertaining.

Quote:
Correct, I can just retask the assert macro to work differently according to the definition of RELEASE.
I think you will eventually make your own try:catch C++ implementation soon..

Quote:
All references I can find refer to the M3, I'm using the M0.
http://infocenter.arm.com/help/index.../BABJHEIG.html
Reply With Quote
  #19  
Old 08-07-2012, 10:59 AM
graynomad graynomad is offline
Senior Member
 
Join Date: Aug 2011
Location: nr Bundaberg, Australia
Posts: 173
graynomad is on a distinguished road
Default

Quote:
toggling pins can be quite entertaining.
There's something very satisfying about a flashing LED, possibly because that's the embedded equivalent of "Hello world" and seeing it means you are finally getting somewhere with your new hardware.

Quote:
I think you will eventually make your own try:catch C++ implementation soon..
Already done, but not quite as good

Thanks for the link, I'll need to delve deeper into the guts of the processor at some point and that looks pretty interesting.
__________________
Rob Gray, aka the GRAYnomad, www.robgray.com
Reply With Quote
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



All times are GMT +2. The time now is 05:28 AM.