目次(備忘録)

スポンサーサイト

C++でファイルのパーミッションを変更する chmod() (備忘録)

■ソース
#include <stdio.h>
#include <sys/stat.h>

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main(){
    string filename = "/sys/class/gpio/gpio27/direction";
    if (chmod(filename.c_str(),0x1ff) == 0) {
        cout << "chmod OK (" + filename + ")" << endl;
    } else {
        cout << "chmod error (" + filename + ")" << endl;
    }

    filename = "/sys/class/gpio/gpio27/value";
    if (chmod(filename.c_str(),0x77)== 0) {
        cout << "chmod OK (" + filename + ")" << endl;
    } else {
        cout << "chmod error (" + filename + ")" << endl;
    }
}

■実行結果
sudo ./test01

※実行前
-rw-r--r-- 1 root root 4096 12月  4 11:51 /sys/class/gpio/gpio27/active_low
lrwxrwxrwx 1 root root    0 12月  4 11:51 /sys/class/gpio/gpio27/device -> ../../../20200000.gpio
-rw-r--r-- 1 root root 4096 12月  4 11:51 /sys/class/gpio/gpio27/direction
-rw-r--r-- 1 root root 4096 12月  4 11:51 /sys/class/gpio/gpio27/edge
lrwxrwxrwx 1 root root    0 12月  4 11:50 /sys/class/gpio/gpio27/subsystem -> ../../../../../../class/gpio
-rw-r--r-- 1 root root 4096 12月  4 11:50 /sys/class/gpio/gpio27/uevent
-rw-r--r-- 1 root root 4096 12月  4 11:51 /sys/class/gpio/gpio27/value

※実行後
-rw-r--r-- 1 root root 4096 12月  4 11:54 /sys/class/gpio/gpio27/active_low
lrwxrwxrwx 1 root root    0 12月  4 11:54 /sys/class/gpio/gpio27/device -> ../../../20200000.gpio
-rwxrwxrwx 1 root root 4096 12月  4 11:54 /sys/class/gpio/gpio27/direction
-rw-r--r-- 1 root root 4096 12月  4 11:54 /sys/class/gpio/gpio27/edge
lrwxrwxrwx 1 root root    0 12月  4 11:54 /sys/class/gpio/gpio27/subsystem -> ../../../../../../class/gpio
-rw-r--r-- 1 root root 4096 12月  4 11:54 /sys/class/gpio/gpio27/uevent
---xrw-rwx 1 root root 4096 12月  4 11:54 /sys/class/gpio/gpio27/value

■key
Raspberry Pi GPIO アクセス権

※2015/11実行

C++ volatile forループ変数の効果を目で見る(備忘録)

最適化を抑止する volatile を空ループのループ変数に使用した場合の効果を目で見えるようにして確認しました。

下記のforの比較です。

for (volatile int n = 0;5000 > n;n++){};

for (int n = 0;5000 > n;n++){};



テストの概要


1.Raspberry Pi のGPIO端子に信号を出し、それをオシロスコープで観測する。
2.forループの直前でGPIO27をONにし、
3.forループを実行
4.forループの直後にGPIO27をOFFとする。
5.テストの最初には、オシロスコープでトリガを掛けやすいように基本パルスを発生させる。
6.それぞれの間にsleepで時間をとる。

ソース概要


int main(int argc, char *argv[], char *envp[])
{

//メモリマップ取得
    sel = get_gpio_map();
    if ((int)sel == -1) {
        return 1;
    }

    //GPIO27をOUTPUTに設定
    GPFSELOUTPUT(sel,27);  //sel->fsel27 = GPIOOUTPUT;

    for (int i = 0;1000000>i;i++){
        //基本パルス幅確認用
        GPSETN(sel,27); //ポートをON
        nano_sleep(100000);
        GPCLRN(sel,27); //ポートをOFF
        nano_sleep(100000);

        //for 内
        GPSETN(sel,27); //ポートをON
        for (volatile int n = 0;5000 > n;n++){};
        GPCLRN(sel,27); //ポートをOFF

        nano_sleep(100000);

        //for 内
        GPSETN(sel,27); //ポートをON
        for (int n = 0;5000 > n;n++){};
        GPCLRN(sel,27); //ポートをOFF

        nano_sleep(1000000);
    }


    return 0;
}


※ GPSETN() GPCLRN() はGPIOポートのON,OFF制御用です。

結果


C++ volatile forループ変数の効果を目で見る(備忘録)
最初のパルはトリガ用のパルス。
中央のパルスがvolatileを指定したforループの実行期間。
三番目の細いパルスはvolatileなしのループの実行期間。

volatileを指定しない空ループはネグられている事がわかります。


※実行環境については省力します。

Raspberry Pi nanosleep関数の指定値と結果確認 C++ (備忘録)

Raspberry Pi B Rev2 (china)

最小指定単位:1nsec
オーバーヘッド:80~200μsec程度あり。

■ソース
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main (int argc, char *argv[],char *envp[])
{
    timeval *t;
    int loop = 0;
    struct timespec req;
    int now_sec;

    printf("nanosleep execution time test Optimization Level None(-O0) testno:0001\n");

    req.tv_sec  = 0;
    req.tv_nsec = 0; // (ns)



    if (argc == 4){
        loop = atoi(argv[1]);
        req.tv_sec = atoi(argv[2]);
        req.tv_nsec = atoi(argv[3]);
    }

    t = new timeval[loop+2];

    gettimeofday(t+loop, NULL);
    for (int i = 0; i < loop; i++) {
        nanosleep(&req, NULL);
    }
    gettimeofday(t+loop+1, NULL);
    now_sec = t[loop].tv_sec;

    printf(" loop=%1d\n",loop);
    printf(" req.tv_sec=%1ld\n",req.tv_sec);
    printf(" req.tv_nsec=%1ld\n",req.tv_nsec);

    long begin_us =  ((long)t[loop].tv_sec - now_sec)*1000000 + (long)t[loop].tv_usec;
    printf("%09ld(usec) loop begin\n", begin_us);

    long end_us =  ((long)t[loop+1].tv_sec - now_sec)*1000000 + (long)t[loop+1].tv_usec;
    printf("%09ld(usec) loop end\n", end_us);

    printf("%09ld(usec)/%1d loop\n", end_us - begin_us,loop);
    if (loop <> 0){
        printf("%09ld(usec)/one loop\n",(end_us - begin_us)/loop);
    }
    return 0;
}



■結果
■0loop 0s 0nsec
nanosleep execution time test Optimization Level None(-O0) testno:0001
 loop=0
 req.tv_sec=0
 req.tv_nsec=0
000451782(usec) loop begin
000451788(usec) loop end
000000006(usec)/0 loop

■1loop 0s 0ns
nanosleep execution time test Optimization Level None(-O0) testno:0001
 loop=1
 req.tv_sec=0
 req.tv_nsec=0
000061557(usec) loop begin
000064010(usec) loop end
000002453(usec)/1 loop
000002453(usec)/one loop

■100loop 0s 0ns
nanosleep execution time test Optimization Level None(-O0) testno:0001
 loop=100
 req.tv_sec=0
 req.tv_nsec=0
000453818(usec) loop begin
000462135(usec) loop end
000008317(usec)/100 loop
000000083(usec)/one loop

■100loop 0s 10ns
nanosleep execution time test Optimization Level None(-O0) testno:0001
 loop=100
 req.tv_sec=0
 req.tv_nsec=10
000511593(usec) loop begin
000519952(usec) loop end
000008359(usec)/100 loop
000000083(usec)/one loop

■100loop 0s 100ns
nanosleep execution time test Optimization Level None(-O0) testno:0001
 loop=100
 req.tv_sec=0
 req.tv_nsec=100
000803488(usec) loop begin
000812377(usec) loop end
000008889(usec)/100 loop
000000088(usec)/one loop

■100loop 0s 100000ns
nanosleep execution time test Optimization Level None(-O0) testno:0001
 loop=100
 req.tv_sec=0
 req.tv_nsec=100000
000226126(usec) loop begin
000249288(usec) loop end
000023162(usec)/100 loop
000000231(usec)/one loop

■100loop 0s 100000000ns
nanosleep execution time test Optimization Level None(-O0) testno:0001
 loop=100
 req.tv_sec=0
 req.tv_nsec=100000000
000222490(usec) loop begin
010234174(usec) loop end
010011684(usec)/100 loop
000100116(usec)/one loop



■環境
Raspberry Pi B Rev2 (china)

Linux raspberrypi 4.1.13+ #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015 armv6l GNU/Linux


Eclipse IDE for C/C++ Developers
Version: Mars.1 Release (4.5.1)
Build id: 20150924-1200


 <?xml version="1.0"?>
-<Toolchain xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ToolchainName>Raspberry PI</ToolchainName>
      <ToolchainType>Linux</ToolchainType>
      <PathDetectionKeyStrip>0</PathDetectionKeyStrip>
      <GNUTargetID>arm-linux-gnueabihf</GNUTargetID>
      <ToolchainID>com.visualgdb.raspberry_pi</ToolchainID>
      <BinaryDirectory>bin</BinaryDirectory>
      <Prefix>arm-linux-gnueabihf-</Prefix>
      <Make>make.exe</Make>
      <BSPIndexUrlFormat>http://visualgdb.com/hwsupport/BSP/?autofetch=1&target=arm-linux-gnueabihf&filter={0}</BSPIndexUrlFormat>
      <IsCygwinBased>false</IsCygwinBased>
      <GCCVersion>4.9.2</GCCVersion>
      <GDBVersion>7.10</GDBVersion>
      <Revision>1</Revision>
      <RelativeSysrootPath>arm-linux-gnueabihf\sysroot</RelativeSysrootPath>
 </Toolchain>



※2015/12 実施

Raspberry Pi C++ gettimeofday 実行時間テスト (備忘録)

■ソース
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

using namespace std;

int main (int argc, char *argv[],char *envp[])
{
    timeval *t;
    int loop = 0;
    int n = 0;

    printf("gettimeofday execution time test Optimization Level None(-O0) testno:0001\n");

    if (argc == 2){
        loop = atoi(argv[1]);
    }

    t = new timeval[loop+2];

    gettimeofday(t+loop, NULL);

    for (int i = 0; i < loop; i++) {
        gettimeofday(t+i, NULL);
    }
    gettimeofday(t+loop+1, NULL);

    printf(" loop=%1d\n",loop);
    printf(" n=%1d\n",n);
    printf("%ld(S)%06ld(usec) loop begin\n", (long)t[loop].tv_sec, (long)t[loop].tv_usec);
    printf("%ld(S)%06ld(usec) loop end\n", (long)t[loop+1].tv_sec, (long)t[loop+1].tv_usec);
    printf("%06ld(usec)/%1d loop\n", (long)t[loop+1].tv_usec - (long)t[loop].tv_usec,loop);
    if (loop > 0){
        printf("%06ld(usec)/one loop\n",((long)t[loop+1].tv_usec - (long)t[loop].tv_usec)/loop);
    }
    return 0;
}


■実施結果
■結果 10000回ループ
gettimeofday execution time test Optimization Level None(-O0) testno:0001
 loop=10000
 n=0
1449026262(S)032661(usec) loop begin
1449026262(S)051902(usec) loop end
019241(usec)/10000 loop
000001(usec)/one loop


■結果 0回ループ
gettimeofday execution time test Optimization Level None(-O0) testno:0001
 loop=0
 n=0
1449026749(S)405494(usec) loop begin
1449026749(S)405498(usec) loop end
000004(usec)/0 loop


■環境
Raspberry Pi B Rev2 (china)

Linux raspberrypi 4.1.13+ #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015 armv6l GNU/Linux


Eclipse IDE for C/C++ Developers
Version: Mars.1 Release (4.5.1)
Build id: 20150924-1200


 <?xml version="1.0"?>
-<Toolchain xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ToolchainName>Raspberry PI</ToolchainName>
      <ToolchainType>Linux</ToolchainType>
      <PathDetectionKeyStrip>0</PathDetectionKeyStrip>
      <GNUTargetID>arm-linux-gnueabihf</GNUTargetID>
      <ToolchainID>com.visualgdb.raspberry_pi</ToolchainID>
      <BinaryDirectory>bin</BinaryDirectory>
      <Prefix>arm-linux-gnueabihf-</Prefix>
      <Make>make.exe</Make>
      <BSPIndexUrlFormat>http://visualgdb.com/hwsupport/BSP/?autofetch=1&target=arm-linux-gnueabihf&filter={0}</BSPIndexUrlFormat>
      <IsCygwinBased>false</IsCygwinBased>
      <GCCVersion>4.9.2</GCCVersion>
      <GDBVersion>7.10</GDBVersion>
      <Revision>1</Revision>
      <RelativeSysrootPath>arm-linux-gnueabihf\sysroot</RelativeSysrootPath>
 </Toolchain>



※2015/12 実施


Raspberry Pi GPIO出力ポートの時間測定 C++ (備忘録)

Raspberry Pi GPIO出力ポートのon/off制御で制御可能な最小時間についての方式比較です。

