0
\$\begingroup\$
int main(void)
{
while (1)
{
   delay(50);
      if (ButtonPress1) {
      ResetOutSwitch();
      }
}

Suppose that button press is detected and output switch is reset. How to make the microcontroller do not pool the button press anaymore.

How to make above code look like below after button pressed and output switch is reset. It will not see any if check in its code.

int main(void)
{
while (1)
{
   delay(50);
}

I am asking how to remove a line of code from execution from microcontroller program memory.

This question was closed because of its answers might be opinion based. So I must make it more specific. Is it possible to remove some program data from microcontroller flash memory, so it skips these deleted parts and continues with the rest.

What is the way to do this? I only know C programming. Using Eclipse to program STM32 microcontrollers.

\$\endgroup\$
10
  • 2
    \$\begingroup\$ Yes it is possible to do by using another conditional. \$\endgroup\$ – Peter Smith Jan 28 at 11:14
  • 2
    \$\begingroup\$ You don't "remove" checks, you stop doing them. For which you just need for example a bool variable and a bit of common sense. If you want a better answer than that, I suggest you show a concrete example. \$\endgroup\$ – Lundin Jan 28 at 11:26
  • 4
    \$\begingroup\$ I get a vibe from this that leads me to something I often tell students: Optimization at the wrong time is bad. The question you should be asking: Does this conditional check create any problems if I run it every iteration? If you run low on memory, program space, or execution time you should then go in and analyze your functions and improve as needed. Spending time to super-optimize code when you don't have to is a waste of time. I have seen so many cases where 80% of the time is spent solving an imaginary problem instead of solving the actual task, assuming they get that far. \$\endgroup\$ – Arcatus Jan 28 at 11:44
  • 2
    \$\begingroup\$ Are you asking if it is possible to modify an in-service, programmed microcontroller to, for example, replace your if instruction block with NOPs? If you give some context to your question and explain why you want to know it would save a lot of guessing as is happening below. \$\endgroup\$ – Transistor Jan 31 at 20:37
  • 1
    \$\begingroup\$ Please, edit your question, and tell us some context: why, how many times, which controller, why no other option, and so on. \$\endgroup\$ – the busybee Jan 31 at 21:23
3
\$\begingroup\$

You can route the execution into another loop, a clone of the first one but without the conditional check. Of course, you need another conditional for this routing, but once you reach there, you won't need to check a conditional on each iteration.

If the loop resides in a function, you can clone the function excluding the condition check. Then all you need is some function pointer magic. If you can replace the function pointer in the caller side, you can avoid all conditional checks. But I'm not sure if calling a function using a pointer introduces additional overhead.

\$\endgroup\$
2
\$\begingroup\$

How to make above code look like below after button pressed and output switch is reset. It will not see any if check in its code...

Is it possible to remove some program data from microcontroller flash memory, so it skips these deleted parts and continues with the rest.

No, it is not realistically possible to do what you ask. Some MCUs can reprogram their flash ROM while running, but this takes several milliseconds and can only be done a limited number of times. Self-modifying code is rarely needed and has many hazards. When applied to Flash ROM it could quickly wear out the memory, or 'brick' the MCU if power is disconnected while writing. The extra code needed and time spent reprogramming the ROM could greatly exceed what you save.

You are attempting an optimization that should not be necessary if your MCU has sufficient processing power and memory. Unless you have a very critical application and cannot use a more capable MCU this is completely unnecessary.

Several answers have been given that explain how your code can be modified by falling into another loop or using a boolean to skip the parts you don't want to execute. Use one of these methods and don't worry about the extra code involved. Concentrate on writing logically sound 'clean' code that makes your intention clear and doesn't rely on hacks to work.

\$\endgroup\$
2
  • \$\begingroup\$ Well, I would not say "no, it is not realistically possible", because we don't know how many times the OP want to do this, and what the other requirements are. To just patch a certain part of the code once, it is possible, given that the chip can do this at all. -- Anyway, +1. \$\endgroup\$ – the busybee Jan 31 at 21:19
  • \$\begingroup\$ OK, i got it. Good answer, thank you. \$\endgroup\$ – tuncel3 Feb 1 at 2:29
2
\$\begingroup\$

There is an if check in while loop of a microcontroller. When something happens it detects it and does what is required. After that the microcontroller should not check this condition anymore to save CPU time.

The correct approach depends on what your condition is.

  • If "something happens" is a hardware event then you can use an interrupt to check for it. In that case you don't waste any CPU cycles polling for the event within the loop.

  • If "something happens" is the state of a variable in software then you can break your loop into two parts. The first loop checks for "something_happens". The second loop is identical, but doesn't check for the "something_happens".

for example...

while(condition){
   do_stuff();
    if(something_happens()){
        break;//exit first loop after something happens
    }
}
//continue identical second loop without condition check.
while(condition){
    do_stuff();
}
  • If "something happens" is a complex condition then you can save time by reducing the complex check into a boolean flag.

If for example "something happens" was (A && B && C && D && E && F && G) then you might write the following...

int flag = 0;
while(condition){
   do_stuff();
   if(flag == 0){
     if(A && B && C && D && E && F && G){
       handle_complex_condition();
       flag = 1;
     }
   }
}

In this case we have one extra check check for a flag for each iteration of the loop, but after the condition occurs we only check the flag and don't have to do the six AND operations, so overall we can save CPU cycles. But if the condition is never met, or met very near the end of the loop then we will actually take more cycles, so this approach is not a guarantee.

I am asking how to remove a line of code from execution from microcontroller program memory.

Modifying flash program memory while the CPU is executing code out of that page is impossible for many families of microcontrollers. The STM32 can execute code from RAM. In that case its possible to simply write NOPs to the location in RAM that corresponds to the if statement. To do that you would need the exact addresses of those instructions. Generally one would create a label and then load the address of the label into a pointer. One would then write NOPs using the pointer. Also, in order for this to work you would probably have to disable the instruction cache for the STM32 (or at least cause it to flush).

But that whole process is much more complicated than the non self-modifying code examples above.

\$\endgroup\$
1
  • \$\begingroup\$ or just if (flag == 0 && A && B && C...) since && short-circuits. \$\endgroup\$ – ilkkachu Jan 31 at 20:53
1
\$\begingroup\$

The simplest method is something like this:

while(condition)
{
        int event, event_has_occurred;
        // other declarations
        event = 0;
        event_has_occurred = 0;
        
        if(!event_has_occurred) // only executes if event has not yet occurred
        { 
            event = check_for_event(); // return true if it has happened
            if(event)
            {
                process_event(); // do whatever is necessary
                event_has_occurred = true; // assuming true is defined as non-zero
            }
        }
        // do regular stuff here

 } // end while

You could play games with function pointers and such but that seems overly complex when a single test can suffice.

\$\endgroup\$
1
\$\begingroup\$

Keep it simple with beginner-level C...

bool dont_do_stuff=false;

while(dont_do_stuff || stuff)
{
  if(something)
  {
    dont_do_stuff = true;
  }
}

This will keep checking stuff until dont_do_stuff is set.

\$\endgroup\$
1
\$\begingroup\$

If you want to change the functionality, you could do that by editing the ROM (if you have access to it, change the firmware file, this isn't trivial to do). You would have to use assembly and machine code, micro controllers don't understand C, it gets compiled\assembled to machine code. You would also have to find the location of that coffee in the ROM.

The if then statement has a jump instruction, and usually a compare instruction before that (not sure with this architecture of processor). You could change the compare instruction so the of statement always

I haven't used eclipse for a long time, but there is probably a way to look at the machine code and c side by side (you might have to debug a different processor).

That being said it would probably be easier to just disconnect the reset button

\$\endgroup\$
0
\$\begingroup\$

Run the code in question out of RAM. When the condition check is evaluated as true and the special case gets handled, have it also write over the original conditional test with NOPs.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Are you sure NOPs are faster than the test they replace? \$\endgroup\$ – marcelm Jan 28 at 19:36
  • \$\begingroup\$ @marcelm No, I didn't check. If so then the entire loop could be rewritten to eliminate the test and the branch. \$\endgroup\$ – Elliot Alderson Jan 28 at 21:56
  • \$\begingroup\$ Generally, self-modifying code in RAM is a royally bad idea, even when the OP isn't some beginner. \$\endgroup\$ – Lundin Jan 29 at 11:14
  • 1
    \$\begingroup\$ @Lundin I agree, it is quite dangerous, but I thought the question was sufficiently vague that I would throw it out there. The "Is is possible..." questions invite this sort of answer. \$\endgroup\$ – Elliot Alderson Jan 29 at 12:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.