2012-03-21 8 views
2

Я искал на этом много, хотя я определенно мог пропустить что-то, и я исхожу из чтения http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html и этого http://www.amazon.com/Essential-Device-Drivers-Sreekrishnan-Venkateswaran/dp/0132396556, но у меня проблемы с чтением из больших массивов, которые я создал в моем модуле ядра Linux ~ 200 КБ. Я развиваюсь на основе ti-omap3530 на основе ARM. Я выделить массивы, как это:чтение большого массива из модуля ядра 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)); 

Моя функция чтения выглядит следующим образом (я понимаю, что я не делаю это, вероятно, лучший способ):

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); 

пространства пользователя чтение всегда сообщает чтение правильного количества байт, но я не получить правильные данные.

Это решение работает нормально, если я заменил 3500s выше чем-нибудь меньшим (до 1000 ведет себя просто отлично), но выше этого я получаю странное поведение, когда массив, который я считывал, заполняет нулевые прокладки последнего N каждого массива (такое же количество элементов в одной и той же точке в каждом из двух массивов) и начинается в конце ряда, например time/param [0] = некоторые значения намного дальше по исходным массивам, которые я хотел прочитать.

Я думаю, это связано с тем, что я недостаточно разбираюсь в обработке памяти, но я не знаю, как сделать это так, как я хочу, который хранит эти массивы данных в модуле, пока я не захочу чтобы прочитать их в пространстве пользователя. Любые предложения или идеи, в которых я ошибаюсь, будут очень признательны.

Заранее благодарим за ваше время, усилия и терпение в отношении меня.

+0

Я не понимаю, почему '3500 * 7 * 4 * 2'. Почему '* 2' в вашем' read' ?? –

+0

Буфер заполняется из двух исходных массивов размером 3500 * 7 * 4 байта (по крайней мере, это то, что я пытаюсь сделать). – gorgoth

+0

Просто обратите внимание, что большинство чисел в моем фактическом коде, например '3500',' 7', '4' и' 2' обрабатываются '# define', но я ввел литеральные числа выше, чтобы _try_, чтобы помочь сообщать то, что я пытаюсь сделать более четко, (не как правило, сильная моя) ... – gorgoth

ответ

0

Вы можете (должны) избегать чтения с помощью mmaping массивов в адресное пространство процесса spacepace с помощью mmap. Смотрите следующий пример:

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

+0

Спасибо за совет! Я проверяю это прямо сейчас. Я новичок в разработке ядра, и я могу использовать все советы, которые я могу получить. – gorgoth

 Смежные вопросы

  • Нет связанных вопросов^_^