要点と結果


■テストの要点
1.valueファイルへの1,0書き込みによる方式
2.書き込み毎にファイルをcloseしない方式とcloseする方式の比較

■結果
一つ目のパルスがcloseしないで1/0を連続的に書き込む方式
二つ目のパルスは1または0を書き込む毎にcloseする方式

Raspberry Pi GPIO出力ポートの時間測定 C++ (備忘録)
GPIO27ポートの波形

■注意点
valueファイルをcloseしないで、on/offをさせる場合、
"0"または"1"のみでは正しく動作しない。
必ず、改行が必要。

closeさせる場合は改行の必要はない。

個々の波形


Raspberry Pi GPIO出力ポートの時間測定 C++ (備忘録)
closeしないで1/0を連続的に書き込む方式の場合

Raspberry Pi GPIO出力ポートの時間測定 C++ (備忘録)
1または0を書き込む毎にcloseする方式

Raspberry Pi GPIO出力ポートの時間測定 C++ (備忘録)
一つ目のパルスがcloseしないで1/0を連続的に書き込む方式
二つ目のパルスは1または0を書き込む毎にcloseする方式

テスト方法


■ソース
main.cpp
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include "gpiotest101.h"

using namespace std;

int main(int argc, char *argv[],char *envp[]){
    string outgpiono = "27";
    string ingpiono = "22";

    // 出力用ポート生成
    if (gpiocreate(outgpiono,"out") == 0){
        cout << "outgpiocreate ok" << endl;
    } else {
        cout << "outgpiocreate error" << endl;
        return 1;
    }

    // 入力用ポート生成
    if (gpiocreate(ingpiono,"in") == 0){
        cout << "ingpiocreate ok" << endl;
    } else {
        cout << "ingpiocreate error" << endl;
        return 1;
    }

    //出力ポート動作時間測定(オシロスコープでの観測を目的としている)
    outportcycletest01(outgpiono,atoi(argv[1]));
    outportcycletest02(outgpiono,atoi(argv[1]));

    //出力ポート破棄
    if (gpiodestroy(outgpiono) == 0) {
        cout << "outgpiodestroy ok" << endl;
    } else {
        cout << "outgpiodestroy error" << endl;
        return 1;
    }

    //入力ポート破棄
    if (gpiodestroy(ingpiono) == 0) {
        cout << "ingpiodestroy ok" << endl;
    } else {
        cout << "ingpiodestroy error" << endl;
        return 1;
    }

    return 0;
}


gpiotest101.h
#include <string>
using namespace std;

#define GPIOPATH "/sys/class/gpio"
#define GPIOPORT GPIOPATH "/gpio%s"

int gpiooutput(string outfilename,string val);
int gpiocreate(string gpiono,string direction);
int gpiodestroy(string gpiono);
void outportcycletest01(string gpiono,int actuatingcycle);
void outportcycletest02(string gpiono,int actuatingcycle);


gpiocreate.cpp
#include <sys/stat.h>
#include <iostream>
#include <fstream>
#include <string>
#include "gpiotest101.h"

using namespace std;

int gpiocreate(string gpiono,string direction){

    char c[256] = GPIOPATH "/export";
    if ((gpiooutput(c,gpiono)) == 0){
        cout << "export" << gpiono << " OK" << endl;
    } else {
        cout << "export" << gpiono << " error" << endl;
        return 1;
    }

    sprintf(c,GPIOPORT "/direction",gpiono.c_str());
    if (chmod(c,0x3ff) == 0) {
        cout << string(c) + " chmod ok" << endl;
    } else {
        cout << string(c) + " chmod error" << endl;
        return 1;
    }
    if ((gpiooutput(c,direction)) == 0) {
        cout << string(c) + " direction set ok" << endl;
    } else {
        cout << string(c) + " direction error ok" << endl;
    }

    sprintf(c,GPIOPORT "/value",gpiono.c_str());
    if (chmod(c,0x3ff) == 0) {
        cout << string(c) + " chmod ok" << endl;
    } else {
        cout << string(c) + " chmod error" << endl;
        return 1;
    }

    sprintf(c,GPIOPORT "/edge",gpiono.c_str());
    if (chmod(c,0x3ff) == 0) {
        cout << string(c) + " chmod ok" << endl;
    } else {
        cout << string(c) + " chmod error" << endl;
        return 1;
    }

    return 0;
}


gpiodestroy.cpp
#include <sys/stat.h>
#include <iostream>
#include <fstream>
#include <string>
#include "gpiotest101.h"

using namespace std;

int gpiodestroy(string gpiono){

    char c[256] = GPIOPATH "/unexport";
    if ((gpiooutput(c,gpiono)) == 0){
        cout << "unexport" << gpiono << " OK" << endl;
    } else {
        cout << "unexport" << gpiono << " error" << endl;
        return 1;
    }
    return 0;
}


gpiooutput.cpp
//#include <sys/stat.h>

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int gpiooutput(string outfilename,string val){
    ofstream fout;

    fout.open(outfilename.c_str(), ios::out);
    if (!fout) {
        cout << outfilename + " Open error." << endl;
        return 1;
    }

    fout << val;
    if (!fout) {
        cout << outfilename + " write error." << endl;
        fout.close();
        return 1;
    }

    fout.close();
    return 0;
}


outportcycletest01.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "gpiotest101.h"
using namespace std;

void outportcycletest01(string gpiono,int actuatingcycle){
    ofstream fout;
    char outfilename[256];

    // value file open
    sprintf(outfilename,GPIOPORT "/value",gpiono.c_str()); //file path <- gpio no
    fout.open(outfilename, ios::out);
    if (!fout) {
        cout << string(outfilename) + " Open error." << endl;
        return;
    }

    // port on/off
    for (int n = 0;n < actuatingcycle;n++){
        fout << 1 << endl;
        if (!fout) {
            cout << string(outfilename) + " write(1) error." << endl;
            fout.close();
            return;
        }

        fout << 0 << endl;
        if (!fout) {
            cout << string(outfilename) + " write(0) error." << endl;
            fout.close();
            return;
        }
    }

    fout.close();
    return;
}


outportcycletest02.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "gpiotest101.h"
using namespace std;

void outportcycletest02(string gpiono,int actuatingcycle){
    ofstream fout;
    char outfilename[256];

    sprintf(outfilename,GPIOPORT "/value",gpiono.c_str());

     // port on/off
    for (int n = 0;n < actuatingcycle;n++){
        if (gpiooutput(outfilename,"1") != 0) {
            cout << string(outfilename) + " write(1) error." << endl;
        }
        if (gpiooutput(outfilename,"0") != 0) {
            cout << string(outfilename) + " write(0) error." << endl;
        }
     }

    return;
}



■環境
Raspberry Pi B Rev2 (china)

Linux raspberrypi 4.1.13+ #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015 armv6l GNU/Linux


Eclipse IDE for C/C++ Developers
Version: Mars.1 Release (4.5.1)
Build id: 20150924-1200


 <?xml version="1.0"?>
-<Toolchain xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ToolchainName>Raspberry PI</ToolchainName>
      <ToolchainType>Linux</ToolchainType>
      <PathDetectionKeyStrip>0</PathDetectionKeyStrip>
      <GNUTargetID>arm-linux-gnueabihf</GNUTargetID>
      <ToolchainID>com.visualgdb.raspberry_pi</ToolchainID>
      <BinaryDirectory>bin</BinaryDirectory>
      <Prefix>arm-linux-gnueabihf-</Prefix>
      <Make>make.exe</Make>
      <BSPIndexUrlFormat>http://visualgdb.com/hwsupport/BSP/?autofetch=1&target=arm-linux-gnueabihf&filter={0}</BSPIndexUrlFormat>
      <IsCygwinBased>false</IsCygwinBased>
      <GCCVersion>4.9.2</GCCVersion>
      <GDBVersion>7.10</GDBVersion>
      <Revision>1</Revision>
      <RelativeSysrootPath>arm-linux-gnueabihf\sysroot</RelativeSysrootPath>
 </Toolchain>

Raspberry Pi C++ GPIOのメモリマップ方式のテスト(備忘録)

Raspberry Pi GPIO出力ポートのメモリマップ方式によるテスト。

テストの要点


1.Raspberry PiのGPIOレジスタ構造をC++のstruct,ビットフィールドでモデル化する
2.メモリマップ方式での出力ポートの動作時間の測定

今回は、出力ポートのみ動作確認をしています。
入力ポートや他の機能について確認していません。

結果


■モデル化
(1)ビットフィールド
 1.GPIOレジスタのGPFSELnを3bitのビットフィールドとして扱う部分は成功していると思わる。
 2.GPCLRnを1bitのビットフィールドとして扱うと、代入時(書き込み)時にRaspbianがフリーズする。(※1)
 3.GPSELnを1bitのビットフィールドとして扱う部分については、一見正常に動作しているが、on/offの制御方式がGPCLRnと同じ為、フリーズする可能性がある。

(2)32bitフィールド
 1.GPSELn及びGPCLRnは32bitフィールドとして操作する。(※2)

(3)欠点
 1.利用するポートの割当がソースレベルで固定化される事である。実行時に任意に変えられない。

■動作時間
(1)出力ポートのon/off動作時間
 1.約21.8nsでon/off可能


■参考資料
 「BROACOM BCM2835 ARM Peripherals

■注
※1 ビットフィールド操作でのフリーズ
(1)推定理由

GPIOのoutput pinのデータをクリアするGPCLRnレジスタをビットフィールドでセットするとRaspberry Piがフリーズする。
C++のビットフィールドのbit操作は、データ操作単位である32bitを一旦読み込んで、目的のbitと目的外のビットをマージして再書込していると思われる。
「BROACOM BCM2835 ARM Peripherals」によるとGPCLRnレジスタはWriteのみ許さている(Page90)。
ただし、Page95のGPCLRnの詳細説明ではR/Wである。許されているのと可能なのとは異なる。
C++のmmapで得た仮想メモリからのGPCLRnの読み込みは0/1混在状態である。
Raspberry Piのシステム上、ユーザがOUTポートとして割当可能なポート以外のデータも帰ってくる。
この値がWriteのみ許さているポートなのでデタラメかもしれないし、正しい値なのかもしれない。
Page90に明記されているWriteの意味は「リードしてマージする必要はありませんよ」かもしれない。
しかし、本当のところは「Pin Set & Clear Regs」に対して、「0は状態を更新しない、1はSetする」という、回路設計上の都合を言い換えただけかもしれない。

したがって、保証されていない出力ポートを読んだ値で、目的bit以外を再書込すると"1"にセットされたレジスタが何らかの動作をし、
結果的にシステムの不具合を引き起こしていると思われる。

そもそも、Outputの状態を1bitで制御せずに、SETとCLRを別に設けている所を十分汲む必要がある。


(2)対策

1.必要に応じて、ビットフィールドを使用しない
GPSETn,GPCLRnのように、「x = No effect」との説明があるレジスタはビットフィールドを使用せずレジスタの一括ライトを行う。
「BROACOM BCM2835 ARM Peripherals」の説明は明らかにそのように指示している。

※2 ただし、あくまでOS上のアプリでの制御のため、割り込み等により動作時間の安定性は望めない。


動作時間



後述するテスト用プログラムでテストした時のGPIO27ポートの波形です。
動作が早いために、ソフトにてパルス幅を10倍に引き伸ばした時の波形です。したがって、最小の制御時間はこの結果の1/10となります。
Raspberry Pi C++ GPIOのメモリマップ方式のテスト(備忘録)
./test03 3 10 で実行した時の波形(したがって、 218ns÷10=21.8ns が制御可能な最小パルス幅の単位となります)


GPIOファイルで制御する場合の最小幅は「Raspberry Pi GPIO出力ポートの時間測定 C++ (備忘録)」から
Raspberry Pi GPIO出力ポートの時間測定 C++ (備忘録)
11.6usとなります。
したがって GPIOファイル制御の方が11.6us/21.8ns=532倍遅い事になります。


テスト用プログラム ソース



#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

typedef struct gpregisters GPREGISTERS;  //例 static volatile GPREGISTERS *sel;
typedef unsigned GPIODIRECTION;

//GPIO registers 定数
#define GPIOINPUT 0x0
#define GPIOOUTPUT 0x1

//    gpio register アドレス情報
#define GPIO_BASE    (0x20000000 + 0x200000)
#define BLOCK_SIZE  4096

//GPIO registers 設定用
#define GPSETN(asel,no) asel->setn[no/31] = 0x1 << (no%31)    //GPSETn output ON 設定用
#define GPCLRN(asel,no) asel->clrn[no/31] = 0x1 << (no%31)  //GPSETn output OFF 設定用
#define GPFSELOUTPUT(asel,no) asel->fsel##no = GPIOOUTPUT    //GPFSELn OUTPUTモードに設定

