`
爱迪生的小屋
  • 浏览: 35622 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

在Arduino上用Java编程-序

阅读更多

在Arduino上用Java编程

    继两个星期前成功实现了java版JVM bytecode解释器TotoroVM(见:http://edisonlovecola.iteye.com/blog/1860545)之后,边着手在arduino平台上实现它c++版,边更新博客(由于忙着实现功能,拖延了更新,以后补上这部分内容)。写完了解释器的代码解释部分,就遇到了从class文件从哪里读取的问题。

    Arduino Uno存储分为2K的RAM,1K的EEPROM和32K的Flash,根据java版解释器的经验,一套基本的java框架,至少包含Object, Class, String类,再加上系统功能调用的System和Arduino类,怎么说都不可能压缩到2K内存以下。也考虑过用SD卡来当外存在保存,细想一下,又会有读取速度和通用性的瓶颈,就在我设法压缩ConstantPool大小的过程中。一个新的想法诞生-何不干脆就放弃保存ConstantPool,将它的信息固化到代码中,再进一步,就是直接把java的bytecode直接编译成c++代码,再用avr-gcc进行二次编译,这样还可以充分利用avr-gcc的优化功能。

    考虑之后,觉得这个方法可行,经过两个星期的努力,今天TotoroVM Compile版正式诞生。

    先试编译一个简单的Arduino程序,类似Blink程序,让13号led灯一秒闪一次:

    Main程序代码

package console;

import arduino.Arduino;
import arduino.Serial;

public class Main extends Arduino {
    
    public Main() {
        pinMode(13, OUTPUT);
    }
    
    private boolean v = false;
    
    public void loop() {
        digitalWrite(13, v = !v);
        delay(1000);
    }
    
    public static void main(String[] args) {
        new Main().start();
    }

}

    Arduino基本类:

package arduino;

public abstract class Arduino {
    
    public static final int HIGH = 1;
    public static final int LOW = 0;
    public static final int INPUT = 0;
    public static final int OUTPUT = 1;
    public static final int INPUT_PULLUP = 2;
    
    public static final int SS = 10;
    public static final int MOSI = 11;
    public static final int MISO = 12;
    public static final int SCK = 13;

    public static final int SDA = 18;
    public static final int SCL = 19;
    public static final int LED_BUILTIN = 13;

    public static final int A0 = 14;
    public static final int A1 = 15;
    public static final int A2 = 16;
    public static final int A3 = 17;
    public static final int A4 = 18;
    public static final int A5 = 19;
    public static final int A6 = 20;
    public static final int A7 = 21;

    public static native void init();

    public static native void pinMode(int pin, int mode);
    public static native void digitalWrite(int pin, boolean val);
    public static native boolean digitalRead(int pin);
    public static native void analogReference(int mode);
    public static native int analogRead(int pin);
    public static native void analogWrite(int pin, int val);

    public static native long millis();
    public static native long micros();
    public static native void delay(long ms);
    public static native void delayMicroseconds(int ms);
    public static native long pulseIn(int pin, int state, long timeout);

    public static native void shiftOut(int dataPin, int clockPin, int bitOrder, byte val);
    public static native byte shiftIn(int dataPin, int clockPin, int bitOrder);

    public Arduino() {
        init();
    }
    
    public void loop() {}
    
    public void start() {
        for(;;) loop();
    }
    
}

 

    编译结果:

    

#include "console_Main.h"

// console/Main.<implements>()
jboolean console_Main__implements_(jreference clz) {
    return arduino_Arduino__implements_(clz);
}

// console/Main.<extends>()
jboolean console_Main__extends_(jreference clz) {
    if (clz == 72) return 1;
    return arduino_Arduino__extends_(clz);
}

// console/Main.<functions>()
vfunc console_Main__functions_(jint index) {
    if (index == 1) return console_Main_loop__V;
    return arduino_Arduino__functions_(index);
}

// console/Main.<interface functions>()
vfunc console_Main__interface_functions_(jreference intf, jint index) {
    return arduino_Arduino__interface_functions_(intf, index);
}

// console/Main.<init>()V
void console_Main__init___V() {
    jint vi = si - 1;
    si = vi + 1;
 _0:								// ALOAD_0
    apush(avalv(0));
 _1:								// INVOKESPECIAL
    arduino_Arduino__init___V();
 _4:								// ALOAD_0
    apush(avalv(0));
 _5:								// ICONST_0
    ipush(0);
 _6:								// PUTFIELD
    tmp1.z = zpop(); tmp2.a = apop(); field_z_console_Main_v(tmp2.a) = tmp1.z;
 _9:								// BIPUSH
    ipush(13);
 _11:								// ICONST_1
    ipush(1);
 _12:								// INVOKESTATIC
    arduino_Arduino_pinMode_II_V();
 _15:								// RETURN
    si = vi; return;
}

// console/Main.loop()V
void console_Main_loop__V() {
    jint vi = si - 1;
    si = vi + 1;
 _0:								// BIPUSH
    ipush(13);
 _2:								// ALOAD_0
    apush(avalv(0));
 _3:								// ALOAD_0
    apush(avalv(0));
 _4:								// GETFIELD
    tmp1.a = apop(); zpush(field_z_console_Main_v(tmp1.a));
 _7:								// IFEQ
    if (! (ipop() == 0) ) {
     _10:								// ICONST_0
        ipush(0);
     _11:								// GOTO
        goto _15;
    }
 _14:								// ICONST_1
    ipush(1);
 _15:								// DUP_X1
    dups(0, 1); dups(1, 2); dups(2, 0); si++;
 _16:								// PUTFIELD
    tmp1.z = zpop(); tmp2.a = apop(); field_z_console_Main_v(tmp2.a) = tmp1.z;
 _19:								// INVOKESTATIC
    arduino_Arduino_digitalWrite_IZ_V();
 _22:								// LDC2_W
    lpush(1000);
 _25:								// INVOKESTATIC
    arduino_Arduino_delay_J_V();
 _28:								// RETURN
    si = vi; return;
}

// console/Main.main([Ljava/lang/String;)V
void console_Main_main__Ljava_lang_String__V() {
    jint vi = si - 1;
    si = vi + 1;
 _0:								// NEW
    apush(allocateInstance(72, 1));
 _3:								// DUP
    dups(0, 1); si++;
 _4:								// INVOKESPECIAL
    console_Main__init___V();
 _7:								// INVOKEVIRTUAL
    getVirtualFunction(avals(1), 2)();
 _10:								// RETURN
    si = vi; return;
}

     在电脑上Windows系统中以MinGW编译通过,回家后实战测试Arduino平台!

     放上编译结果的C++项目,MinGW和cygwin的gcc应该都可以用。

     打算再过一段时候和java版翻译器一起开源,sourceforge还是github呢?求推荐!

分享到:
评论
2 楼 jianwwpro 2013-09-28  

希望继续研究
1 楼 303931362 2013-09-23  
为什么我测试不行呢?

相关推荐

Global site tag (gtag.js) - Google Analytics