1

After answering my previous question correctly I'm getting all sorts of errors when trying to compile the following program:

I'm completely new to both assembly and the arduino IDE so I apologise in advance for any basic errors.

sketch.ino:

#include "blink.S"
extern void blink();
void setup() {
  // put your setup code here, to run once:
blink();
}

void loop() {
  // put your main code here, to run repeatedly:

}

blink.S file:

#define __SFR_OFFSET 0
#include <avr/io.h>         




  .section .text


  ldi r18, 0x20   ; loading 0x20 = 00100000 into register r18
  out DDRB, r18   ; making pin 5 of port B an output

  mov r16, r18    ; copy mask 00100000 also to r16

loop: out PORTB, r16    ; switch on or off the pins of port B
        ; according to bit pattern in r16


  ldi r17, 82   ; 1000ms delay, see below

outer_delay:
  clr r1      
middle_delay:
  clr r2      
inner_delay:        
  dec r2      ; 1 clock tick
  brne inner_delay  ; 2 clock ticks when z!=0, 1 tick when z=0.

  dec r1      ; when this line is reached, about
        ; 256*3 = 768 ticks have been consumed since inner_delay.
  brne middle_delay ; 

  dec r17                 ; when this line is reached, about
        ; 256*256*3 = 196608 ticks have been
        ; consumed since middle delay.
  brne outer_delay  

  eor r16,r18   ; invert bit 5 in r16 using exclusive or.
  rjmp loop   ; jump back to loop.
2
  • 1
    Try just removing #include "blink.S". Nov 9, 2017 at 10:27
  • blink.s is the source of your pain, and removing it will make a big difference, but if you need the assembler then there is normally some sort of keyword to mark the start and end of the assembler and I suspect you .s file might need there IF you need the .s file. I have no idea of what it is, its a long time since I did ASM and then it was on a PC. Nov 9, 2017 at 11:12

2 Answers 2

0

A couple of things you can try.

First, make sure your assembly code makes the blink() function visible to the linker. blink.S should start like this:

#define __SFR_OFFSET 0
#include <avr/io.h>         

.section .text
.global blink
blink:
  ; Your assembly code goes below the above label.

Next, your sketch file should not try to include the assembly source. It should only reference it as an external symbol. And note that the symbol should be declared extern "C".

If your program is a mix of assembly and Arduino code, you could start with this sketch.ino:

extern "C" void blink();

void setup() {
    blink();
}

void loop() {}

If you are not using the Arduino core library, you could instead write:

extern "C" void blink();

int main(void)
{
    blink();
    return 0;
}

And if you don't want to use C++ at all, you could try to use a dummy or empty sketch.ino, and rename “blink” to “main” in blink.S.

1

There's four things I can see wrong (one of which is my fault, actually - I should have mentioned it in the previous question - nevermind).

Firstly you cannot include a .S file in a .INO file. A .S file is assembly, a .INO file is C++. You can't mix the two in one file (and including a file does just that - includes the file verbatim at that point). So remove that #include. Otherwise it would be like opening a book written in English only to find the preface is written in Klingon.

Secondly you need to give your function a name. It doesn't have one at the moment. Naming the file is not naming the function.

So you need to provide a label at the entry point:

  .section .text

blink:    ; << This is the name of the function
  ldi r18, 0x20   ; loading 0x20 = 00100000 into register r18
  out DDRB, r18   ; making pin 5 of port B an output

Third you need to export that name as a global symbol:

  .section .text
  .global blink ; << This exports the function name

blink:    ; << This is the name of the function
  ldi r18, 0x20   ; loading 0x20 = 00100000 into register r18
  out DDRB, r18   ; making pin 5 of port B an output

And finally you have the problem of linkage name munging. You're linking a C++ file with (ostensibly) a C file - and C++ munges names. So you have to tell your C++ file that the function is not a C++ function, but a C function (which is what I should have mentioned previously):

extern "C" void blink(); // << Add the "C" to tell it not to munge the name

void setup() {
  // put your setup code here, to run once:
  blink();
}

void loop() {
  // put your main code here, to run repeatedly:
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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