// GPIO(General Purpose I/O)仮想アドレス構造定義
struct gpregisters {
    unsigned fsel0:3;
    unsigned fsel1:3;
    unsigned fsel2:3;
    unsigned fsel3:3;
    unsigned fsel4:3;
    unsigned fsel5:3;
    unsigned fsel6:3;
    unsigned fsel7:3;
    unsigned fsel8:3;
    unsigned fsel9:3;
    unsigned :0;        //これがなくても次のbitはバウンダリ調整されるが、解りやすさと念のために記述
    unsigned fsel10:3;
    unsigned fsel11:3;
    unsigned fsel12:3;
    unsigned fsel13:3;
    unsigned fsel14:3;
    unsigned fsel15:3;
    unsigned fsel16:3;
    unsigned fsel17:3;
    unsigned fsel18:3;
    unsigned fsel19:3;
    unsigned :0;        //これがなくても次のbitはバウンダリ調整されるが、解りやすさと念のために記述
    unsigned fsel20:3;
    unsigned fsel21:3;
    unsigned fsel22:3;
    unsigned fsel23:3;
    unsigned fsel24:3;
    unsigned fsel25:3;
    unsigned fsel26:3;
    unsigned fsel27:3;
    unsigned fsel28:3;
    unsigned fsel29:3;
    unsigned :0;        //これがなくても次のbitはバウンダリ調整されるが、解りやすさと念のために記述
    unsigned fsel30:3;
    unsigned fsel31:3;
    unsigned fsel32:3;
    unsigned fsel33:3;
    unsigned fsel34:3;
    unsigned fsel35:3;
    unsigned fsel36:3;
    unsigned fsel37:3;
    unsigned fsel38:3;
    unsigned fsel39:3;
    unsigned :0;
    unsigned fsel40:3;
    unsigned fsel41:3;
    unsigned fsel42:3;
    unsigned fsel43:3;
    unsigned fsel44:3;
    unsigned fsel45:3;
    unsigned fsel46:3;
    unsigned fsel47:3;
    unsigned fsel48:3;
    unsigned fsel49:3;
    unsigned :0;
    unsigned fsel50:3;
    unsigned fsel51:3;
    unsigned fsel52:3;
    unsigned fsel53:3;
    unsigned :0;
    unsigned reserved1;
    union{
        unsigned setn[2];        //設定にはこちらを使用すること
        struct{
            unsigned set0:1;    //setnは設定には使用してはいけない。
            unsigned set1:1;
            unsigned set2:1;
            unsigned set3:1;
            unsigned set4:1;
            unsigned set5:1;
            unsigned set6:1;
            unsigned set7:1;
            unsigned set8:1;
            unsigned set9:1;
            unsigned set10:1;
            unsigned set11:1;
            unsigned set12:1;
            unsigned set13:1;
            unsigned set14:1;
            unsigned set15:1;
            unsigned set16:1;
            unsigned set17:1;
            unsigned set18:1;
            unsigned set19:1;
            unsigned set20:1;
            unsigned set21:1;
            unsigned set22:1;
            unsigned set23:1;
            unsigned set24:1;
            unsigned set25:1;
            unsigned set26:1;
            unsigned set27:1;
            unsigned set28:1;
            unsigned set29:1;
            unsigned set30:1;
            unsigned set31:1;
            unsigned :0;
            unsigned set32:1;
            unsigned set33:1;
            unsigned set34:1;
            unsigned set35:1;
            unsigned set36:1;
            unsigned set37:1;
            unsigned set38:1;
            unsigned set39:1;
            unsigned set40:1;
            unsigned set41:1;
            unsigned set42:1;
            unsigned set43:1;
            unsigned set44:1;
            unsigned set45:1;
            unsigned set46:1;
            unsigned set47:1;
            unsigned set48:1;
            unsigned set49:1;
            unsigned set50:1;
            unsigned set51:1;
            unsigned set52:1;
            unsigned set53:1;
        };
    };
    unsigned :0;
    unsigned reserved2;

    union{
        unsigned clrn[2];            //設定にはこちらを使用するとこ
        struct{
            unsigned clr0:1;        //clrnは設定には使用してはいけない。
            unsigned clr1:1;
            unsigned clr2:1;
            unsigned clr3:1;
            unsigned clr4:1;
            unsigned clr5:1;
            unsigned clr6:1;
            unsigned clr7:1;
            unsigned clr8:1;
            unsigned clr9:1;
            unsigned clr10:1;
            unsigned clr11:1;
            unsigned clr12:1;
            unsigned clr13:1;
            unsigned clr14:1;
            unsigned clr15:1;
            unsigned clr16:1;
            unsigned clr17:1;
            unsigned clr18:1;
            unsigned clr19:1;
            unsigned clr20:1;
            unsigned clr21:1;
            unsigned clr22:1;
            unsigned clr23:1;
            unsigned clr24:1;
            unsigned clr25:1;
            unsigned clr26:1;
            unsigned clr27:1;
            unsigned clr28:1;
            unsigned clr29:1;
            unsigned clr30:1;
            unsigned clr31:1;
            unsigned :0;
            unsigned clr32:1;
            unsigned clr33:1;
            unsigned clr34:1;
            unsigned clr35:1;
            unsigned clr36:1;
            unsigned clr37:1;
            unsigned clr38:1;
            unsigned clr39:1;
            unsigned clr40:1;
            unsigned clr41:1;
            unsigned clr42:1;
            unsigned clr43:1;
            unsigned clr44:1;
            unsigned clr45:1;
            unsigned clr46:1;
            unsigned clr47:1;
            unsigned clr48:1;
            unsigned clr49:1;
            unsigned clr50:1;
            unsigned clr51:1;
            unsigned clr52:1;
            unsigned clr53:1;
        };
    };

