avr-llvm / llvm

[MERGED UPSTREAM] AVR backend for the LLVM compiler library
220 stars 21 forks source link

Arduino HardwareSerial TX lighting issue #167

Closed 4ntoine closed 8 years ago

4ntoine commented 9 years ago

after complining and uploading simple Blink sketch TX LED is constantly lighting, no LED on pin 13 blinking.

I had to add serialEventRun function to override wrong behaviour initialied by weak issue: https://github.com/avr-llvm/clang/issues/9

Blink.cpp:

#line 1 "Blink.ino"
/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.

  This example code is in the public domain.
 */

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
#include "Arduino.h"
void setup();
void loop();
#line 10
int led = 13;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

// TODO : remove
// just for testing until ((weak)) is supported
void serialEventRun() {

}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

Then i compiled all the .cpp:

./clang -c -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega328p -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=105 -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/variants/standard -I/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/avr/include --target=avr /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/HardwareSerial.cpp -o /tmp/arduino_test1/HardwareSerial.cpp.o

and packed into .a:

./llvm-ar rcs /tmp/arduino_test1/core.a /tmp/arduino_test1/HardwareSerial.cpp.o 

created archive index:

avr-ranlib /tmp/arduino_test1/core.a

linked:

/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -w -Os -Wl,--gc-sections,--relax -mmcu=atmega328p -o /tmp/arduino_test1/Blink.cpp.elf /tmp/arduino_test1/Blink.cpp.o /tmp/arduino_test1/core.a -L/tmp/arduino_test1 -lm --target=avr 

and prepared hex:

/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-objcopy -O ihex -R .eeprom /tmp/arduino_test1/Blink.cpp.elf /tmp/arduino_test1/Blink.cpp.hex

After flashing with avrdude i'm getting described behaviour.

4ntoine commented 9 years ago

What can i check?

4ntoine commented 9 years ago

hex size seems to be reasonable: MBA-Anton:bin asmirnov$ ls -l /tmp/arduino_test1/Blink.cpp.hex.txt -rw-r--r-- 1 asmirnov wheel 3879 1 окт 11:22 /tmp/arduino_test1/Blink.cpp.hex.txt

dylanmckay commented 9 years ago

HardwareSerial probably uses interrupts under the hood, and due to #162, the interrupt signal routine table is incorrectly generated.

This is probably related.

4ntoine commented 9 years ago

yes it does use interrupts:

// Actual interrupt handlers //////////////////////////////////////////////////////////////

void HardwareSerial::_tx_udr_empty_irq(void)
{
  // If interrupts are enabled, there must be more data in the output
  // buffer. Send the next byte
  unsigned char c = _tx_buffer[_tx_buffer_tail];
  _tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE;

  *_udr = c;

  // clear the TXC bit -- "can be cleared by writing a one to its bit
  // location". This makes sure flush() won't return until the bytes
  // actually got written
  sbi(*_ucsra, TXC0);

  if (_tx_buffer_head == _tx_buffer_tail) {
    // Buffer empty, so disable interrupts
    cbi(*_ucsrb, UDRIE0);
  }
}
4ntoine commented 9 years ago

This is pretty important issue as Arduino does not have debugger and serial is the only way to debug or interact with a board. For now it blocks arduino..

4ntoine commented 9 years ago

i've tried to:

  1. exclude USB-related headers from Arduino.h
// 4ntoine : for now we can't use Serial because of https://github.com/avr-llvm/llvm/issues/167
#ifndef NO_SERIAL
  #include "HardwareSerial.h"
  #include "USBAPI.h"
#endif
  1. compile all the files with -DNO_SERIAL=1
  2. modify main.cpp in order to skip serialRun:
// 4ntoine 
  #ifndef NO_SERIAL  
    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }
  #endif
  1. don't link USB-related files and don't include them into core.a

So i was able to compile Blink.hex:

-rw-r--r-- 1 asmirnov wheel 1989 12 окт 09:36 /tmp/arduino_test1/Blink.cpp.hex

Anyway i'm still having this issue: L (pin 13) is constantly lighting and TX is constantly lighting too.

4ntoine commented 9 years ago

oh, i've noted i used

#ifndef NO_SERIAL  
    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }
  #endif

but i should use:

    for (;;) {
    loop();
        #ifndef NO_SERIAL 
        if (serialEventRun) serialEventRun();
        #endif
    }

now blink is larger:

-rw-r--r-- 1 asmirnov wheel 3793 12 окт 09:43 /tmp/arduino_test1/Blink.cpp.hex

and it's having slightely different behaviour:

dylanmckay commented 8 years ago

Closing as this is a dupe of #192.

4ntoine commented 8 years ago

not sure it's duplicate. in #192 you can't compile avr-llvm but in this task you can compile avr-llvm, but compiled files work incorrectly. consider reopening

dylanmckay commented 8 years ago

Sorry, I meant #162.