Prefetch Error

While running my code on a V5 Brain, I keep running into a “Prefetch Error.” I have the code run certain functions when the screen is pressed but when I press the screen an error message pops up saying “Prefetch Error ! 00000000” and nothing else happens. The code builds and downloads fine, I just run into the error when the code is running. What causes prefetch errors and how do you fix them?

1 Like

Well, you are doing something bad in the code (assuming there’s no hardware fault). prefetch error is pretty rare, here’s an explanation from some ARM documentation.

Prefetch Abort (PABT) Exception occurs when an instruction fetch causes an error.
When a Prefetch Abort occurs, the processor marks the prefetched instruction
as invalid, but does not take the exception until the instruction is to be executed.
If the instruction is not executed, for example because a branch occurs while it is
in the pipeline, an abort does not occur. All prefetch aborts are synchronous.
The difference between Undefined Instruction Abort and Prefetch Abort exception
is that in case of prefetch, CPU is unable to fetch the instruction from the address;
in an Undefined Instruction Exception, the CPU does not know what the instruction does.
 
Prefetch Abort or Undefined Instruction Exception often follows a common path:
1.     Return address being corrupted
2.     General branch address is corrupted
4 Likes

Are you using PROS ?

1 Like

VEXcode Text. Could it be caused by an issue with the brain’s firmware?

can you try on a different brain ?
If not, zip up the project and send it to me and I will try it tomorrow.

2 Likes

I don’t have a different brain with me but I’m going to try to reset the brain or redownload the firmware tomorrow.

Is it possible that you are calling a function from a pointer that isn’t set to a function, or that is calling from a restricted region in memory? I would assume that this would give you a NullPtrException or a Memory Permission Error, but, judging from jpearman’s description, and your button thing, it could be an issue with the function call.

First, to verify your hardware, you may want to you upload a simple program that only prints a number on screen, sleeps 1 sec, and then repeats this in an infinite loop.

Then, does your code crash before you press any screen buttons or does it crash only after you do that?

If it crashes before you had a chance to interact with a screen, then I would bet on corrupted return address on your stack. For example, if you have local variable on function’s stack of a size 16 bytes and write to it something that is 100 bytes long, overwriting other variables and also a saved return address back to the caller code.

If the crash occurs only when you touch the screen, then then it could be bad callback address that you pass to the UI library or similar stack corruption in the button handling code.

In any case, please, upload the minimal code that reproduces your issue (enclosed between [code] ... [/code] tags) so that we could give you more informed advice.

2 Likes

I managed to fix the issue, but I’m not sure why it happened. I found and deleted the lines of the code that caused the error and then rewrote them elsewhere in the code and that fixed it. Thanks for everyone’s help!

so could you share what you changed ? I would be nice to know what the root cause is.

11 Likes

I managed to replicate the issue with my code. What I did that caused the error was. I suspended a task in that task and it got very upset at me. So removing the suspend worked.

int myTaskCallback() {
  
  if (true) {
  Claw.spinFor(forward,5,seconds);
  task suspend(myTaskCallback);
  }
  return 0;
}
int main() {
  // Initializing Robot Configuration. DO NOT REMOVE!
  vexcodeInit();
  while(true){
    if(Controller1.ButtonX.pressing()) {
   Arm.spinFor(forward,90,degrees); 
   Drivetrain.driveFor(forward, 24, inches);
   task myTask = task(myTaskCallback);
   Drivetrain.driveFor(reverse, 24, inches);
   Drivetrain.turnFor(left,90,degrees);

I tried to reproduce the prefetch error with your code and failed, you must have had something else going on.
FYI,

task suspend(myTaskCallback);

does not suspend the task, it actually creates a new task called suspend with the callback function myTaskCallback.

to suspend a task you need a reference to the original task. In your case you could suspend the task myTask from main using either.

myTask.suspend();

or

task::suspend( myTask );
6 Likes

That wasn’t the issue in my code since I never suspended any task. I didn’t save the older version of the code that made the error (I know, bad coding practice) so the code I have right now is working. I can try to remake the error by working backwards from the version I have of it.

Thank you for the help with that. As for the error the only code I left off was some brackets and setup items. Maybe the fact that there was no task with that name and there was nothing to fetch for it caused the error.

No, that’s not what prefetch error means. My guess is somewhere you took the address of a local variable, and then later that address was used and written to, but after the function containing the variable had returned. If you get unlucky, that’ll overwrite data that another part of the program stored, and if you get really unlikely, that data that you overwrote is the “return address”—the location of the code to go back to when a function returns. Then, that function finished its job and tried to return, but the CPU looked at the address (now overwritten with some other data) and wasn’t able to properly read code from it.

I’ll try to come up with a proof of concept later; this may be a good opportunity for people (if they are interested) to learn a bit more about computer architectures and how their code actually runs on the microcontroller.

4 Likes

Isn’t it going to start creating new tasks and t hen each task will create another one and then exit right after that?

Could the scheduler that manages the tasks run out of stack memory?

Yes and yes, I think it was established earlier in this thread that that code is not correct.