    unsigned :0;
    unsigned reserved3;
    unsigned lev0:1;
    unsigned lev1:1;
    unsigned lev2:1;
    unsigned lev3:1;
    unsigned lev4:1;
    unsigned lev5:1;
    unsigned lev6:1;
    unsigned lev7:1;
    unsigned lev8:1;
    unsigned lev9:1;
    unsigned lev10:1;
    unsigned lev11:1;
    unsigned lev12:1;
    unsigned lev13:1;
    unsigned lev14:1;
    unsigned lev15:1;
    unsigned lev16:1;
    unsigned lev17:1;
    unsigned lev18:1;
    unsigned lev19:1;
    unsigned lev20:1;
    unsigned lev21:1;
    unsigned lev22:1;
    unsigned lev23:1;
    unsigned lev24:1;
    unsigned lev25:1;
    unsigned lev26:1;
    unsigned lev27:1;
    unsigned lev28:1;
    unsigned lev29:1;
    unsigned lev30:1;
    unsigned :0;
    unsigned lev31:1;
    unsigned lev32:1;
    unsigned lev33:1;
    unsigned lev34:1;
    unsigned lev35:1;
    unsigned lev36:1;
    unsigned lev37:1;
    unsigned lev38:1;
    unsigned lev39:1;
    unsigned lev40:1;
    unsigned lev41:1;
    unsigned lev42:1;
    unsigned lev43:1;
    unsigned lev44:1;
    unsigned lev45:1;
    unsigned lev46:1;
    unsigned lev47:1;
    unsigned lev48:1;
    unsigned lev49:1;
    unsigned lev50:1;
    unsigned lev51:1;
    unsigned lev52:1;
    unsigned lev53:1;
    unsigned :0;
    unsigned reserved4;
    unsigned eds0:1;
    unsigned eds1:1;
    unsigned eds2:1;
    unsigned eds3:1;
    unsigned eds4:1;
    unsigned eds5:1;
    unsigned eds6:1;
    unsigned eds7:1;
    unsigned eds8:1;
    unsigned eds9:1;
    unsigned eds10:1;
    unsigned eds11:1;
    unsigned eds12:1;
    unsigned eds13:1;
    unsigned eds14:1;
    unsigned eds15:1;
    unsigned eds16:1;
    unsigned eds17:1;
    unsigned eds18:1;
    unsigned eds19:1;
    unsigned eds20:1;
    unsigned eds21:1;
    unsigned eds22:1;
    unsigned eds23:1;
    unsigned eds24:1;
    unsigned eds25:1;
    unsigned eds26:1;
    unsigned eds27:1;
    unsigned eds28:1;
    unsigned eds29:1;
    unsigned eds30:1;
    unsigned :0;
    unsigned eds31:1;
    unsigned eds32:1;
    unsigned eds33:1;
    unsigned eds34:1;
    unsigned eds35:1;
    unsigned eds36:1;
    unsigned eds37:1;
    unsigned eds38:1;
    unsigned eds39:1;
    unsigned eds40:1;
    unsigned eds41:1;
    unsigned eds42:1;
    unsigned eds43:1;
    unsigned eds44:1;
    unsigned eds45:1;
    unsigned eds46:1;
    unsigned eds47:1;
    unsigned eds48:1;
    unsigned eds49:1;
    unsigned eds50:1;
    unsigned eds51:1;
    unsigned eds52:1;
    unsigned eds53:1;
    unsigned :0;
    unsigned reserved5;
    unsigned ren0:1;
    unsigned ren1:1;
    unsigned ren2:1;
    unsigned ren3:1;
    unsigned ren4:1;
    unsigned ren5:1;
    unsigned ren6:1;
    unsigned ren7:1;
    unsigned ren8:1;
    unsigned ren9:1;
    unsigned ren10:1;
    unsigned ren11:1;
    unsigned ren12:1;
    unsigned ren13:1;
    unsigned ren14:1;
    unsigned ren15:1;
    unsigned ren16:1;
    unsigned ren17:1;
    unsigned ren18:1;
    unsigned ren19:1;
    unsigned ren20:1;
    unsigned ren21:1;
    unsigned ren22:1;
    unsigned ren23:1;
    unsigned ren24:1;
    unsigned ren25:1;
    unsigned ren26:1;
    unsigned ren27:1;
    unsigned ren28:1;
    unsigned ren29:1;
    unsigned ren30:1;
    unsigned :0;
    unsigned ren31:1;
    unsigned ren32:1;
    unsigned ren33:1;
    unsigned ren34:1;
    unsigned ren35:1;
    unsigned ren36:1;
    unsigned ren37:1;
    unsigned ren38:1;
    unsigned ren39:1;
    unsigned ren40:1;
    unsigned ren41:1;
    unsigned ren42:1;
    unsigned ren43:1;
    unsigned ren44:1;
    unsigned ren45:1;
    unsigned ren46:1;
    unsigned ren47:1;
    unsigned ren48:1;
    unsigned ren49:1;
    unsigned ren50:1;
    unsigned ren51:1;
    unsigned ren52:1;
    unsigned ren53:1;
    unsigned :0;
    unsigned reserved6;
    unsigned fen0:1;
    unsigned fen1:1;
    unsigned fen2:1;
    unsigned fen3:1;
    unsigned fen4:1;
    unsigned fen5:1;
    unsigned fen6:1;
    unsigned fen7:1;
    unsigned fen8:1;
    unsigned fen9:1;
    unsigned fen10:1;
    unsigned fen11:1;
    unsigned fen12:1;
    unsigned fen13:1;
    unsigned fen14:1;
    unsigned fen15:1;
    unsigned fen16:1;
    unsigned fen17:1;
    unsigned fen18:1;
    unsigned fen19:1;
    unsigned fen20:1;
    unsigned fen21:1;
    unsigned fen22:1;
    unsigned fen23:1;
    unsigned fen24:1;
    unsigned fen25:1;
    unsigned fen26:1;
    unsigned fen27:1;
    unsigned fen28:1;
    unsigned fen29:1;
    unsigned fen30:1;
    unsigned :0;
    unsigned fen31:1;
    unsigned fen32:1;
    unsigned fen33:1;
    unsigned fen34:1;
    unsigned fen35:1;
    unsigned fen36:1;
    unsigned fen37:1;
    unsigned fen38:1;
    unsigned fen39:1;
    unsigned fen40:1;
    unsigned fen41:1;
    unsigned fen42:1;
    unsigned fen43:1;
    unsigned fen44:1;
    unsigned fen45:1;
    unsigned fen46:1;
    unsigned fen47:1;
    unsigned fen48:1;
    unsigned fen49:1;
    unsigned fen50:1;
    unsigned fen51:1;
    unsigned fen52:1;
    unsigned fen53:1;
    unsigned :0;
    unsigned reserved7;
    unsigned hen0:1;
    unsigned hen1:1;
    unsigned hen2:1;
    unsigned hen3:1;
    unsigned hen4:1;
    unsigned hen5:1;
    unsigned hen6:1;
    unsigned hen7:1;
    unsigned hen8:1;
    unsigned hen9:1;
    unsigned hen10:1;
    unsigned hen11:1;
    unsigned hen12:1;
    unsigned hen13:1;
    unsigned hen14:1;
    unsigned hen15:1;
    unsigned hen16:1;
    unsigned hen17:1;
    unsigned hen18:1;
    unsigned hen19:1;
    unsigned hen20:1;
    unsigned hen21:1;
    unsigned hen22:1;
    unsigned hen23:1;
    unsigned hen24:1;
    unsigned hen25:1;
    unsigned hen26:1;
    unsigned hen27:1;
    unsigned hen28:1;
    unsigned hen29:1;
    unsigned hen30:1;
    unsigned :0;
    unsigned hen31:1;
    unsigned hen32:1;
    unsigned hen33:1;
    unsigned hen34:1;
    unsigned hen35:1;
    unsigned hen36:1;
    unsigned hen37:1;
    unsigned hen38:1;
    unsigned hen39:1;
    unsigned hen40:1;
    unsigned hen41:1;
    unsigned hen42:1;
    unsigned hen43:1;
    unsigned hen44:1;
    unsigned hen45:1;
    unsigned hen46:1;
    unsigned hen47:1;
    unsigned hen48:1;
    unsigned hen49:1;
    unsigned hen50:1;
    unsigned hen51:1;
    unsigned hen52:1;
    unsigned hen53:1;
    unsigned :0;
    unsigned reserved8;
    unsigned len0:1;
    unsigned len1:1;
    unsigned len2:1;
    unsigned len3:1;
    unsigned len4:1;
    unsigned len5:1;
    unsigned len6:1;
    unsigned len7:1;
    unsigned len8:1;
    unsigned len9:1;
    unsigned len10:1;
    unsigned len11:1;
    unsigned len12:1;
    unsigned len13:1;
    unsigned len14:1;
    unsigned len15:1;
    unsigned len16:1;
    unsigned len17:1;
    unsigned len18:1;
    unsigned len19:1;
    unsigned len20:1;
    unsigned len21:1;
    unsigned len22:1;
    unsigned len23:1;
    unsigned len24:1;
    unsigned len25:1;
    unsigned len26:1;
    unsigned len27:1;
    unsigned len28:1;
    unsigned len29:1;
    unsigned len30:1;
    unsigned :0;
    unsigned len31:1;
    unsigned len32:1;
    unsigned len33:1;
    unsigned len34:1;
    unsigned len35:1;
    unsigned len36:1;
    unsigned len37:1;
    unsigned len38:1;
    unsigned len39:1;
    unsigned len40:1;
    unsigned len41:1;
    unsigned len42:1;
    unsigned len43:1;
    unsigned len44:1;
    unsigned len45:1;
    unsigned len46:1;
    unsigned len47:1;
    unsigned len48:1;
    unsigned len49:1;
    unsigned len50:1;
    unsigned len51:1;
    unsigned len52:1;
    unsigned len53:1;
    unsigned :0;
    unsigned reserved9;
    unsigned aren0:1;
    unsigned aren1:1;
    unsigned aren2:1;
    unsigned aren3:1;
    unsigned aren4:1;
    unsigned aren5:1;
    unsigned aren6:1;
    unsigned aren7:1;
    unsigned aren8:1;
    unsigned aren9:1;
    unsigned aren10:1;
    unsigned aren11:1;
    unsigned aren12:1;
    unsigned aren13:1;
    unsigned aren14:1;
    unsigned aren15:1;
    unsigned aren16:1;
    unsigned aren17:1;
    unsigned aren18:1;
    unsigned aren19:1;
    unsigned aren20:1;
    unsigned aren21:1;
    unsigned aren22:1;
    unsigned aren23:1;
    unsigned aren24:1;
    unsigned aren25:1;
    unsigned aren26:1;
    unsigned aren27:1;
    unsigned aren28:1;
    unsigned aren29:1;
    unsigned aren30:1;
    unsigned :0;
    unsigned aren31:1;
    unsigned aren32:1;
    unsigned aren33:1;
    unsigned aren34:1;
    unsigned aren35:1;
    unsigned aren36:1;
    unsigned aren37:1;
    unsigned aren38:1;
    unsigned aren39:1;
    unsigned aren40:1;
    unsigned aren41:1;
    unsigned aren42:1;
    unsigned aren43:1;
    unsigned aren44:1;
    unsigned aren45:1;
    unsigned aren46:1;
    unsigned aren47:1;
    unsigned aren48:1;
    unsigned aren49:1;
    unsigned aren50:1;
    unsigned aren51:1;
    unsigned aren52:1;
    unsigned aren53:1;
    unsigned :0;
    unsigned reserved10;
    unsigned afen0:1;
    unsigned afen1:1;
    unsigned afen2:1;
    unsigned afen3:1;
    unsigned afen4:1;
    unsigned afen5:1;
    unsigned afen6:1;
    unsigned afen7:1;
    unsigned afen8:1;
    unsigned afen9:1;
    unsigned afen10:1;
    unsigned afen11:1;
    unsigned afen12:1;
    unsigned afen13:1;
    unsigned afen14:1;
    unsigned afen15:1;
    unsigned afen16:1;
    unsigned afen17:1;
    unsigned afen18:1;
    unsigned afen19:1;
    unsigned afen20:1;
    unsigned afen21:1;
    unsigned afen22:1;
    unsigned afen23:1;
    unsigned afen24:1;
    unsigned afen25:1;
    unsigned afen26:1;
    unsigned afen27:1;
    unsigned afen28:1;
    unsigned afen29:1;
    unsigned afen30:1;
    unsigned :0;
    unsigned afen31:1;
    unsigned afen32:1;
    unsigned afen33:1;
    unsigned afen34:1;
    unsigned afen35:1;
    unsigned afen36:1;
    unsigned afen37:1;
    unsigned afen38:1;
    unsigned afen39:1;
    unsigned afen40:1;
    unsigned afen41:1;
    unsigned afen42:1;
    unsigned afen43:1;
    unsigned afen44:1;
    unsigned afen45:1;
    unsigned afen46:1;
    unsigned afen47:1;
    unsigned afen48:1;
    unsigned afen49:1;
    unsigned afen50:1;
    unsigned afen51:1;
    unsigned afen52:1;
    unsigned afen53:1;
    unsigned :0;
    unsigned reserved11;
    unsigned pud:2;
    unsigned :0;
    unsigned pudclk0:1;
    unsigned pudclk1:1;
    unsigned pudclk2:1;
    unsigned pudclk3:1;
    unsigned pudclk4:1;
    unsigned pudclk5:1;
    unsigned pudclk6:1;
    unsigned pudclk7:1;
    unsigned pudclk8:1;
    unsigned pudclk9:1;
    unsigned pudclk10:1;
    unsigned pudclk11:1;
    unsigned pudclk12:1;
    unsigned pudclk13:1;
    unsigned pudclk14:1;
    unsigned pudclk15:1;
    unsigned pudclk16:1;
    unsigned pudclk17:1;
    unsigned pudclk18:1;
    unsigned pudclk19:1;
    unsigned pudclk20:1;
    unsigned pudclk21:1;
    unsigned pudclk22:1;
    unsigned pudclk23:1;
    unsigned pudclk24:1;
    unsigned pudclk25:1;
    unsigned pudclk26:1;
    unsigned pudclk27:1;
    unsigned pudclk28:1;
    unsigned pudclk29:1;
    unsigned pudclk30:1;
    unsigned :0;
    unsigned pudclk31:1;
    unsigned pudclk32:1;
    unsigned pudclk33:1;
    unsigned pudclk34:1;
    unsigned pudclk35:1;
    unsigned pudclk36:1;
    unsigned pudclk37:1;
    unsigned pudclk38:1;
    unsigned pudclk39:1;
    unsigned pudclk40:1;
    unsigned pudclk41:1;
    unsigned pudclk42:1;
    unsigned pudclk43:1;
    unsigned pudclk44:1;
    unsigned pudclk45:1;
    unsigned pudclk46:1;
    unsigned pudclk47:1;
    unsigned pudclk48:1;
    unsigned pudclk49:1;
    unsigned pudclk50:1;
    unsigned pudclk51:1;
    unsigned pudclk52:1;
    unsigned pudclk53:1;
    unsigned :0;
    unsigned reserved12;
    unsigned test:4;
};

GPREGISTERS* get_gpio_map(){
    int fd;
    void *gpio_map;

    //仮想メモリアドレスの取得
    fd = open("/dev/mem", O_RDWR | O_SYNC);
    if (fd == -1) {
            return (GPREGISTERS*)-1;
    }

    gpio_map = mmap(NULL, BLOCK_SIZE,
                PROT_READ | PROT_WRITE, MAP_SHARED,
                fd, GPIO_BASE );

    if ((int)gpio_map == -1) {
            return (GPREGISTERS*)-1;
    }
    close(fd);

    return (GPREGISTERS*)gpio_map;
}

static volatile GPREGISTERS *sel;

int main(int argc, char *argv[], char *envp[]) {

    long loop = 1;
    long pulse_width = 1;

    if (argc == 3) {
        loop = atoi(argv[1]);
        pulse_width = atoi(argv[2]);
    }

    sel = get_gpio_map();
    if ((int)sel == -1) {
        return 1;
    }

    GPFSELOUTPUT(sel,27); //sel->fsel27 = 0x1;

    printf("sel:%08x\n",(unsigned)sel);


    for (int i1 = 0;i1 < loop;i1++){
        for (int i2 = 0;i2 < pulse_width;i2++){
            GPSETN(sel,27); //sel->setn[0] = 0x1 << 27;
        }
        for (int i2 = 0;i2 < pulse_width;i2++){
            GPCLRN(sel,27);    //sel->clrn[0] = 0x1 << 27;
        }
    }

    printf("end.\n");

    return 0;
}



環境


Raspberry Pi B Rev2 (china)

Linux raspberrypi 4.1.13+ #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015 armv6l GNU/Linux


Eclipse IDE for C/C++ Developers
Version: Mars.1 Release (4.5.1)
Build id: 20150924-1200


 <?xml version="1.0"?>
-<Toolchain xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ToolchainName>Raspberry PI</ToolchainName>
      <ToolchainType>Linux</ToolchainType>
      <PathDetectionKeyStrip>0</PathDetectionKeyStrip>
      <GNUTargetID>arm-linux-gnueabihf</GNUTargetID>
      <ToolchainID>com.visualgdb.raspberry_pi</ToolchainID>
      <BinaryDirectory>bin</BinaryDirectory>
      <Prefix>arm-linux-gnueabihf-</Prefix>
      <Make>make.exe</Make>
      <BSPIndexUrlFormat>http://visualgdb.com/hwsupport/BSP/?autofetch=1&target=arm-linux-gnueabihf&filter={0}</BSPIndexUrlFormat>
      <IsCygwinBased>false</IsCygwinBased>
      <GCCVersion>4.9.2</GCCVersion>
      <GDBVersion>7.10</GDBVersion>
      <Revision>1</Revision>
      <RelativeSysrootPath>arm-linux-gnueabihf\sysroot</RelativeSysrootPath>
 </Toolchain>

Raspberry Pi C++ GPIO読み取り方式比較(メモリマップ式)(備忘録)

Raspberry Pi GPIO入力ポートの読み取り三方式の動作時間比較。

テストの概要


1.GPIO入出力はメモリマップ方式で行う
2.入力ポートの読み取りはレジスタ一括方式(二種類)とビットフィールド方式の比較を行う。

■読み込み方式
(1)レジスタ一括方式(都度bitマスク生成方式)
  (0x1 << (22%31)) & (sel->levn[22/31]))
(2)レジスタ一括方式(事前bitマスク生成方式)
  levn_mask & (sel->levn[22/31])
(3)ビットフィールド方式
  sel->lev22


■測定方法
1.GPIO27ポートを出力ポートとしてon/offし、それをオシロスコープで観測する。
2.GPIO27ポートをon → 「入力ポートの読み込み」 → 出力ポートoff。
3.項番2の方法で、「入力ポート読み込みなし」及び「■読み込み方式」三種を連続して実行し、
4.オシロスコープで観測する。

■参考資料
 「BROACOM BCM2835 ARM Peripherals


結果



Raspberry Pi C++ GPIO読み取り方式比較(メモリマップ式)(備忘録)
./testreg07 100000000 1 1000 で実行

■パルス順に
1.入力読み込みなし
2.レジスタ一括方式(都度bitマスク生成方式)
3.レジスタ一括方式(事前bitマスク生成方式)
4.ビットフィールド方式

入力ポートの読み込み速度が最も早いのは
 1.「レジスタ一括方式(事前bitマスク生成方式)」
 2.「ビットフィールド方式」
 3.「.レジスタ一括方式(都度bitマスク生成方式)」


テスト用プログラム ソース



■main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include "nrpgpio01.h"

static volatile GPREGISTERS *sel;

