2

I am just now learning Assembly calls with c. I am trying to change my code, so the assembly code never exits and continues to blink the LED, but I cannot figure out how to do it. I have tried changing the C file to just have the myled=!myled, but that doesnt work.

Change the delay_asm code turn on and off the LED and never exit the delay_asm.s subroutine.

here is the C file and Assembly.

 #include "mbed.h"
DigitalOut myled(LED1);
extern "C" void delay_asm(void);
int main() {
while(1) {
    delay_asm(); 
    myled = !myled; // invert LED state
   }
}

Assembly file:

AREA |.text|, CODE, READONLY
delay_asm     PROC
      EXPORT delay_asm
      MOV R0, #0x01900000
      MOV R1, #1
LOOP      SUBS R0, R1
      BNE LOOP
      BX LR
      ENDP

      ALIGN
      END
Hunter
  • 21
  • 5
  • Have you run it in debugger? – Eugene Sh. Sep 15 '17 at 18:00
  • how does that variable tie to the led? where are you initalizing the gpio block to be enabled and the pin to be an output? – old_timer Sep 15 '17 at 18:04
  • I have tried, but I am new to this, so I am not sure what to do. I am not sure what to change in the assembly file to make it continue to blink the led – Hunter Sep 15 '17 at 18:04
  • the Digitalout line does this, it is a feature in mbed online IDE – Hunter Sep 15 '17 at 18:05
  • you should be able to have a main with while(1) continue; and have the led in one state solid. then add before that inifinite loop a myled =~myled; or != as the case may be and it should be solid in the other state, if that doesnt work then blinking wont work. – old_timer Sep 15 '17 at 18:05
  • The code as it is right now works, but what is needed is to change the assembly file to never branch back out to the c file and continue to blink the led – Hunter Sep 15 '17 at 18:08
  • you have to re-write the program in assembly then. – old_timer Sep 15 '17 at 19:01
  • I would suggest to avoid delays. LEDs are best done in the Timer interrupts. Theoretically it is more complicated but in the fact I do not the way how to archive the same effect like there "blocking way" https://www.diymat.co.uk/arm-blinking-led-driver/ – 0___________ Sep 15 '17 at 19:30
  • Disassemble your C compiler's output (or use `gcc -O2 -S`) to see how it's toggling the LED state. Then you'll know what to do in asm. Related: https://stackoverflow.com/questions/38552116/how-to-remove-noise-from-gcc-clang-assembly-output. I see you already realize that you need to implement (in asm) whatever `DigitalOut myled(LED1);` from `mbed.h` gives you. – Peter Cordes Sep 15 '17 at 23:59

1 Answers1

0

You need to re-engineer the 'feature of the mbed online IDE' which you mention in the comments. mbed provides a hardware abstraction later to achieve this. For example, here for M3 DesignStart (which is a very simple SoC, minimal pin muxing and no clocks to worry about). Look at the patch which added support for this platform to see the extent of the code.

The hal is very modular so it can be customised to suit a wide range of hardware. Not the 'Cortex-M4' processor, but the SoC level GPIO and other peripherals. You should always refer to the particular SoC you're using in this scenario.

There are two parts to using a GPIO. You need to configure the pin and the peripheral. This should be done by the C++ constructor (so maybe you will want to keep that in your code). Then each access to read or write the status will typically be a single memory access to the specific peripheral.

You could of course call the hal's functions with your assembly code, but that sounds like an unnecessary diversion into how to interface C++ to assembler (be aware that mbed is C++).

Sean Houlihane
  • 1,698
  • 16
  • 22