KURUMIのローカルビルドとe2studio5.4について

TETNOGUCHIです。

 

さて、久しぶりに KURUMIのArduinoを触ることになりそうなので
せっかくなので e2studioのローカルビルド環境をこの際設定しておきたく

e2studio 5.4.0

KPIT GCC v15

をダウンロードしてきて、導入しました。

GR-KURUMI e2studio(V4)用スケッチ環境 V1.12

http://japan.renesasrulz.com/gr_user_forum_japanese/m/mediagallery/230

を参考に(KPITもe2studioもリンク切れですが)スケッチもダウンロードして、インポートしました。

ここまでは eclipseの普通の手順なので安心していたのですが
ビルドすると

===============================

'Invoking: Scanner and Compiler'
C:\Users\noguchi\AppData\Local\Temp\ccdAx87Y.s: Assembler messages:
C:\Users\noguchi\AppData\Local\Temp\ccdAx87Y.s:1426: Error: redefined symbol cannot be used on reloc
src/RLduino78/cores/subdir.mk:69: recipe for target 'src/RLduino78/cores/RLduino78_basic.o' failed
make: *** [src/RLduino78/cores/RLduino78_basic.o] Error 1
make: *** Waiting for unfinished jobs....

===============================

というエラーでコンパイルに失敗してしまいます。
Local\Tempのなにがし、ってのもきになるんですが、
HardwareDebug/src/RLduino78/cores/subdir.mk
の69行目からの部分で
/src/RLduino78/cores/RLduino78_basic.cpp

シンボルの重複?でエラーになっているようです。
これって治ります?

それとも
GCC v14に戻したほうがいいんでしょうか?
それともe2studio v4に?

できれば最新環境のほうがありがたいのですが、メンテナンスはされているのでしょうか?

もしくは解決策があるなら教えていただきたく。

以上、よろしくお願いいたします。