int main(int argc, char *argv[], char *envp[]) {

    int n;
    int x;
    int i1;
    unsigned levn_mask;
    struct timespec req;
    req.tv_sec = 0;
    req.tv_nsec = 0;

    long loop = 1;
    long pulse_width = 1;

    if (argc == 4) {
        loop = atoi(argv[1]);
        pulse_width = atoi(argv[2]);
        req.tv_sec  = 0;
        req.tv_nsec = atoi(argv[3]); // (ns)
    }

    sel = get_gpio_map();
    if ((int)sel == -1) {
        return 1;
    }

    GPFSELOUTPUT(sel,27);     //sel->fsel27 = GPIOOUTPUT;
    GPFSELINPUT(sel,22);    //sel->fsel22 = 0x0;

    printf("sel:%08x\n",(unsigned)sel);

    levn_mask = 0x1 << (22%31);
    printf("levn_mask:%08x\n",levn_mask);

    GPCLRN(sel,27);
    for (i1 = 0;i1 < loop;i1++){

        //基本パルス幅
        for (n = 0;n < pulse_width;n++){
            GPSETN(sel,27);
        }
        for (n = 0;n < pulse_width;n++){
            GPCLRN(sel,27);
        }

        //GPLEVN (0x1 << (22%31)) & (sel->levn[22/31])) 方式のパルス幅
        for (n = 0;n < pulse_width;n++){
            GPSETN(sel,27);
        }
        x = GPLEVN(sel,22);
//        printf("GPLEVN   :%08x\n",x);
        for (n = 0;n < pulse_width;n++){
            GPCLRN(sel,27);
        }

        //levn_mask & (sel->levn[22/31])) 方式のパルス幅  (都度シフトの回避)
        for (n = 0;n < pulse_width;n++){
            GPSETN(sel,27);
        }
        x = levn_mask & (sel->levn[22/31]);
//        printf("levn_mask :%08x\n",x);
        for (n = 0;n < pulse_width;n++){
            GPCLRN(sel,27);
        }


        //GPLEVNbm sel->lev22 方式のパルス幅
        for (n = 0;n < pulse_width;n++){
            GPSETN(sel,27);
        }
        x = GPLEVNbm(sel,22);
//        printf("GPLEVNbm  :%08x\n",x);
        for (n = 0;n < pulse_width;n++){
            GPCLRN(sel,27);
        }

         nanosleep(&req, NULL);
    }

    printf("end.\n");

    return 0;
}


■nrpgpio01.h
typedef struct gpregisters GPREGISTERS;  //例 static volatile GPREGISTERS *sel;
typedef unsigned GPIODIRECTION;

//GPIO registers 定数
#define GPIOINPUT 0x0
#define GPIOOUTPUT 0x1

//    gpio register アドレス情報
#define GPIO_BASE    (0x20000000 + 0x200000)
#define BLOCK_SIZE  4096

//旧バージョン 新たに使用しない事
#define FSEL(asel,no) asel->fsel##no




//GPIO registers 設定用

#define GPFSELINPUT(asel,no) asel->fsel##no = GPIOINPUT        //GPFSELn INPUTモードに設定
#define GPFSELOUTPUT(asel,no) asel->fsel##no = GPIOOUTPUT    //GPFSELn OUTPUTモードに設定

#define GPSETN(asel,no) asel->setn[no/31] = 0x1 << (no%31)    //GPSETn output ON 設定用
#define GPCLRN(asel,no) asel->clrn[no/31] = 0x1 << (no%31)  //GPSETn output OFF 設定用
#define GPLEVNbm(asel,no) asel->lev##no                        //GPLEVn pin level
#define GPLEVN(asel,no) ((0x1 << (no%31)) & (asel->levn[no/31]))

// GPIO(General Purpose I/O)仮想アドレス構造定義
struct gpregisters {
    unsigned fsel0:3;
    unsigned fsel1:3;
    unsigned fsel2:3;
    unsigned fsel3:3;
    unsigned fsel4:3;
    unsigned fsel5:3;
    unsigned fsel6:3;
    unsigned fsel7:3;
    unsigned fsel8:3;
    unsigned fsel9:3;
    unsigned :0;        //これがなくても次のbitはバウンダリ調整されるが、解りやすさと念のために記述
    unsigned fsel10:3;
    unsigned fsel11:3;
    unsigned fsel12:3;
    unsigned fsel13:3;
    unsigned fsel14:3;
    unsigned fsel15:3;
    unsigned fsel16:3;
    unsigned fsel17:3;
    unsigned fsel18:3;
    unsigned fsel19:3;
    unsigned :0;        //これがなくても次のbitはバウンダリ調整されるが、解りやすさと念のために記述
    unsigned fsel20:3;
    unsigned fsel21:3;
    unsigned fsel22:3;
    unsigned fsel23:3;
    unsigned fsel24:3;
    unsigned fsel25:3;
    unsigned fsel26:3;
    unsigned fsel27:3;
    unsigned fsel28:3;
    unsigned fsel29:3;
    unsigned :0;        //これがなくても次のbitはバウンダリ調整されるが、解りやすさと念のために記述
    unsigned fsel30:3;
    unsigned fsel31:3;
    unsigned fsel32:3;
    unsigned fsel33:3;
    unsigned fsel34:3;
    unsigned fsel35:3;
    unsigned fsel36:3;
    unsigned fsel37:3;
    unsigned fsel38:3;
    unsigned fsel39:3;
    unsigned :0;
    unsigned fsel40:3;
    unsigned fsel41:3;
    unsigned fsel42:3;
    unsigned fsel43:3;
    unsigned fsel44:3;
    unsigned fsel45:3;
    unsigned fsel46:3;
    unsigned fsel47:3;
    unsigned fsel48:3;
    unsigned fsel49:3;
    unsigned :0;
    unsigned fsel50:3;
    unsigned fsel51:3;
    unsigned fsel52:3;
    unsigned fsel53:3;
    unsigned :0;
    unsigned reserved1;
    union{
        unsigned setn[2];        //設定にはこちらを使用すること
        struct{
            unsigned set0:1;    //setnは設定には使用してはいけない。
            unsigned set1:1;
            unsigned set2:1;
            unsigned set3:1;
            unsigned set4:1;
            unsigned set5:1;
            unsigned set6:1;
            unsigned set7:1;
            unsigned set8:1;
            unsigned set9:1;
            unsigned set10:1;
            unsigned set11:1;
            unsigned set12:1;
            unsigned set13:1;
            unsigned set14:1;
            unsigned set15:1;
            unsigned set16:1;
            unsigned set17:1;
            unsigned set18:1;
            unsigned set19:1;
            unsigned set20:1;
            unsigned set21:1;
            unsigned set22:1;
            unsigned set23:1;
            unsigned set24:1;
            unsigned set25:1;
            unsigned set26:1;
            unsigned set27:1;
            unsigned set28:1;
            unsigned set29:1;
            unsigned set30:1;
            unsigned set31:1;
            unsigned :0;
            unsigned set32:1;
            unsigned set33:1;
            unsigned set34:1;
            unsigned set35:1;
            unsigned set36:1;
            unsigned set37:1;
            unsigned set38:1;
            unsigned set39:1;
            unsigned set40:1;
            unsigned set41:1;
            unsigned set42:1;
            unsigned set43:1;
            unsigned set44:1;
            unsigned set45:1;
            unsigned set46:1;
            unsigned set47:1;
            unsigned set48:1;
            unsigned set49:1;
            unsigned set50:1;
            unsigned set51:1;
            unsigned set52:1;
            unsigned set53:1;
        };
    };
    unsigned :0;
    unsigned reserved2;

    union{
        unsigned clrn[2];            //設定にはこちらを使用するとこ
        struct{
            unsigned clr0:1;    //clrnは設定には使用してはいけない。
            unsigned clr1:1;
            unsigned clr2:1;
            unsigned clr3:1;
            unsigned clr4:1;
            unsigned clr5:1;
            unsigned clr6:1;
            unsigned clr7:1;
            unsigned clr8:1;
            unsigned clr9:1;
            unsigned clr10:1;
            unsigned clr11:1;
            unsigned clr12:1;
            unsigned clr13:1;
            unsigned clr14:1;
            unsigned clr15:1;
            unsigned clr16:1;
            unsigned clr17:1;
            unsigned clr18:1;
            unsigned clr19:1;
            unsigned clr20:1;
            unsigned clr21:1;
            unsigned clr22:1;
            unsigned clr23:1;
            unsigned clr24:1;
            unsigned clr25:1;
            unsigned clr26:1;
            unsigned clr27:1;
            unsigned clr28:1;
            unsigned clr29:1;
            unsigned clr30:1;
            unsigned clr31:1;
            unsigned :0;
            unsigned clr32:1;
            unsigned clr33:1;
            unsigned clr34:1;
            unsigned clr35:1;
            unsigned clr36:1;
            unsigned clr37:1;
            unsigned clr38:1;
            unsigned clr39:1;
            unsigned clr40:1;
            unsigned clr41:1;
            unsigned clr42:1;
            unsigned clr43:1;
            unsigned clr44:1;
            unsigned clr45:1;
            unsigned clr46:1;
            unsigned clr47:1;
            unsigned clr48:1;
            unsigned clr49:1;
            unsigned clr50:1;
            unsigned clr51:1;
            unsigned clr52:1;
            unsigned clr53:1;
        };
    };

    unsigned :0;
    unsigned reserved3;
    union {
        unsigned levn[2];
        struct{
            unsigned lev0:1;
            unsigned lev1:1;
            unsigned lev2:1;
            unsigned lev3:1;
            unsigned lev4:1;
            unsigned lev5:1;
            unsigned lev6:1;
            unsigned lev7:1;
            unsigned lev8:1;
            unsigned lev9:1;
            unsigned lev10:1;
            unsigned lev11:1;
            unsigned lev12:1;
            unsigned lev13:1;
            unsigned lev14:1;
            unsigned lev15:1;
            unsigned lev16:1;
            unsigned lev17:1;
            unsigned lev18:1;
            unsigned lev19:1;
            unsigned lev20:1;
            unsigned lev21:1;
            unsigned lev22:1;
            unsigned lev23:1;
            unsigned lev24:1;
            unsigned lev25:1;
            unsigned lev26:1;
            unsigned lev27:1;
            unsigned lev28:1;
            unsigned lev29:1;
            unsigned lev30:1;
            unsigned :0;
            unsigned lev31:1;
            unsigned lev32:1;
            unsigned lev33:1;
            unsigned lev34:1;
            unsigned lev35:1;
            unsigned lev36:1;
            unsigned lev37:1;
            unsigned lev38:1;
            unsigned lev39:1;
            unsigned lev40:1;
            unsigned lev41:1;
            unsigned lev42:1;
            unsigned lev43:1;
            unsigned lev44:1;
            unsigned lev45:1;
            unsigned lev46:1;
            unsigned lev47:1;
            unsigned lev48:1;
            unsigned lev49:1;
            unsigned lev50:1;
            unsigned lev51:1;
            unsigned lev52:1;
            unsigned lev53:1;
        };
    };

