• AVR Freaks

Helpful ReplyHot!Is there a Proper way to write a C function the returns with an eret

Author
NKurzman
A Guy on the Net
  • Total Posts : 18901
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: offline
2020/07/28 16:32:42 (permalink)
5 (1)

Is there a Proper way to write a C function the returns with an eret

The NMI requires an "eret" to return instead of an "ret".
Is there a correct way to get it to do that without inline ASM?
#1
jdeguire
Super Member
  • Total Posts : 596
  • Reward points : 0
  • Joined: 2012/01/13 07:48:44
  • Location: United States
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/29 10:29:04 (permalink)
0
Doesn't using the "interrupt" attribute do that? I don't fully remember.
#2
NKurzman
A Guy on the Net
  • Total Posts : 18901
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/29 10:39:23 (permalink)
+1 (3)
The NMI is different.
Actually this is a question for JasonK.
Since he ask why you would need inline asm in a different question.
I decided not to hijack the other question.
#3
al_bin
Super Member
  • Total Posts : 214
  • Reward points : 0
  • Joined: 2011/02/11 06:28:47
  • Location: 0
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/29 13:35:03 (permalink)
0
I use this with original gcc compiled for mips architecture.

__attribute__((interrupt, used, keep_interrupts_masked)) void myNMI_handler(void) asm("irq_nmi");
void myNMI_handler(void) {
...
}

irq_nmi is my equivalent of MCHP _nmi_handler. (weak label where crt0.s code jump in case NMI irq)
 
Albert
#4
NKurzman
A Guy on the Net
  • Total Posts : 18901
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/29 18:13:34 (permalink)
0 (2)
That doesn’t appear to be the exact same syntax as XC32.
It doesn’t say how the eret would be generated.
#5
JasonK
Moderator
  • Total Posts : 3411
  • Reward points : 0
  • Joined: 2003/11/14 09:49:40
  • Location: Microchip Technology in Arizona, USA
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/29 19:31:21 (permalink) ☄ Helpfulby moser 2020/07/31 04:02:47
+5 (5)
NMIs are a little tricky since they cause a reset rather than a normal interrupt. I'd recommend writing an NMI in assembly code.
 
If you really want to be able to return from the NMI, you'd want to save and restore all registers. However, because the first few instructions of our default startup code use a JAL instruction to ensure that the device is in the correct ISA mode, we end up modifying the RA register. You'd want to remove that code from crt0.S to prevent modifying the RA register. Ideally, we would get into the NMI without modifying any registers. (We might be able to rewrite this code to use a JR instead of a JAL.)

The default startup code then tests for and NMI and jumps to _nmi_hander. Notice that we use only the k0 and k1 registers, which are reserved for use by an interrupt context and aren't used by non-interrupt code.
https://i.imgur.com/qxkKKwO.png
The default NMI handler code, which you can find in [pic32-libs/pic32-libs.zip -> pic32m-libs.tar.bz2 -> pic32m-libs/libpic32/stubs/default-nmi-handler.S], handles the NMI again using only the k0 and k1 registers. This is the reason why I recommend writing in assembly code. There's no way to write a C function that is limited to only the k0 and k1 registers.
https://i.imgur.com/4vxawuS.png
 
All of this is assuming that you want to service the NMI as soon as possible.
 
If you want to write your NMI handler in C, you might do something like we do for general exceptions. We save all registers, call a C function, then restore all registers, and return with an eret. See [pic32-libs/pic32-libs.zip -> pic32m-libs.tar.bz2 -> pic32m-libs/libpic32/startup/general-exception.S] for an example of that. Of course, that would have a much longer latency.
 
I hope this helps! ugh, i couldn't post the images where I wanted them.
post edited by JasonK - 2020/07/29 19:51:07

Jason Kajita
 Follow me on Twitter
http://support.microchip.com for urgent questions
#6
aschen0866
Super Member
  • Total Posts : 4587
  • Reward points : 0
  • Joined: 2006/01/08 22:18:32
  • Location: San Diego
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/29 19:49:36 (permalink)
+1 (1)
Jason - When people talk about NMI and WDT, I have always thought they want to use windowed WDT so that a NMI can be triggered before the reset takes place. My FAE told me a few years back that the windowed WDT was buggy and one should stay away from it. Is that still true for new revisions of PIC32MZ family chips? 
 
