2020年4月15日水曜日

[Linux] ファイル最後まで達したことを判定するには

こんにちは

ソフトな道をほのぼのと今日も歩きます。


今回は、Linux アプリ(C言語)でファイルリードする際、


ファイル最後に達したかどうか判定するのですが


その処理で、もしかすると、正しく判断できていないのでは?と思ったので


調べてみました。


これによって引き起こされていた現象は、


数十時間はアプリは動作するが、いきなりアプリがハングといった動作です。


推測している動作。


アプリ実行

→ファイルリード実行

→ファイル最後を超えるが、リードなのでそれとなく動いてしまう。

→スレッド動作が割り込んでくる。

→絶妙なタイミングでたまたま入って、リードしていたデータが変わる。

→スレッド処理から復帰する。

→データが化けた状態で処理を続行する為、リードデータを使用したサウンドなどの処理で誤動作

→アプリハング



下記参考までにサンプルです。

(一部、抜粋し、加工したものですので、動作するかは保証いたしかねます。)


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

#include <stdio.h>

#include <stdlib.h>

#include <sys/stat.h>


#define NORMALEND 0


int test(UCHAR* name, UINT line, char *result, UINT maxsize)

{

    FILE *fp;

    int i= 0;

    UCHAR chr[2];

    UINT length= 0;

    int count;

   struct stat statbuf;

   

      if(stat(name, &statbuf) != 0)

    {// error

        printf("[file] Error: stat() (%s %d) \n", __FILE__ , __LINE__ );

    }

    printf("[file] file size: %d (%s %d) \n ", (int)statbuf.st_size, __FILE__ , __LINE__ );

   

    //---------

    // ファイルリードの都度 countと比較していく

   fp = fopen(name, "rb");

   if (fp == NULL) {

       return ERROR_OPEN_FILE;

   }

   

    count= 0;

   

    /* ファイルの終端まで文字を読み取り表示する */

   for (i= 0; i< 0x1000; i++)

   {

        while(1)

        {

            if(count>= statbuf.st_size)

            {// サイズを超えたか?

                fclose(fp);

                return -1;

            }

            chr[0] = fgetc(fp);count++;

            if(count>= statbuf.st_size)

            {

                fclose(fp);

                return -1;

            }

           

            chr[1] = fgetc(fp);count++;

            if(chr[0]== 0 && chr[1]==0)

            {// ファイルの最後に到達(指定行見つかりませんでした。)

            // UTF-16だったので、2バイト分で見ています。

                fclose(fp);

                return -1;

            }

            else if(chr[0] == LF_CODE && chr[1] == 00)

            {// 改行コード検出

                break;

            }

        }

    }

    …

    return NORMALEND;

}


[環境]

私の使用環境は VMware 上でUbuntu14.04を使用しています。

コンパイラ: arm-linux-gnueabihf-gcc


近くの商店街は大繁盛でした。

(私は遠くから確認しただけです。)


先進国なので、

ソーシャルディスタンス系の開発とか、やりようがあるんじゃないかと

思いました。


・店を検索した時に人がいないところを教えてくれる。

・お弁当を自動販売機にする。


どうですか?


2020年4月14日火曜日

[Linux] アプリからSDカード上のファイルライトしたデータが反映されない

こんにちは

ソフトな道をほのぼのと今日も歩きます。


今回は、Linux アプリでSDカード上のファイルへライトした直後に


SDカードを抜くと、SDカードライトしたデータが反映されない


現象になっていました。


    ライトしたはずのデータが、文字化けしたり、

    途中からごっそりなくなっている。そういうような状態でした。


こちらの現象を解決できたのでアップします。


以下、非常に役に立ったリンク先になります。


http://oswald.hatenablog.com/entry/20101223/1293064800


ポイントはfwrite()した後に、以下3つを行うことでした。


1. fileno()より"fdatasync()"用の番号を取得する。

2. fflush()を行う。

3. fdatasync()を行う。


です。


下記参考サンプルです。


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

#include <unistd.h>


#define NORMALEND 0


int test(void)

{

    FILE *fp;    //ファイルポインター

    unsigned char buf[30];

    int rtc;

   

    memset(buf, 0, sizeof(buf));

   

    fp = fopen("/var/test.log","a"); //ファイルを開く

   

    int fp_num = fileno(fp);

   

    sprintf(buf, "dummy data %d \n", 1 );

   

    length= strlen(buf);

   

    fwrite(buf, length, 1, fp);

   

    rtc = fflush(fp);

   

    rtc= fdatasync(fp_num);

   

    fclose(fp); //ファイルを閉じる

   

    return NORMALEND;

}


[環境]

私の使用環境は VMware 上でUbuntu14.04を使用しています。

コンパイラ: arm-linux-gnueabihf-gcc


在宅ワークを開始しました。

残業代は出ないし、出るにしても非常に面倒な手続きが必要のようです。

ただ、外食もせず、子供の塾代やお稽古事もない状態なので

収支としてはトントンだと思います。


政府の30万円愚策はやらなくていいから、

所得税を控除してもらいたいです。


僕らの税金を返してください。

2020年4月1日水曜日

[Linux] エージングで逝ってしまう調査3

こんにちは

ソフトな道をほのぼのと今日も歩きます。


今回は、前回の逝ってしまう原因調査の続きです。


スレッドがsnd_pcm_writei()実行中に”-EBADFD”が入ってくると、

   

    そのエラーに対する処理は入っていない為


    リトライ発生という無限ループに入っていました。

   

調査したところ、そもそも、EBADFD自体でるのがNGということが分かりました。


スレッド内でクローズ処理をしていたのですが、


オープン失敗に対してもクローズ処理をしているところがありました。


要するにnullに対してのクローズ処理。


お恥ずかしい限りですw