    unsigned :0;
    unsigned reserved4;
    unsigned eds0:1;
    unsigned eds1:1;
    unsigned eds2:1;
    unsigned eds3:1;
    unsigned eds4:1;
    unsigned eds5:1;
    unsigned eds6:1;
    unsigned eds7:1;
    unsigned eds8:1;
    unsigned eds9:1;
    unsigned eds10:1;
    unsigned eds11:1;
    unsigned eds12:1;
    unsigned eds13:1;
    unsigned eds14:1;
    unsigned eds15:1;
    unsigned eds16:1;
    unsigned eds17:1;
    unsigned eds18:1;
    unsigned eds19:1;
    unsigned eds20:1;
    unsigned eds21:1;
    unsigned eds22:1;
    unsigned eds23:1;
    unsigned eds24:1;
    unsigned eds25:1;
    unsigned eds26:1;
    unsigned eds27:1;
    unsigned eds28:1;
    unsigned eds29:1;
    unsigned eds30:1;
    unsigned :0;
    unsigned eds31:1;
    unsigned eds32:1;
    unsigned eds33:1;
    unsigned eds34:1;
    unsigned eds35:1;
    unsigned eds36:1;
    unsigned eds37:1;
    unsigned eds38:1;
    unsigned eds39:1;
    unsigned eds40:1;
    unsigned eds41:1;
    unsigned eds42:1;
    unsigned eds43:1;
    unsigned eds44:1;
    unsigned eds45:1;
    unsigned eds46:1;
    unsigned eds47:1;
    unsigned eds48:1;
    unsigned eds49:1;
    unsigned eds50:1;
    unsigned eds51:1;
    unsigned eds52:1;
    unsigned eds53:1;
    unsigned :0;
    unsigned reserved5;
    unsigned ren0:1;
    unsigned ren1:1;
    unsigned ren2:1;
    unsigned ren3:1;
    unsigned ren4:1;
    unsigned ren5:1;
    unsigned ren6:1;
    unsigned ren7:1;
    unsigned ren8:1;
    unsigned ren9:1;
    unsigned ren10:1;
    unsigned ren11:1;
    unsigned ren12:1;
    unsigned ren13:1;
    unsigned ren14:1;
    unsigned ren15:1;
    unsigned ren16:1;
    unsigned ren17:1;
    unsigned ren18:1;
    unsigned ren19:1;
    unsigned ren20:1;
    unsigned ren21:1;
    unsigned ren22:1;
    unsigned ren23:1;
    unsigned ren24:1;
    unsigned ren25:1;
    unsigned ren26:1;
    unsigned ren27:1;
    unsigned ren28:1;
    unsigned ren29:1;
    unsigned ren30:1;
    unsigned :0;
    unsigned ren31:1;
    unsigned ren32:1;
    unsigned ren33:1;
    unsigned ren34:1;
    unsigned ren35:1;
    unsigned ren36:1;
    unsigned ren37:1;
    unsigned ren38:1;
    unsigned ren39:1;
    unsigned ren40:1;
    unsigned ren41:1;
    unsigned ren42:1;
    unsigned ren43:1;
    unsigned ren44:1;
    unsigned ren45:1;
    unsigned ren46:1;
    unsigned ren47:1;
    unsigned ren48:1;
    unsigned ren49:1;
    unsigned ren50:1;
    unsigned ren51:1;
    unsigned ren52:1;
    unsigned ren53:1;
    unsigned :0;
    unsigned reserved6;
    unsigned fen0:1;
    unsigned fen1:1;
    unsigned fen2:1;
    unsigned fen3:1;
    unsigned fen4:1;
    unsigned fen5:1;
    unsigned fen6:1;
    unsigned fen7:1;
    unsigned fen8:1;
    unsigned fen9:1;
    unsigned fen10:1;
    unsigned fen11:1;
    unsigned fen12:1;
    unsigned fen13:1;
    unsigned fen14:1;
    unsigned fen15:1;
    unsigned fen16:1;
    unsigned fen17:1;
    unsigned fen18:1;
    unsigned fen19:1;
    unsigned fen20:1;
    unsigned fen21:1;
    unsigned fen22:1;
    unsigned fen23:1;
    unsigned fen24:1;
    unsigned fen25:1;
    unsigned fen26:1;
    unsigned fen27:1;
    unsigned fen28:1;
    unsigned fen29:1;
    unsigned fen30:1;
    unsigned :0;
    unsigned fen31:1;
    unsigned fen32:1;
    unsigned fen33:1;
    unsigned fen34:1;
    unsigned fen35:1;
    unsigned fen36:1;
    unsigned fen37:1;
    unsigned fen38:1;
    unsigned fen39:1;
    unsigned fen40:1;
    unsigned fen41:1;
    unsigned fen42:1;
    unsigned fen43:1;
    unsigned fen44:1;
    unsigned fen45:1;
    unsigned fen46:1;
    unsigned fen47:1;
    unsigned fen48:1;
    unsigned fen49:1;
    unsigned fen50:1;
    unsigned fen51:1;
    unsigned fen52:1;
    unsigned fen53:1;
    unsigned :0;
    unsigned reserved7;
    unsigned hen0:1;
    unsigned hen1:1;
    unsigned hen2:1;
    unsigned hen3:1;
    unsigned hen4:1;
    unsigned hen5:1;
    unsigned hen6:1;
    unsigned hen7:1;
    unsigned hen8:1;
    unsigned hen9:1;
    unsigned hen10:1;
    unsigned hen11:1;
    unsigned hen12:1;
    unsigned hen13:1;
    unsigned hen14:1;
    unsigned hen15:1;
    unsigned hen16:1;
    unsigned hen17:1;
    unsigned hen18:1;
    unsigned hen19:1;
    unsigned hen20:1;
    unsigned hen21:1;
    unsigned hen22:1;
    unsigned hen23:1;
    unsigned hen24:1;
    unsigned hen25:1;
    unsigned hen26:1;
    unsigned hen27:1;
    unsigned hen28:1;
    unsigned hen29:1;
    unsigned hen30:1;
    unsigned :0;
    unsigned hen31:1;
    unsigned hen32:1;
    unsigned hen33:1;
    unsigned hen34:1;
    unsigned hen35:1;
    unsigned hen36:1;
    unsigned hen37:1;
    unsigned hen38:1;
    unsigned hen39:1;
    unsigned hen40:1;
    unsigned hen41:1;
    unsigned hen42:1;
    unsigned hen43:1;
    unsigned hen44:1;
    unsigned hen45:1;
    unsigned hen46:1;
    unsigned hen47:1;
    unsigned hen48:1;
    unsigned hen49:1;
    unsigned hen50:1;
    unsigned hen51:1;
    unsigned hen52:1;
    unsigned hen53:1;
    unsigned :0;
    unsigned reserved8;
    unsigned len0:1;
    unsigned len1:1;
    unsigned len2:1;
    unsigned len3:1;
    unsigned len4:1;
    unsigned len5:1;
    unsigned len6:1;
    unsigned len7:1;
    unsigned len8:1;
    unsigned len9:1;
    unsigned len10:1;
    unsigned len11:1;
    unsigned len12:1;
    unsigned len13:1;
    unsigned len14:1;
    unsigned len15:1;
    unsigned len16:1;
    unsigned len17:1;
    unsigned len18:1;
    unsigned len19:1;
    unsigned len20:1;
    unsigned len21:1;
    unsigned len22:1;
    unsigned len23:1;
    unsigned len24:1;
    unsigned len25:1;
    unsigned len26:1;
    unsigned len27:1;
    unsigned len28:1;
    unsigned len29:1;
    unsigned len30:1;
    unsigned :0;
    unsigned len31:1;
    unsigned len32:1;
    unsigned len33:1;
    unsigned len34:1;
    unsigned len35:1;
    unsigned len36:1;
    unsigned len37:1;
    unsigned len38:1;
    unsigned len39:1;
    unsigned len40:1;
    unsigned len41:1;
    unsigned len42:1;
    unsigned len43:1;
    unsigned len44:1;
    unsigned len45:1;
    unsigned len46:1;
    unsigned len47:1;
    unsigned len48:1;
    unsigned len49:1;
    unsigned len50:1;
    unsigned len51:1;
    unsigned len52:1;
    unsigned len53:1;
    unsigned :0;
    unsigned reserved9;
    unsigned aren0:1;
    unsigned aren1:1;
    unsigned aren2:1;
    unsigned aren3:1;
    unsigned aren4:1;
    unsigned aren5:1;
    unsigned aren6:1;
    unsigned aren7:1;
    unsigned aren8:1;
    unsigned aren9:1;
    unsigned aren10:1;
    unsigned aren11:1;
    unsigned aren12:1;
    unsigned aren13:1;
    unsigned aren14:1;
    unsigned aren15:1;
    unsigned aren16:1;
    unsigned aren17:1;
    unsigned aren18:1;
    unsigned aren19:1;
    unsigned aren20:1;
    unsigned aren21:1;
    unsigned aren22:1;
    unsigned aren23:1;
    unsigned aren24:1;
    unsigned aren25:1;
    unsigned aren26:1;
    unsigned aren27:1;
    unsigned aren28:1;
    unsigned aren29:1;
    unsigned aren30:1;
    unsigned :0;
    unsigned aren31:1;
    unsigned aren32:1;
    unsigned aren33:1;
    unsigned aren34:1;
    unsigned aren35:1;
    unsigned aren36:1;
    unsigned aren37:1;
    unsigned aren38:1;
    unsigned aren39:1;
    unsigned aren40:1;
    unsigned aren41:1;
    unsigned aren42:1;
    unsigned aren43:1;
    unsigned aren44:1;
    unsigned aren45:1;
    unsigned aren46:1;
    unsigned aren47:1;
    unsigned aren48:1;
    unsigned aren49:1;
    unsigned aren50:1;
    unsigned aren51:1;
    unsigned aren52:1;
    unsigned aren53:1;
    unsigned :0;
    unsigned reserved10;
    unsigned afen0:1;
    unsigned afen1:1;
    unsigned afen2:1;
    unsigned afen3:1;
    unsigned afen4:1;
    unsigned afen5:1;
    unsigned afen6:1;
    unsigned afen7:1;
    unsigned afen8:1;
    unsigned afen9:1;
    unsigned afen10:1;
    unsigned afen11:1;
    unsigned afen12:1;
    unsigned afen13:1;
    unsigned afen14:1;
    unsigned afen15:1;
    unsigned afen16:1;
    unsigned afen17:1;
    unsigned afen18:1;
    unsigned afen19:1;
    unsigned afen20:1;
    unsigned afen21:1;
    unsigned afen22:1;
    unsigned afen23:1;
    unsigned afen24:1;
    unsigned afen25:1;
    unsigned afen26:1;
    unsigned afen27:1;
    unsigned afen28:1;
    unsigned afen29:1;
    unsigned afen30:1;
    unsigned :0;
    unsigned afen31:1;
    unsigned afen32:1;
    unsigned afen33:1;
    unsigned afen34:1;
    unsigned afen35:1;
    unsigned afen36:1;
    unsigned afen37:1;
    unsigned afen38:1;
    unsigned afen39:1;
    unsigned afen40:1;
    unsigned afen41:1;
    unsigned afen42:1;
    unsigned afen43:1;
    unsigned afen44:1;
    unsigned afen45:1;
    unsigned afen46:1;
    unsigned afen47:1;
    unsigned afen48:1;
    unsigned afen49:1;
    unsigned afen50:1;
    unsigned afen51:1;
    unsigned afen52:1;
    unsigned afen53:1;
    unsigned :0;
    unsigned reserved11;
    unsigned pud:2;
    unsigned :0;
    unsigned pudclk0:1;
    unsigned pudclk1:1;
    unsigned pudclk2:1;
    unsigned pudclk3:1;
    unsigned pudclk4:1;
    unsigned pudclk5:1;
    unsigned pudclk6:1;
    unsigned pudclk7:1;
    unsigned pudclk8:1;
    unsigned pudclk9:1;
    unsigned pudclk10:1;
    unsigned pudclk11:1;
    unsigned pudclk12:1;
    unsigned pudclk13:1;
    unsigned pudclk14:1;
    unsigned pudclk15:1;
    unsigned pudclk16:1;
    unsigned pudclk17:1;
    unsigned pudclk18:1;
    unsigned pudclk19:1;
    unsigned pudclk20:1;
    unsigned pudclk21:1;
    unsigned pudclk22:1;
    unsigned pudclk23:1;
    unsigned pudclk24:1;
    unsigned pudclk25:1;
    unsigned pudclk26:1;
    unsigned pudclk27:1;
    unsigned pudclk28:1;
    unsigned pudclk29:1;
    unsigned pudclk30:1;
    unsigned :0;
    unsigned pudclk31:1;
    unsigned pudclk32:1;
    unsigned pudclk33:1;
    unsigned pudclk34:1;
    unsigned pudclk35:1;
    unsigned pudclk36:1;
    unsigned pudclk37:1;
    unsigned pudclk38:1;
    unsigned pudclk39:1;
    unsigned pudclk40:1;
    unsigned pudclk41:1;
    unsigned pudclk42:1;
    unsigned pudclk43:1;
    unsigned pudclk44:1;
    unsigned pudclk45:1;
    unsigned pudclk46:1;
    unsigned pudclk47:1;
    unsigned pudclk48:1;
    unsigned pudclk49:1;
    unsigned pudclk50:1;
    unsigned pudclk51:1;
    unsigned pudclk52:1;
    unsigned pudclk53:1;
    unsigned :0;
    unsigned reserved12;
    unsigned test:4;
};



GPREGISTERS* get_gpio_map();



■printfの出力結果
sel:b6f65000
levn_mask:00400000
GPLEVN   :00400000
levn_mask :00400000
GPLEVNbm  :00000001
end.


環境


Raspberry Pi B Rev2 (china)

Linux raspberrypi 4.1.13+ #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015 armv6l GNU/Linux


Eclipse IDE for C/C++ Developers
Version: Mars.1 Release (4.5.1)
Build id: 20150924-1200


 <?xml version="1.0"?>
-<Toolchain xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ToolchainName>Raspberry PI</ToolchainName>
      <ToolchainType>Linux</ToolchainType>
      <PathDetectionKeyStrip>0</PathDetectionKeyStrip>
      <GNUTargetID>arm-linux-gnueabihf</GNUTargetID>
      <ToolchainID>com.visualgdb.raspberry_pi</ToolchainID>
      <BinaryDirectory>bin</BinaryDirectory>
      <Prefix>arm-linux-gnueabihf-</Prefix>
      <Make>make.exe</Make>
      <BSPIndexUrlFormat>http://visualgdb.com/hwsupport/BSP/?autofetch=1&target=arm-linux-gnueabihf&filter={0}</BSPIndexUrlFormat>
      <IsCygwinBased>false</IsCygwinBased>
      <GCCVersion>4.9.2</GCCVersion>
      <GDBVersion>7.10</GDBVersion>
      <Revision>1</Revision>
      <RelativeSysrootPath>arm-linux-gnueabihf\sysroot</RelativeSysrootPath>
 </Toolchain>

Raspberry Piと秋月I2C接続LCD(gnublin-api)(C++)(備忘録)

Raspberry Pi B Rev2 (china) に秋月の「I2C接続小型キャラクタLCDモジュール 8x2行」を繋いで、表示させてみる。

Raspberry Pi(Raspbian)の設定


raspi-configのAdvanced Optionsで設定。

Raspberry Piと秋月I2C接続LCD

Raspberry Piと秋月I2C接続LCD

Raspberry Piと秋月I2C接続LCD

Raspberry Piと秋月I2C接続LCD

Raspberry Piと秋月I2C接続LCD

Raspberry Piと秋月I2C接続LCD

RaspRaspberry Piと秋月I2C接続LCD