#7
JasonK
Moderator
  • Total Posts : 3411
  • Reward points : 0
  • Joined: 2003/11/14 09:49:40
  • Location: Microchip Technology in Arizona, USA
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/29 19:53:46 (permalink)
+1 (1)
Hmm, I don't really know about the Windowed WDT or any errata related to it. That's outside my area of expertise. I do know that for MIPS, an NMI is really a reset with a special bit that gets set. That's what makes it tricky to use.
 
P.S. I guess we won't meet in person for MASTERs this year!
post edited by JasonK - 2020/07/30 07:01:54

Jason Kajita
 Follow me on Twitter
http://support.microchip.com for urgent questions
#8
ric
Super Member
  • Total Posts : 28365
  • Reward points : 0
  • Joined: 2003/11/07 12:41:26
  • Location: Australia, Melbourne
  • Status: online
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/29 20:00:46 (permalink)
+5 (7)
Won't it be MASKERS this year? ;)
 

I also post at: PicForum
Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
NEW USERS: Posting images, links and code - workaround for restrictions.
To get a useful answer, always state which PIC you are using!
#9
NKurzman
A Guy on the Net
  • Total Posts : 18901
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/29 22:36:29 (permalink)
+1 (1)
So this is a bigger project then it would appear.
Possibly needing more expertise than I have.
I can't have it unstable, especially if it can stop the WDT. 
This is assuming it is possible With REV A Silicon. NMICNTR is only 8 bits.
So fast vectoring is required. The units are already in the field, so REV B would not be an option.
Only the registers the NMI Handler uses need to be pushed, correct?
If the Handler is done in ASM (ie based on default-nmi-handler.S) do I still need to edit CRT0?
What else besides BEV needs to be cleared to return? (besides NMICNTR and the WDT)
 
The NMI Counter reaching 0 causes the reset according to the Data sheet.
This is not how the NMI Hardware works? Or is this feature software assisted?
 
Basically i need to hold off the WDT a maximum of a N times (If N > 0)  This is due to the Harmony File System drivers can Block if the USB MSD is Busy.  And I did Not use an RTOS.
 
Sorry to Ask so many questions.
I hate it when my simple question isn't :(
 
Ref: https://www.microchip.com/forums/m1140884.aspx
 
#10
JasonK
Moderator
  • Total Posts : 3411
  • Reward points : 0
  • Joined: 2003/11/14 09:49:40
  • Location: Microchip Technology in Arizona, USA
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/30 07:03:15 (permalink)
0
Wow. I meant that we "won't" be able to meet at MASTERs this year! That's what I get for posting at late at night.

Jason Kajita
 Follow me on Twitter
http://support.microchip.com for urgent questions
#11
aschen0866
Super Member
  • Total Posts : 4587
  • Reward points : 0
  • Joined: 2006/01/08 22:18:32
  • Location: San Diego
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/30 08:14:07 (permalink)
0

... I do know that for MIPS, an NMI is really a reset with a special bit that gets set...

NKurzman - If I understand what Jason said correctly, by the time the NMI fires, the reset has already occurred, which means all the SFRs would have already been reset to their default states. 
#12
NKurzman
A Guy on the Net
  • Total Posts : 18901
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/30 08:29:12 (permalink)
+1 (1)
According to the way I read the Manual.  The WDT causes an NMI And starts the NMI counter.  Once the NMI counter reaches 0 then a reset occurs.  if the counter is left at its default of 0, the WDT would cause an immediate reset.
I assumed this was all Hardware, So would be handles like any other interrupt. But apparently not.
 
If all the SFRs were cleared you could not continue.  But I can continue. but it is not completely continuing.
 
#13
al_bin
Super Member
  • Total Posts : 214
  • Reward points : 0
  • Joined: 2011/02/11 06:28:47
  • Location: 0
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/30 08:44:56 (permalink)
0
JasonK
... an NMI is really a reset with a special bit that gets set.