また、FDファイルディスクリプタ自体が不定な箇所がありました。


fopen()とopen()のエラー判定は違うことに対処できていなかったです。


fopen()の失敗はNULL(0)

open()の失敗は-1

です。

 

FDはそれぞれ1以上、0以上となるので、エラー判定はしっかりしないと、数百回に一回の不具合につながります。


    今回は以上です。


[環境]

私の使用環境は VMware 上でUbuntu14.04を使用しています。

コンパイラ: arm-linux-gnueabihf-gcc


今日から新入社員が入ってきます。

電車内でおしゃべりしているが、飛沫感染させないようにしてもらいたいですね。

 

2020年3月26日木曜日

[Linux] 音がなる時にノイズがなる。

こんにちは

ソフトな道をほのぼのと今日も歩きます。


今回は、音が鳴る時に瞬間的にノイズのようなものが入ることについて記載します。


鳴っていたのを調べてみました。


linux-x.xx.xx/sound/soc/codecs/tlv320aic31xx.c


{TIMER_CLOCK_MCLK_DIVIDER , 0x00},*/


これをいじるとpop音の対応ができるとあったのですができませんでした。


試行錯誤した挙句、初期化を行うとどうやらパツパツ音が鳴るようです。


なので、起動時に一度だけ初期化を行うようにしました。


結果としてpop音はこの対策によってならなくなりました。


[環境]

私の使用環境は VMware 上でUbuntu14.04を使用しています。

コンパイラ: arm-linux-gnueabihf-gcc


商品券を12000円を国民に給付する案があるようです。


安倍総理の顔入りなら記念にとっておこう。


麻生元総理ならすぐに使おうかな。


2020年3月14日土曜日

[Linux] エージングで逝ってしまう調査2

こんにちは

ソフトな道をほのぼのと今日も歩きます。


今回は、前回の逝ってしまう原因調査の続きです。


スレッドがsnd_pcm_writei()実行中に”-EBADFD”が入ってくると、

   

    そのエラーに対する処理は入っていない為


    リトライ発生という無限ループに入っていました。


https://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html#gabc748a500743713eafa960c7d104ca6f


    こちらを見ると、”-EBADFD自体はPWMが正しくない状態になっているようです。


    手探りですが、snd_pcm_recover()を行って、復帰しなければ

   

    あきらめて、全体的にリトライを行うようにしようと思います。

           

今回は以上です。


[環境]

私の使用環境は VMware 上でUbuntu14.04を使用しています。

コンパイラ: arm-linux-gnueabihf-gcc



2020年3月6日金曜日

[Linux] エージングで逝ってしまう調査

こんにちは

ソフトな道をほのぼのと今日も歩きます。


今回は、linux 上で自作したアプリを実行中に何のエラーもなくどこかに逝ってしまったかのような現象について考えてみたいと思います。


2020-03-05時点ではまだ分かっていません。


  1. デバッカで強制ブレークすると、ソース情報にはないアドレスで止まりました。

→何かしらの処理でメインに戻れなくなったか?スレッドが入ってはいけない処理でスレッドが入ってしまったか

  1. "/etc/rc.local"から本アプリを登録していたが辞めてみたところ、現象発生時に"ctrl+c"で強制的に抜けることができた。

→DDRメモリが辺という訳ではない。

  1. いたるところでデバッグ用にprintf文を出力させてみた。

          →音再生開始してから終了するまでの間にスレッドが入っているような気がします。

スレッドは確かにクリエイトして動かしているだけなので、

動作としてラウンドロビンだとアウトかもしれません。

まずは、スレッドの動作仕様を見直してみることにします。

int pthread_getschedparam(pthread_t thread, int *policy,

                         struct sched_param *param);

で見ていきます!

           

今回は以上です。


[環境]

私の使用環境は VMware 上でUbuntu14.04を使用しています。

コンパイラ: arm-linux-gnueabihf-gcc


2020年2月19日水曜日

[Linux] SDカードブートがカードによって出来ない件

こんにちは

ソフトな道をほのぼのと今日も歩きます。


今回は、SDカード(MicroSDカードです。以下、SDカードとします。)の種類によってlinuxが起動できなかった件についてになります。


最近、ユーザにSDカードを渡す約束があったので、今までの開発に使用していた


ものとは別のSDカードを用意して、


uboot, kernel, デバイスツリー、ユーザランド(rootfs)を書き込んで、


端末に挿し込んで起動してみたところ、uboot→kernel途中までは


動作しているようですが、ユーザランドに到達する前に


“Waiting for root device /dev/mmcblk0p2..."


から先に進みませんでした。


SDの違いとしては以下の通りでした。


[NG品]

    スピードクラス10

    バスインターフェーススピード:UHS-I

[OK品]

スピードクラス10

    バスインターフェーススピード:記載ない

(

上記については、以下のサイトが分かりやすかったです。

https://www.green-house.co.jp/special/sd-card/

}


どうやら、クロックが速すぎて、ドライバ側では対応できていないことが

判明しました。


私の解決した方法は、”High Speedで動作させるように変更する”、の方針でした。


デバイスツリーファイル(xx.dts)を以下のように”no-1-8-v;”を追加することで


現象は収まりました。

-----------------------------------------------

    &mmc_1 {

        status = "okay";

        bus-width = <4>;

        …

        no-1-8-v;

        …

    };

-----------------------------------------------

           

今回は以上です。


[環境]

私の使用環境は VMware 上でUbuntu14.04を使用しています。

コンパイラ: arm-linux-gnueabihf-gcc


    コロナウィルスになった場合の症状が分からないでいます。

    たまに、すごい咳をしている人見かけますがそういう人は

    もしかしたらもしかすると。。。と思ってしまいます。

    人混みはやはり避けたほうがよさそうですね。