Raspberry Piと秋月I2C接続LCD

Raspberry Piと秋月I2C接続LCD

Raspberry Piと秋月I2C接続LCD

再起動して完了。

C++用 I2C API(gnublin-api)入手


I2C用APIライブラリーを下記より入手。

参考:https://www.raspberrypi.org/forums/viewtopic.php?f=33&t=43725

ダウンロード:https://github.com/embeddedprojects/gnublin-api

gnublin.cppとgnublin.hをダウンロードする。


LCD制御


■資料
I2Cを使用してLCDを制御する方法は、秋月のI2C接続小型キャラクタLCDモジュール 8x2行の頁に参考資料のリンクがあるので、そちらから入手する。


テスト


■ソース
#define BOARD RASPBERRY_PI
#include "gnublin.h"
#include <time.h>
#include <sys/time.h>
#include <unistd.h>

#define POWERONWAITTIME 50000000
#define EXECWAITTIME       30000
#define FOLLWAITTIME   200000000
#define CLEARWAITTIME    2000000

void nano_sleep(unsigned Anano_sec){
struct timespec req;
req.tv_sec = Anano_sec/1000000000;
req.tv_nsec = Anano_sec%1000000000 ;
nanosleep(&req, NULL);
}

int main() {
gnublin_i2c i2c;
unsigned char buffer[100];

i2c.setAddress(0x3e); // set the address of the slave you want to read/write

// init begin
nano_sleep(POWERONWAITTIME);
//Function SET IS=0
buffer[0] = 0x00;
buffer[1] = 0x38;
i2c.send(buffer, 2);
nano_sleep(EXECWAITTIME);

//Function SET IS=1
buffer[0] = 0x00;
buffer[1] = 0x39;
i2c.send(buffer, 2);
nano_sleep(EXECWAITTIME);

//Internal OSC frequency
buffer[0] = 0x00;
buffer[1] = 0x14;
i2c.send(buffer, 2);
nano_sleep(EXECWAITTIME);

//Contrast set
buffer[0] = 0x00;
buffer[1] = 0x70;
i2c.send(buffer, 2);
nano_sleep(EXECWAITTIME);

//Pwoer/ICON/Contrast control
buffer[0] = 0x00;
buffer[1] = 0x56;
i2c.send(buffer, 2);
nano_sleep(EXECWAITTIME);

//follower control
buffer[0] = 0x00;
buffer[1] = 0x6c;
i2c.send(buffer, 2);
nano_sleep(FOLLWAITTIME);

//nano_sleep(EXECWAITTIME);
//Function set
buffer[0] = 0x00;
buffer[1] = 0x38;
i2c.send(buffer, 2);
nano_sleep(EXECWAITTIME);

//Display ON/OFF control
buffer[0] = 0x00;
buffer[1] = 0x0c;
i2c.send(buffer, 2);
nano_sleep(EXECWAITTIME);

//Clear Display
buffer[0] = 0x00;
buffer[1] = 0x01;
i2c.send(buffer, 2);
nano_sleep(CLEARWAITTIME);

//DDRAM Address set
buffer[0] = 0x00;
buffer[1] = 0x80;
i2c.send(buffer, 2);

// init end


//disp char
buffer[0] = 0x40;
buffer[1] = 'A';
i2c.send(buffer, 2);

buffer[0] = 0x40;
buffer[1] = 'B';
i2c.send(buffer, 2);

}



■結果
LCD左上から「AB」と続けて表示した。

以下はロジックアナライザの画面
Raspberry Piと秋月I2C接続LCD


問題点


Raspberry Pi電源投入後、第一回目の実行では文字が表示されない。
二回目移行は問題なく動作する。

原因は下図の様に、「00」「56」に続いて送られる「00」「6C」が送出されていない。(時により、6Cのみ送出されない時もある)
Raspberry Piと秋月I2C接続LCD

現在、真の原因は不明。

環境


root@raspberrypi:/# uname -a
Linux raspberrypi 4.1.13+ #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015 armv6l GNU/Linux

os-release(ファイル内容)
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"
NAME="Raspbian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"


Eclipse IDE for C/C++ Developers

Version: Mars.1 Release (4.5.1)
Build id: 20150924-1200


<?xml version="1.0"?>
<Toolchain xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ToolchainName>Raspberry PI</ToolchainName>
  <ToolchainType>Linux</ToolchainType>
  <PathDetectionKeyStrip>0</PathDetectionKeyStrip>
  <GNUTargetID>arm-linux-gnueabihf</GNUTargetID>
  <ToolchainID>com.visualgdb.raspberry_pi</ToolchainID>
  <BinaryDirectory>bin</BinaryDirectory>
  <Prefix>arm-linux-gnueabihf-</Prefix>
  <Make>make.exe</Make>
  <BSPIndexUrlFormat>http://visualgdb.com/hwsupport/BSP/?autofetch=1&amp;target=arm-linux-gnueabihf&amp;filter={0}</BSPIndexUrlFormat>
  <IsCygwinBased>false</IsCygwinBased>
  <GCCVersion>4.9.2</GCCVersion>
  <GDBVersion>7.10</GDBVersion>
  <Revision>1</Revision>
  <RelativeSysrootPath>arm-linux-gnueabihfsysroot</RelativeSysrootPath>
</Toolchain>


※2016/03 実施

Eclipse Raspberry Pi(Raspbian)での日本語の使用(備忘録)

Raspbian日本語環境はUTF-8を使用。

■Eclipse

下記で設定
Window→Preferences


Eclipse Raspberry Pi(Raspbian)での日本語の使用(備忘録)


■環境
Raspberry Pi B Rev2 (china)

Linux raspberrypi 4.1.13+ #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015 armv6l GNU/Linux


Eclipse IDE for C/C++ Developers
Version: Mars.1 Release (4.5.1)
Build id: 20150924-1200


 <?xml version="1.0"?>
-<Toolchain xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <ToolchainName>Raspberry PI</ToolchainName>
      <ToolchainType>Linux</ToolchainType>
      <PathDetectionKeyStrip>0</PathDetectionKeyStrip>
      <GNUTargetID>arm-linux-gnueabihf</GNUTargetID>
      <ToolchainID>com.visualgdb.raspberry_pi</ToolchainID>
      <BinaryDirectory>bin</BinaryDirectory>
      <Prefix>arm-linux-gnueabihf-</Prefix>
      <Make>make.exe</Make>
      <BSPIndexUrlFormat>http://visualgdb.com/hwsupport/BSP/?autofetch=1&target=arm-linux-gnueabihf&filter={0}</BSPIndexUrlFormat>
      <IsCygwinBased>false</IsCygwinBased>
      <GCCVersion>4.9.2</GCCVersion>
      <GDBVersion>7.10</GDBVersion>
      <Revision>1</Revision>
      <RelativeSysrootPath>arm-linux-gnueabihf\sysroot</RelativeSysrootPath>
 </Toolchain>

Eclipse の Workspace内のincludesとエディタ上での参照関係でエラーがでる(現象と対策)(備忘録)

■現象
Pプロジェクトのp.cppと連携しているi.hインクルードファイルの関係において。

P生成時に存在しなかった#defineをi.hに定義すると、
ビルドは正常に終了するが、エディタ上では参照関係を解決できなかった旨のエラーが発性する。

P生成時に存在するが、i.hを編集する事により文字位置が変わると、p.cppで「F3」キーによる「OPen Declaration」で正しくない位置を示す。(旧の文字位置にJUMPする)

■対策
1.全てのファイルをセーブする。
2.Pプロジェクトをdeleteする。(ファイルは消さない)
3.Pプロジェクトをimport→General→existing Porjects into Workspace
これで完了。



■環境(2015年12月実施)
Eclipse?IDE?for?C/C++?Developers
Version:?Mars.1?Release?(4.5.1)
Build?id:?20150924-1200






感想


関連する現象も含めて、3日掛かったが本来の設定方法は分からなかった。
暫定的な回避方法です。

android.os.AsyncTaskの実行スレッド(android studio)(Android)(備忘録)

UDPを使用する事があり、AsyncTask の onPostExecute を実行するスレッドについて確認してみました。

class WhoIsTask extends AsyncTask で AcyncTask のサブクラスを定義して各箇所で LOG を出力し、
実行しているスレッドIDを調べました。


■結果
doInBackground は WhoIsTask のインスタンスを実行しているスレッドで実行される。
onPostExecute は whoIsTask.executeOnExecutor した MainActivity のスレッドで実行される。


10-16 12:52:19.541 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: onCreate 001. Thread ID=1
10-16 12:52:19.541 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: onCreate 001. Process myPid=9124
10-16 12:52:19.541 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: onCreate 001. Process myTid=9124
10-16 12:52:19.541 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: onStart 001. Thread ID=1
10-16 12:52:19.541 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: onStart 001. Process myPid=9124
10-16 12:52:19.541 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: onStart 001. Process myTid=9124
10-16 12:52:19.541 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: WhoIsTask 001. Thread ID=1
10-16 12:52:19.541 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: WhoIsTask 001. Process myPid=9124
10-16 12:52:19.551 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: WhoIsTask 001. Process myTid=9124
10-16 12:52:19.551 9124-9178/jp.no4393.amefurictrl I/Amefurictrl001: doInBackground 001. Thread ID=1088
10-16 12:52:19.551 9124-9178/jp.no4393.amefurictrl I/Amefurictrl001: doInBackground 001. Process myPid=9124
10-16 12:52:19.551 9124-9178/jp.no4393.amefurictrl I/Amefurictrl001: doInBackground 001. Process myTid=9178
10-16 12:52:19.691 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: onPostExecute 001. Thread ID=1
10-16 12:52:19.691 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: onPostExecute 001. Process myPid=9124
10-16 12:52:19.691 9124-9124/jp.no4393.amefurictrl I/Amefurictrl001: onPostExecute 001. Process myTid=9124




■ソース概要

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

logger = Logger.getLogger("Amefurictrl001");
logger.info("onCreate 001. Thread ID=" + Thread.currentThread().getId() );
logger.info("onCreate 001. Process myPid=" + android.os.Process.myPid());
logger.info("onCreate 001. Process myTid=" + android.os.Process.myTid());


@Override
protected void onStart() {
super.onStart();

logger.info("onStart 001. Thread ID=" + Thread.currentThread().getId() );
logger.info("onStart 001. Process myPid=" + android.os.Process.myPid());
logger.info("onStart 001. Process myTid=" + android.os.Process.myTid());

whoIsTask = new WhoIsTask(logger);
whoIsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);