According MIPS:
After Reset/SoftReset the processor  performs a full reset initialization, including aborting state machines, establishing critical state, and generally placing the processor in a state in which it can execute instructions from uncached, unmapped address space. The state of the
processor is not defined (except same Config and Status register bits).
The ErrorEPC register value may or may not be predictable.
 
An NMI exception occurs only at  instruction boundaries, so it does not cause any reset or other hardware initialization.
The state of the cache, memory, and other processor states are consistent and all registers are preserved,
except same Config and Status register bits.
Albert
#14
al_bin
Super Member
  • Total Posts : 214
  • Reward points : 0
  • Joined: 2011/02/11 06:28:47
  • Location: 0
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/30 09:08:27 (permalink)
0
@NKurzman
As JasonK said you need edit crt0.s for don't use RA register.
If  NMICNT is 0 reset occurs.
Otherwise when WDT event occurs counter starts, and  NMI exception take place.
If you don't clear NMI bit before timeout, reset occurs. No mater if you in nmi handler or in your code.
Simple.
 
Albert
#15
moser
Super Member
  • Total Posts : 587
  • Reward points : 0
  • Joined: 2015/06/16 02:53:47
  • Location: Germany
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/31 04:58:37 (permalink)
0
Note, this thread came somehow as question from another thread:
General PIC32 Topics > The PIC32 WDT NMI
 
I guess many people seem to have the view of an NMI as either wake-up-from-sleep or unrecoverable exception. I didn't found any example for returning from it, besides for the wake-up.
 
I checked the register usage in the crt0 startup code, and seen the K0 register, which is no problem to use. But since I never coded assembler I did completely miss that it modifies the RA register, because of the jal instructions. Thanks for pointing that out, JasonK.
 
So what we need is basically:
- changed crt0 statup code, so it does not screw up any register, used by C code. K0, K1 is OK.
- an assembler written _nmi_handler (which is actually more a _nmi_context), similar as the context function for general exceptions. We save all registers, call a C function (e.g. _real_nmi_handler), then restore all registers, and return with an eret.
- The user implemented _real_nmi_handler can then do whatever it wants to deal with the situation, in C code.
 
But actually I still have another question:
Is an eret really enough? ErrorEPC contains the address where the NMI happened. But what if it happend in a branch delay slot. Can this happen? If yes, how would you need to handle that? Would we need to interpret that instruction, and/or extract the jump address from the branch to continue correctly, or how would you need to do that? Or is this no problem at all?
 
 
 
aschen0866Jason - When people talk about NMI and WDT, I have always thought they want to use windowed WDT so that a NMI can be triggered before the reset takes place. My FAE told me a few years back that the windowed WDT was buggy and one should stay away from it. Is that still true for new revisions of PIC32MZ family chips?

I just quote myself from the other thread:
moserI'm using both DMT and WDT in window mode with PIC32 MZ EF. Nothing in the errata. And nothing in my log files, unless I manually force to not clear DMT/WDT for testing purpose. And I have some devices running non-stop for years now.
 