Parents
  • 試しにGCC V14に落とすとコンパイルが通って、バイナリが作成されました。
    どうやら15にするとダメみたいですね。

    GDB+E1でデバッグできるかどうかは後日確かめてみます。
  • あ、もう解決したんですね。
  • 私も同様にエラーが出ますね。環境は4.9.2.201701-GNURL78、e2 studio Version: 5.2.0.020

    現在はGR-KURUMI, COTTON, ADZUKI三種のRL78統合Arduinoライブラリメンテをしてまして、以下の通りのエラーです。

    'Invoking: Scanner and Compiler'

    C:\Users\a5034000\AppData\Local\Temp\cc7KVsCv.s: Assembler messages:

    C:\Users\a5034000\AppData\Local\Temp\cc7KVsCv.s:220: Error: redefined symbol cannot be used on reloc

    'Scanning and building file: ../arduino/gr_sketch.cpp'

    arduino/cores/subdir.mk:104: recipe for target 'arduino/cores/wiring_pulse.o' failed

    make: *** [arduino/cores/wiring_pulse.o] Error 1

    make: *** Waiting for unfinished jobs....

     

    エラーが発生するwiring_pulse.cは以下の通りで、インラインアセンブルがあり、その部分をif 1にして無効にするとコンパイルは通ります。Fujitaさんにアセンブルで高速化を図っていただいていたのですが、4.9.2.201701では不整合が生じてしまうのですかね。

     

    /*
    wiring_pulse.c - pulseIn() function
    Part of Arduino - http://www.arduino.cc/

    Copyright (c) 2005-2006 David A. Mellis

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General
    Public License along with this library; if not, write to the
    Free Software Foundation, Inc., 59 Temple Place, Suite 330,
    Boston, MA 02111-1307 USA

    $Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
    */
    /*
    * Modified 5 Mar 2017 by Yuuki Okamiya for RL78/G13
    */

    #include "wiring_private.h"
    #include "pins_arduino.h"
    #include "pintable.h"

    #ifdef __RL78__
    static bool pulseInWait(
    volatile uint8_t* Px,
    uint8_t u8Bit,
    uint8_t u8StateMask,
    unsigned long* u32TimeoutCycles
    ) {
    bool ret;
    #if 0
    const unsigned char u16PulseInWaitCycles = 30;
    while ((*Px & u8Bit) == u8StateMask) {
    if (*u32TimeoutCycles >= u16PulseInWaitCycles) {
    *u32TimeoutCycles -= u16PulseInWaitCycles;
    } else {
    ret = true;
    break;
    }
    }
    ret = false;
    #else
    __asm __volatile(
    " clrb %0 \n"
    " movw de, %1 \n"
    " mov a, %2 \n"
    " mov b, a \n"
    " mov a, %3 \n"
    " mov c, a \n"
    " movw hl, %4 \n"
    "1: \n"
    " mov a, [de] ;1 \n"
    " and a, b ;1 \n"
    " cmp a, c ;1 \n"
    " bnz $2f ;2/4 \n"
    " movw ax, [hl] ;1 \n"
    " subw ax, #PulseInWaitCycles ;1 \n"
    " movw [hl], ax ;1 \n"
    " movw ax, [hl+2] ;1 \n"
    " sknc ;1 \n"
    " subw ax, #1 ;1 \n"
    " movw [hl+2], ax ;1 \n"
    " bnc $1b ;2/4 \n"
    " .equiv PulseInWaitCycles, 1+1+1+2+1+1+1+1+1+1+1+4 \n"
    " oneb %0 \n"
    "2: \n"
    :"=&r"(ret)
    :"r"(Px), "r"(u8Bit), "r"(u8StateMask), "r"(u32TimeoutCycles)
    :"ax", "bc", "de", "hl"
    );
    #endif
    return ret;
    }

    static bool pulseInCount(
    volatile uint8_t* Px,
    uint8_t u8Bit,
    uint8_t u8StateMask,
    unsigned long u32TimeoutCycles,
    unsigned long* u32PulseCycles
    ) {
    bool ret;
    #if 0
    const unsigned long u16PulseInCountCycles = 35;
    *u32PulseCycles = 0;
    while ((*Px & u8Bit) == u8StateMask) {
    if (u32TimeoutCycles >= u16PulseInCountCycles) {
    u32TimeoutCycles -= u16PulseInCountCycles;
    } else {
    ret = true;
    break;
    }
    *u32PulseCycles += u16PulseInCountCycles;
    }
    ret = false;
    #else
    __asm __volatile(
    " clrb %0 \n"
    " movw de, %1 \n"
    " mov a, %2 \n"
    " mov b, a \n"
    " mov a, %3 \n"
    " mov c, a \n"
    " movw hl, %5 \n"
    " movw ax, PulseInWaitCycles/2+PulseInCountCycles/2 \n"
    " movw [hl], ax \n"
    " clrw ax \n"
    " movw [hl+2], ax \n"
    " br $2f \n"
    "1: \n"
    " movw ax, [hl] ;1 \n"
    " addw ax, #PulseInCountCycles ;1 \n"
    " movw [hl], ax ;1 \n"
    " movw ax, [hl+2] ;1 \n"
    " sknc ;1 \n"
    " incw ax ;1 \n"
    " movw [hl+2], ax ;1 \n"
    "2: \n"
    " mov a, [de] ;1 \n"
    " and a, b ;1 \n"
    " cmp a, c ;1 \n"
    " bnz $3f ;2/4 \n"
    " movw ax, %4+0 ;1 \n"
    " subw ax, #PulseInCountCycles ;1 \n"
    " movw %4+0, ax ;1 \n"
    " movw ax, %4+2 ;1 \n"
    " sknc ;1 \n"
    " subw ax, #1 ;1 \n"
    " movw %4+2, ax ;1 \n"
    " bnc $1b ;2/4 \n"
    " .equiv PulseInCountCycles, 1+1+1+1+1+1+1+1+1+1+2+1+1+1+1+1+1+1+4 \n"
    " oneb %0 \n"
    "3: \n"
    :"=&r"(ret)
    :"r"(Px), "r"(u8Bit), "r"(u8StateMask), "r"(u32TimeoutCycles), "r"(u32PulseCycles)
    :"ax", "bc", "de", "hl"
    );
    #endif
    return ret;
    }
    #endif
    /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
    * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
    * to 3 minutes in length, but must be called at least a few dozen microseconds
    * before the start of the pulse. */
    unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
    {
    #ifndef __RL78__
    // cache the port and bit of the pin in order to speed up the
    // pulse width measuring loop and achieve finer resolution. calling
    // digitalRead() instead yields much coarser resolution.
    uint8_t bit = digitalPinToBitMask(pin);
    uint8_t port = digitalPinToPort(pin);
    uint8_t stateMask = (state ? bit : 0);
    unsigned long width = 0; // keep initialization out of time critical area

    // convert the timeout from microseconds to a number of times through
    // the initial loop; it takes 16 clock cycles per iteration.
    unsigned long numloops = 0;
    unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;

    // wait for any previous pulse to end
    while ((*portInputRegister(port) & bit) == stateMask)
    if (numloops++ == maxloops)
    return 0;

    // wait for the pulse to start
    while ((*portInputRegister(port) & bit) != stateMask)
    if (numloops++ == maxloops)
    return 0;

    // wait for the pulse to stop
    while ((*portInputRegister(port) & bit) == stateMask) {
    if (numloops++ == maxloops)
    return 0;
    width++;
    }

    // convert the reading to microseconds. The loop has been determined
    // to be 20 clock cycles long and have about 16 clocks between the edge
    // and the start of the loop. There will be some error introduced by
    // the interrupt handlers.
    return clockCyclesToMicroseconds(width * 21 + 16);
    #else
    /**
    * ピンに入力されるパルスを検出します。
    *
    * たとえば、パルスの種類(u8Value)をHIGHに指定した場合、 pulseIn()関数は入力がHIGHに
    * 変わると同時に時間の計測を始め、またLOWに戻ったら、そこまでの時間(つまりパルス
    * の長さ)をマイクロ秒単位で返します。タイムアウトを指定した場合は、その時間を超
    * えた時点で0を返します。
    *
    * @param[in] u8Pin パルスを入力するピン番号を指定します。
    * @param[in] u8Value 測定するパルスの種類(HIGHまたはLOW)を指定します。
    * @param[in] u32Timeout タイムアウトまでの時間(単位・マイクロ秒)を指定します。
    *
    * @return パルスの長さ(マイクロ秒)を返却します。
    * パルスがスタートする前にタイムアウトとなった場合は0を返却します。
    *
    * @attention なし
    ***************************************************************************/
    uint8_t u8StateMask;
    unsigned long u32TimeoutCycles;
    unsigned long u32PulseCycles;
    unsigned long u32PulseLength = 0;
    bool timeOut;


    if (pin < NUM_DIGITAL_PINS) {
    PinTableType* p = getPinTable(pin);
    u8StateMask = (state ? p->mask : 0);
    {
    u32TimeoutCycles = microsecondsToClockCycles(timeout);
    timeOut = pulseInWait(p->portRegisterAddr, p->mask, u8StateMask, &u32TimeoutCycles);

    if (!timeOut) {
    timeOut = pulseInWait(p->portRegisterAddr, p->mask, u8StateMask ^ p->mask, &u32TimeoutCycles);
    if (!timeOut) {
    timeOut = pulseInCount(p->portRegisterAddr, p->mask, u8StateMask, u32TimeoutCycles, &u32PulseCycles);
    }
    }
    if (!timeOut) {
    u32PulseLength = clockCyclesToMicroseconds(u32PulseCycles);
    }
    }
    }


    return u32PulseLength;

    #endif
    }
  • > Fujitaさんにアセンブルで高速化を図っていただいていたのですが、4.9.2.201701では不整合が生じてしまうのですかね。

    高速化ではなく、実行の際のクロック数の特定が必要な箇所なのでインラインアセンブラを使用しています。コンパイラでは出力コードの保証ができません。
  • Fujitaさん、ありがとうございました。私の環境では無事にビルドできました。この変更を反映させていただきます。統合ライブラリのwiring_pulse.cに以下の変更履歴を追加したいと思いますが、問題あれば言ってください。
     * Modified 18 Mar 2017 by Nozomu Fujita for pulseInWait, pulseInCount

    なるほど、この部分は確かに高速化ではないですね。
  • > この変更を反映させていただきます。

    ちょっと計測結果に誤差がでてるので調整中です。終わったら再度投稿します。
  • 了解です。恐れ入りますが、よろしくお願いいたします!
  • 添付のものに差し替えお願いします。

    テスト用スケッチ:

    /*GR-KURUMI Sketch Template Version: V1.13*/
    #include <Arduino.h>
    
    const int pinPulseOut = 3;
    const int pinPulseIn = 2;
    
    void setup()
    {
        Serial.begin(9600);
    }
    
    void loop()
    {
        for (int i = 1; i <= 255; i++) {
            analogWrite(pinPulseOut, i);
            for (int j = 0; j < 10; j++) {
                noInterrupts();
                unsigned long highWidth = pulseIn(pinPulseIn, HIGH, 100000UL);
                unsigned long lowWidth  = pulseIn(pinPulseIn, LOW, 100000UL);
                interrupts();
                char buf[100];
                sprintf(buf, "%8ld: high(%3d) low(%3d) => high(%3ld) low(%3ld)", millis(), 8 * i, 8 * (255 - i), highWidth, lowWidth);
                Serial.println(buf);
                Serial.flush();
            }
        }
    }
    

    使い方:

     ピン3 に出力される 8μ秒きざみの PWM のパルス幅をピン2 に入力し、HIGH と LOW それぞれのパルス幅を測定してターミナル等に出力する。ピン2 とピン3 を結線し、ピン1(TXD) をターミナル等に接続する必要がある。

    実行結果:

           1: high(  8) low(2032) => high(  8) low(2032)
          58: high(  8) low(2032) => high(  8) low(2032)
         115: high(  8) low(2032) => high(  8) low(2032)
         172: high(  8) low(2032) => high(  8) low(2032)
         229: high(  8) low(2032) => high(  8) low(2032)
         287: high(  8) low(2032) => high(  8) low(2032)
         345: high(  8) low(2032) => high(  8) low(2032)
         403: high(  8) low(2032) => high(  8) low(2032)
         460: high(  8) low(2032) => high(  8) low(2032)
         517: high(  8) low(2032) => high(  8) low(2032)
         574: high( 16) low(2024) => high( 16) low(2024)
         631: high( 16) low(2024) => high( 16) low(2024)
         688: high( 16) low(2024) => high( 16) low(2024)
         746: high( 16) low(2024) => high( 16) low(2024)
         804: high( 16) low(2024) => high( 16) low(2024)
         862: high( 16) low(2024) => high( 16) low(2024)
         919: high( 16) low(2024) => high( 16) low(2024)
         976: high( 16) low(2024) => high( 16) low(2024)
        1033: high( 16) low(2024) => high( 16) low(2024)
        1090: high( 16) low(2024) => high( 16) low(2024)
        1147: high( 24) low(2016) => high( 25) low(2016)
        1205: high( 24) low(2016) => high( 24) low(2016)
        1263: high( 24) low(2016) => high( 24) low(2016)
        1321: high( 24) low(2016) => high( 24) low(2016)
        1378: high( 24) low(2016) => high( 24) low(2016)
        1435: high( 24) low(2016) => high( 24) low(2016)
        1492: high( 24) low(2016) => high( 24) low(2016)
        1549: high( 24) low(2016) => high( 24) low(2016)
        1606: high( 24) low(2016) => high( 24) low(2016)
        1664: high( 24) low(2016) => high( 24) low(2016)
    

  • fujitaさん、ありがとうございます。

    うちでも試してみました。
    たしかに

    ビルド完了できました!
    ありがとうございます。
    これですこし、勘をとりもどしていきます。
  • Fujitaさん、ご返信遅くなりすみません。pulseIn関連の修正ありがとうございました。正しく動作しました。
    C言語側の測定は多少ずれるのですが、アセンブルの方は完璧ですね。
Reply Children
No Data