2012-03-21 11 views
2

私はこれをかなり捜しましたが、何かを見逃しているかもしれませんが、http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.htmlとこのhttp://www.amazon.com/Essential-Device-Drivers-Sreekrishnan-Venkateswaran/dp/0132396556を読んでいますが、読みづらい私は自分のLinuxカーネルモジュール〜200kBで作成した大きな配列を取り出します。私はARMベースのti-omap3530を開発中です。 (私はおそらく最善の方法これをやっていないよということを理解)linuxカーネルモジュールから大きな配列を読み出す

static unsigned int* captured_params; 
static unsigned int* time_params; 

captured_params=vmalloc(3500*7*sizeof(unsigned int)); 
time_params=vmalloc(3500*7*sizeof(unsigned int)); 

マイread関数は次のようになります:私はこのような配列を割り当てる

ssize_t tgdev_read(struct file *file, char *buf, size_t count, loff_t *ppos){ 
    /*This file will expect reads in 8-byte chunks, 4 for the data parameter 
    and 4 for the time parameter*/ 

    struct tg_dev *tg_devp = file->private_data; 
    unsigned int num_pairs=sample_counter; 
    static unsigned int pairs_out=0; 
    static unsigned int sent_successfully=0; 
    unsigned int* param_ptr; 
    unsigned int* time_ptr; 
    pairs_out=(tg_devp->current_pointer)/8; 
    num_pairs=sample_counter; 

    if(pairs_out==num_pairs){//all returned end of file 
    return 0; //EOF 
    } 
    while((pairs_out*8)<count){ 
    //update data pointers 
    time_ptr=&time_params[pairs_out]; 
    param_ptr=&captured_params[pairs_out]; 
    //send user time first 
    sent_successfully=copy_to_user(&buf[tg_devp->current_pointer],time_ptr,4); 
    //send param value for that time 
    sent_successfully=copy_to_user(&buf[tg_devp->current_pointer+4],param_ptr,4); 
    //update number of pairs sent to user 
    pairs_out+=1; 
    //update file_pointer 
    tg_devp->current_pointer +=8; 
    } 
    return pairs_out*8; 
} 

をそして私は、ユーザーにそれを読みます

int fp; 
char* mode="r"; 
char* fname="/dev/my_device"; 
unsigned int param[3500*7]={0}; 
unsigned int time[3500*7]={0}; 
unsigned int* param_ptr; 
unsigned int* time_ptr; 
char buff[3500*7*4*2]; 
int i=0; 
int rc=0; 
int completed_reads; 

fp=open(fname,O_RDONLY); 

if(fp<0){ 
    printf("failed to open file EXITING\n"); 
    return 1; 
} 

rc=read(fp,buff,3500*7*4*2); 
completed_reads=(rc-rc%8)/8; 
printf("rc=%i cr=%i\n",rc,completed_reads); 

for(i=0;i<completed_reads;i++){ 
    param_ptr=&param[i]; 
    time_ptr=&time[i]; 
    memcpy(param_ptr,&buff[i*8],4); 
    memcpy(time_ptr,&buff[i*8+4],4); 
    printf("[%i]%u,%u\n",i,param[i],time[i]); 
} 
close(fp); 

読んでいるユーザー空間は、常に正しいバイト数を報告していますが、正しいデータは得られません。

上記の3500を何か小さなもの(最大1000まで動作します)で置き換えると、この解決策はうまくいくように見えますが、それより上では、アレイが0のパッドを読み出すと、 2つの配列のそれぞれの同じ点にある同じ数の要素)、シリーズの後半に開始します。 time/param [0] =私が読んでいた元の配列よりはるかに遠いいくつかの値。

メモリの処理が分かりにくいと思っていますが、私が望むようにこれを行う方法はわかりません。私が望むまで、これらのデータ配列をモジュールに格納しています。それらをユーザー空間に読み込むことができます。私が間違っている提案やアイデアは非常に高く評価されます。

私はあなたの時間、努力と忍耐のために事前に感謝します。

+0

を私がなぜ '3500 * 7 * 4 * 2'理解しません。なぜあなたの 'read'に' * 2'があるのですか? –

+0

バッファは、オリジナルの2つの配列からそれぞれ3500 * 7 * 4バイトのサイズで埋められています(少なくとも私がしようとしているものです)。 – gorgoth

+0

私の実際のコードでは、 '3500'、' 7'、 '4'、' 2'のような数字は '#define'で扱われますが、 _try_私がもっと明確にしようとしていることを伝えるのを助けるために(一般的に私の強みではない)... – gorgoth

答えて

0

mmapでユーザ空間のプロセスのアドレス空間に配列をmmapingすることで読み込みを行うことはできません。次の例を参照してください:

http://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-8.html

+0

アドバイスをいただきありがとうございます!私は今それをチェックしている。私はカーネル開発が初めてで、私が得ることができるすべてのアドバイスを使用することができます。 – gorgoth

関連する問題