PIC32 MZ EC had issues with window mode WDT (Errata item #22).
I can't tell you about other devices. I guess for those devices you are interested in, you just need to check the errata to see the problems, and the device data sheet to see what was intended to be supported.
 
 
 
NKurzmanThis is due to the Harmony File System drivers can Block if the USB MSD is Busy.  And I did Not use an RTOS.

I had a similar problem as NKurzman: microSD card access was causing blocking (!!!) delays of 2 seconds (others were talking about 5 seconds).
 
I fixed it by creating a regular interrupt, and everything time critical was moved there. I uses a very sharp 15/16 windowed deadman timer for monitoring this.
The main loop only contained all stuff which is not really time critical, and which might even block for long times. Mainly SD and network and such things. I used an extremely lazy (multiple seconds) windowed watchdog for it, which used the core timer to decide when to clear. 
#16
Chris A
Super Member
  • Total Posts : 858
  • Reward points : 0
  • Joined: 2010/07/20 04:37:07
  • Location: 0
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/31 06:25:05 (permalink)
0
Sorry to jump in here and I don't use PIC32 ATM so might be talking rubbish, but isn't the safest solution here to add code into the blocking loop to selectively and locally "kick the dog" with the help of a timer, to achieve the same thing without all the NMI fuss?
 
post edited by Chris A - 2020/07/31 06:27:27
#17
moser
Super Member
  • Total Posts : 587
  • Reward points : 0
  • Joined: 2015/06/16 02:53:47
  • Location: Germany
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/31 07:06:31 (permalink)
+1 (1)
The problem is to identify the blocking loop. We are talking here about a ...
- File system Service, which sits on top of a 
- FAT library, which uses a
- File System Media Manager, which accesses a 
- Media Driver for Flash/USB/SD card, which might access a driver for
- NVM / USB / SPI, which is using 
- Peripheral Libraries. 
 
I'm not even sure if I have the layers correct. And if you like you can put HTTP on top. OK, the peripheral is simple. But the loop may hide at any of those layers. Except for the FAT library, which is only vaguely documented, most is from Microchip. But the non-public APIs between their layers are very often also not documented at all. Therefore, the task is to find the performance issue in this badly documented layer-thing, and identify a point, which is regularly executed.
 
One main theory was, that during a write, which increases the file size the FAT driver is causing the delay, when it tries to find an unused sector on a fragmented SD card. But that library is not easy to understand. For example it took me almost a day to find out, why one http request reading a file is very fast, but two http request reading the same file using the same file handle is extremely slow. Reason is, that any change of the file pointer backwards across a sector border needs to start at the beginning of the file and needs to follow the whole chain through all sectors of the file.
 
 
This problem with identifying the performance issue, is why I came up instead with an regular very short interrupt, which "kicks the dog" regularly. I have used such a thing in my bootloader to serve the DMT. You could enable this interrupt in the main loop right before the respecting library, and stop it after. Quite simple if you are not using windowed mode. On the other hand, if there would ever be an infinite loop in the File System libraries, you would just hang and never detect it, unless you give that regular very short interrupt a bit more intelligence.
#18
andersm
Super Member
  • Total Posts : 2839
  • Reward points : 0
  • Joined: 2012/10/07 14:57:44
  • Location: 0
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/31 08:51:18 (permalink)
+2 (2)
moser- changed crt0 statup code, so it does not screw up any register, used by C code. K0, K1 is OK.

The "jal" instruction is used to handle the special case where the currently executing instruction set doesn't match the instruction set used in the startup code. If you're not using microMIPS (or conversely, only using microMIPS), you can simply delete it.
 
ErrorEPC contains the address where the NMI happened. But what if it happend in a branch delay slot.

ErrorEPC will contain the address of the branch or jump instruction. See the description of the ErrorEPC register in the architecture documentation.
post edited by andersm - 2020/07/31 11:12:31
#19
NKurzman
A Guy on the Net
  • Total Posts : 18901
  • Reward points : 0
  • Joined: 2008/01/16 19:33:48
  • Location: 0
  • Status: offline
Re: Is there a Proper way to write a C function the returns with an eret 2020/07/31 19:13:44 (permalink)
+1 (1)
mouser
A special kick the Dog in the Timer Interrupt a max of N Times.  I think this is safe enough for what I have to do.
I found that some USB Sticks take many seconds to create a Folder.  And will corrupt the Stick if it WDTs in the Middle.
It can then be so bad it will no longer work.  (more WDT)  my plan is to allow it a certain time, allow the WDT, and disable the stick.
 
The NMI is making me nervous.  Did Microchip ever test it?
This is out of my usual wheel house. I am not looking to create intermittent failures.
Plus Old failures if someone ever updates the compiler.  An ASM function is one thing. a custom CTR0 is another.
Worse, What about my Bootloader? Is that even possible?  I never got that far.
 
Chris A
Adding code in the Blocking loop "what mouser said".  Harmony needs an RTOS for many of the Big features as written.  I believe that is the Default in Harmony 3.
#20
Jump to:
© 2020 APG vNext Commercial Version 4.5