public class WhoIsTask extends AsyncTask {

public WhoIsTask(Logger logger){
super();
this.logger = logger;

logger.info("WhoIsTask 001. Thread ID=" + Thread.currentThread().getId() );
logger.info("WhoIsTask 001. Process myPid=" + android.os.Process.myPid());
logger.info("WhoIsTask 001. Process myTid=" + android.os.Process.myTid());


@Override
protected Integer doInBackground(Integer... value){
logger.info("doInBackground 001. Thread ID=" + Thread.currentThread().getId() );
logger.info("doInBackground 001. Process myPid=" + android.os.Process.myPid());
logger.info("doInBackground 001. Process myTid=" + android.os.Process.myTid());


@Override
protected void onPostExecute(Integer result) {
logger.info("onPostExecute 001. Thread ID=" + Thread.currentThread().getId() );
logger.info("onPostExecute 001. Process myPid=" + android.os.Process.myPid());
logger.info("onPostExecute 001. Process myTid=" + android.os.Process.myTid());


スレッドでTextViewの更新(post)(android studio)(Android)(備忘録)

TextViewはUIスレッド(メインスレッド)でないと更新できない。

サブスレッドでTextViewを更新する一例。
ポイント : textView1.post(new Runnable(){});


■MainActivity

package jp.no4393.processthreadtest001;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.logging.Logger;

public class MainActivity extends AppCompatActivity {

private Logger logger;
private TextView textView1;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

logger = Logger.getLogger("PTTest001");
logger.info("onCreate 001.");

textView1 = (TextView)findViewById(R.id.textView1);
}

public void buttoun1onClick(View view){
logger.info("buttoun1onClick 001.");
((Button)view).setText("buttoun1onClick");

SubThread subThread = new SubThread(logger);
subThread.textView1 = textView1;
Thread thread = new Thread(subThread);
thread.start();

}

}




■subThead

package jp.no4393.processthreadtest001;

import android.widget.TextView;
import java.util.logging.Logger;


public class SubThread implements Runnable {
private Logger logger;
public TextView textView1;

public SubThread(Logger logger){
this.logger = logger;
}

public void run(){
logger.info("subThead.run 001.");
textView1.post(new Runnable(){
public void run() {
textView1.setText("Runnable setText.");
logger.info("Runnable 101.");
}
});
logger.info("subThead.run 002.");
}

}




■log

10-16 18:13:30.182 24965-24965/jp.no4393.processthreadtest001 I/PTTest001: onCreate 001.
10-16 18:13:32.875 24965-24965/jp.no4393.processthreadtest001 I/PTTest001: buttoun1onClick 001.
10-16 18:13:32.875 24965-25170/jp.no4393.processthreadtest001 I/PTTest001: subThead.run 001.
10-16 18:13:32.875 24965-25170/jp.no4393.processthreadtest001 I/PTTest001: subThead.run 002.
10-16 18:13:32.885 24965-24965/jp.no4393.processthreadtest001 I/PTTest001: Runnable 101.

System.out.print()の出力先(android studio)(Android)(備忘録)

USB接続でNEC N-03E(Android 4.1.2 API 16)に接続してテスト。
Android Studio 2.2.1


■テスト目的
System.out.print()の出力先について。

■結果
Android Monitorのlogcatに表示される。


■MainActivity

package jp.no4393.printtest001;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

public void buttonOnClick(View view){
System.out.println("println 001.");
System.out.println("println 002.");
System.out.print("print 101.");
System.out.print("print 102.");
System.out.println("println 201.");
}

}





■出力結果(logcat)

10-16 11:12:43.324 17265-17265/jp.no4393.printtest001 I/System.out: println 001.
10-16 11:12:43.324 17265-17265/jp.no4393.printtest001 I/System.out: println 002.
10-16 11:12:43.324 17265-17265/jp.no4393.printtest001 I/System.out: print 101.print 102.println 201.

Thread間通信 Handler Message Looper(android studio)(Android)(備忘録)

メインスレッドが生成する二つのサブスレッドに於いて
SubThread1はSubThread2からの情報を受取り内部データを更新する。
SubThread2は何らかの情報を指定されたThreadに引き渡す役目を持つ。

SubThread1はインスタンスが生成され実行されるとLooperがループし、 メーセージを待つ。
また、SubThread1は自身のThreadで実行されるHandlerを生成し要求元へ引き渡す機能をもつ。
生成されたHandlerは他のThreadから送られてきたMessageの内容に従って特定の処理を実行するhandleMessage()を持つ。
このHandlerを生成する関数を複数種用意する事により、異なった機能を持たせる事ができる。

SubThread2はSubThread1が生成したHandlerを受け取り、自身が生成したデータをMessageに載せ、HandlerをsendMessage()でSubThread1に送る。
SubThread2は送ったハンドルを誰(Thread)が受け取りどの様に処理されるかは知らない。

メインスレッドはデータを処理する者(SubThread1)とデータを提供する者(SubThread2)の関係を制御するスレッドとなる。

※下記sampleはスレッドの実行順序の不正によるエラーは考慮していない。

■MainActivity

package jp.no4393.loopertest002;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {

private SubThread1 subThread1;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

public void bt1onClick(View view){
Log.d("LT002","B1-----start.");
subThread1 = new SubThread1();
subThread1.start();
Log.d("LT002","B1-----end.");
}

public void bt2onClick(View view){
Log.d("LT002","B2-----start.");
SubThread2 st2 = new SubThread2(subThread1.getHandler());
st2.start();
Log.d("LT002","B2-----end.");
}
}





■subThread1

package jp.no4393.loopertest002;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

public class SubThread1 extends Thread{

private String mark;
private Looper myLooper;

SubThread1(){
}

public void run(){
Log.d("LT002","T1 run.");
Looper.prepare();
myLooper = Looper.myLooper();
Looper.loop();
Log.d("LT002","T1 run end.");
}

public Handler getHandler(){
Log.d("LT002","T1 getHandler.");
mark = "SubThead1 getHandler.";
return new Handler(myLooper) {
public void handleMessage(Message msg) {
mark = String.valueOf(msg.what) + " mark=" + (String) msg.obj;
Log.d("LT002", mark);
}
};
}

}




■SubThread2

package jp.no4393.loopertest002;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class SubThread2 extends Thread {

private Handler toHandler;

SubThread2(Handler toHandler){
this.toHandler = toHandler;
}

public void run(){
Log.d("LT002","ST2 run sendMessage.");
try{
Thread.sleep(2000);
}catch(InterruptedException e){}
Message msg = new Message();
msg.what = 123;
msg.obj = "ST2 run message obj. myThreadId=" + String.valueOf(Thread.currentThread().getId());
toHandler.sendMessage(msg);
Log.d("LT002","ST2 run end.");
}

}




■log

Button1をタッチ後、Button2を三回連続タッチした時のlog

10-30 09:07:02.110 4768-4768/jp.no4393.loopertest002 D/LT002: B1-----start.
10-30 09:07:02.110 4768-4768/jp.no4393.loopertest002 D/LT002: B1-----end.
10-30 09:07:02.110 4768-5001/jp.no4393.loopertest002 D/LT002: T1 run.
10-30 09:07:03.241 4768-4768/jp.no4393.loopertest002 D/LT002: B2-----start.
10-30 09:07:03.241 4768-4768/jp.no4393.loopertest002 D/LT002: T1 getHandler.
10-30 09:07:03.241 4768-4768/jp.no4393.loopertest002 D/LT002: B2-----end.
10-30 09:07:03.241 4768-5075/jp.no4393.loopertest002 D/LT002: ST2 run sendMessage.
10-30 09:07:03.812 4768-4768/jp.no4393.loopertest002 D/LT002: B2-----start.
10-30 09:07:03.812 4768-4768/jp.no4393.loopertest002 D/LT002: T1 getHandler.
10-30 09:07:03.822 4768-4768/jp.no4393.loopertest002 D/LT002: B2-----end.
10-30 09:07:03.822 4768-5107/jp.no4393.loopertest002 D/LT002: ST2 run sendMessage.
10-30 09:07:04.383 4768-4768/jp.no4393.loopertest002 D/LT002: B2-----start.
10-30 09:07:04.383 4768-4768/jp.no4393.loopertest002 D/LT002: T1 getHandler.
10-30 09:07:04.383 4768-4768/jp.no4393.loopertest002 D/LT002: B2-----end.
10-30 09:07:04.383 4768-5146/jp.no4393.loopertest002 D/LT002: ST2 run sendMessage.
10-30 09:07:05.244 4768-5075/jp.no4393.loopertest002 D/LT002: ST2 run end.
10-30 09:07:05.244 4768-5001/jp.no4393.loopertest002 D/LT002: 123 mark=ST2 run message obj. myThreadId=519
10-30 09:07:05.834 4768-5107/jp.no4393.loopertest002 D/LT002: ST2 run end.
10-30 09:07:05.834 4768-5001/jp.no4393.loopertest002 D/LT002: 123 mark=ST2 run message obj. myThreadId=520
10-30 09:07:06.385 4768-5146/jp.no4393.loopertest002 D/LT002: ST2 run end.
10-30 09:07:06.385 4768-5001/jp.no4393.loopertest002 D/LT002: 123 mark=ST2 run message obj. myThreadId=521





■環境
Thread間通信 Handler Message Looper(android studio)(Android)(備忘録)


Thread間通信 Handler Message Looper(android studio)(Android)(備忘録)


Thread間通信 Handler Message Looper(android studio)(Android)(備忘録)

PIC12F675 GPIO port change interrupt 処理のループと対策(備忘録)

PIC 12F675の割り込み処理がうまく動作しないので調べてみました。

GPIO port change interrupt 処理がループしている模様です。
割り込み処理を一旦抜けるものの再度割り込み処理に入る。これを永遠に繰り返します。

開発環境 : MPLAB X IDE v3.51、Microchip MPLAB XC8 C Compiler (Free Mode) V1.40、ICD3です。

■結果
GPIO port change interrupt の割り込み処理内でGPIOレジスタに何らかのアクセスを すると、割り込み処理ループの現象は無くなりました。

調査


■発生時のソース

※下記ソースは現象確認の為のもので、この現象に気づいた時のものではありません。

GP5がport change 監視の対象ピン(外部からパルス信号を与える)
GP1はオシロによるデバック目的の出力ピン(今回のレポートでは使用していません)
GP4はCLKOUTとして、クロックを監視(目的は割り込み処理内での現象把握の為)

/*
 * GPIO割り込みテスト
 * Created on 2017/02/11, 8:17
 */

// CONFIG
#pragma config FOSC = INTRCCLK  // Oscillator Selection bits (INTOSC oscillator: CLKOUT function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // GP3/MCLR pin function select (GP3/MCLR pin function is MCLR)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)


#include <xc.h>

char time_count;

void interrupt intservice() {
    INTCONbits.GIE = 0;
    if (INTCONbits.GPIE && INTCONbits.GPIF) {
        INTCONbits.GPIF = 0;

        if (time_count++ > 10) {
            INTCON = 0x00;
            SLEEP();
        }

        //asm("MOVF GPIO,W");
    }
    INTCONbits.GIE = 1;
}

void main(void) {
    GPIO = 0x00;
    ANSEL = 0x00;
    CMCON = 0X07; //Comparator Off (Lowest power) CM2:CM0 = 111
    TRISIO = 0b00100000; //GPIO5:input
    GPIO = 0x00; //GPIOクリア
    INTCON = 0x00; //割り込み不許可
    OPTION_REG = 0x00;
    IOC = 0x00;
    PIE1 = 0x00;
    ADCON0 = 0x00;

    GPIObits.GP1 = 0;
    GPIObits.GP2 = 0;
    INTCON = 0x88;  //Enables all unmasked interrupts;
                    //Enables the GPIO port change interrupt
    IOC = 0b00100000; //IOC5 : enable an interrupt-on-change

    time_count = 0;
    while (1) {
        asm("MOVF GPIO,W");
        //asm("MOVWF GPIO");
    }

    return;
}


■発生時のオシロ波形

※CH1(黄) GP5がport change 監視の対象ピン(外部からパルス信号を与える)
※CH2(青) GP1はオシロによるデバック目的の出力ピン(今回のレポートでは使用していません)
※CH3(紫) GP4はCLKOUTとして、クロックを監視(目的は割り込み処理内での現象把握の為)
PIC12F675 GPIO port change interrupt 処理のループと対策(備忘録)
(1)CH1(黄) GP5入力端子にパルスが入り、信号レベルが変化すると、
(2)interrupt intservice()に制御が移る。
(3)intservice()内で、time_count++により割り込み回数をカウントし、
(4)一定回数(10回)を超えると、SLEEPさせる。(注1)
(5)SLEEPより、内部クロックが停止しCH3(紫) GP4のCLKOUT波形は停止する。これによりSLEEPを通過したことを確認した。

※注1:GP1にパルスを出す方法では、GP1へのアクセスそのものがこの現象を妨げる要因になるので、SLEEPを使用し内部クロックを停止する事により、ポイント通過を確認しました。


■現象要約
一度の割り込みであるにもかかわらず、連続して10回以上の割り込みが発生する。
time_countを100回カウントしても同様。


発生要素


(1)mainのループ、この場合while(1)内でGPIOレジスタにアクセスし、かつ
(2)interrupt intservice()内で、GPIOレジスタにアクセスしていない場合
に発生する。

対策


interrupt intservice()内で、asm("MOVF GPIO,W"); によりGPIOに空アクセスする。
main()内でGPIOへのアクセス制限はかけられない為。


感想


■この対策に気づいた理由は、

PIC12F675 GPIO port change interrupt 処理のループと対策(備忘録)
出典:MICROCHIP社のPIC12F629/675 Data Sheet

↓上図の拡大
PIC12F675 GPIO port change interrupt 処理のループと対策(備忘録)

入力はすでに安定しているにもかかわらず、Interrupt-on-Changeが発生するということは、上図右下の2つのDフリップフロップよるchange検出回路が動作していない、すなわち、RD PORTが出ていない。
よって、GPIOを空読みしたらいいのでは。
これで解決しましたが、このRD PORTは単にポートを読む時だけではなさそうです。mainでのwhile(1)よる空ループではGPIOのリードをしなくても、changeを検出しています。

■さらに詳細は
その後、色々試みましたが良く判りませんでした。





お知らせ
■注意:Google Chrome以外のブラウザでは動作しない事もあります。
お好みに応じて
画像だけの表示でいいよ
やっぱり全部表示して
背景は黒がいいな
背景を元に戻して
サブジャンル
メモリアルマップ
My Favorite Photo
検索フォーム
プロフィール

otsu.usiwakamaru

Author:otsu.usiwakamaru
五条の橋でひらりひらりと欄干を飛び渡る牛若丸のように、興の向くまま電子回路にプログラミングに写真にと飛び回っています。

プロフィール詳細

カレンダー
11 | 2007/12 | 01
- - - - - - 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 - - - - -
キーワード
クリックしたキーワードの記事のみ表示します。

ダンサー ミニー ミッキー デイジー ドナルド グーフィー  キャラクター 3D 試み MFP 電池 ティンカーベル デザイン クラリス 全天球 パークテーマ チップデール プルート IXY キャスト マレフィセント スクルージ ダッフィー スモールプラネット SPOT 改造 

最新記事
月別アーカイブ
全記事表示リンク

全ての記事を表示する

おすすめプログ(新着記事)
リンク


にほんブログ村
カテゴリ
橋 (1)
PIC (1)
カウンタ
訪問者数(UU)

アクセス数

現在の閲覧者数

tael no013用