чтение из канала для SPI

Работаю улинуксом на микроблейзе.

У меня проблема с SPI. Мой код работает, я вижу, что канал считывается. Но как я могу проверить данные (rdata) printf не работает.

Вот мой код

//slavetool

int main(int argc, char **argv)
{

    uint8_t rdata[1500];
    int ctrl = 0;
    int fd;
    int pipenr = 9;
    int n;
    char device[15];
    fd_set socks;

    //open codec
    sprintf(device,"/dev/spi/pipe%d", pipenr);
    fd = open(device, O_RDWR);
    if(fd < 0)
        {
        printf("Failed to open pipe %s\n", device);
        return 0;
        } else 
        {
        printf("openend %s\n", device);
        }   
    printf("fd = %i\n", fd);

    printf("Initialisation complete!\n");


while(1)
    {
        printf("try to set!\n");

        FD_ZERO(&socks);
        FD_SET(fd, &socks);

        printf("fd_set set!\n");

        n = select(fd + 1, &socks, NULL, NULL, NULL);   

        //printf("Select is %i!\n", n);

        if(FD_ISSET(fd, &socks)) 
        {
           ctrl = read(fd, &rdata, 1500);
           printf("entered data: %s", rdata);  //DOESN'T WORK
           printf("ctrl: %i", ctrl);           //DOESN'T WORK
           printf("Check1\n");                 // WORK

                if(ctrl<0) 
                {
                    perror("read");
                    printf("Ende ctrl ist %i!\n",ctrl);
                    FD_ZERO(&socks);
                    close(fd);
                    return -1;
                }  

                printf("Check2\n"); 



        } else {printf("FD_ISSET not set");}


    }

    close(fd);


    return 0;
}

Терминал:

# ./spiread
openend /dev/spi/pipe9
fd = 3
Initialisation complete!
try to set!
fd_set set!
Select is 1!
Wait:
Check1
Check2 

* Редактировать Спасибо за быстрый ответ. Не работай! Перепрыгивая через этот print(). ** Редактировать О, это работает! Спасибо Альтер Манн. Не могу проголосовать -.-


person hoherprotektor    schedule 29.01.2014    source источник
comment
Взгляните на редактирование моего ответа, это было неправильно   -  person David Ranieri    schedule 29.01.2014


Ответы (1)


uint8_t rdata[1500];
...
ctrl = read(fd, &rdata, 1500);
printf("entered data: %s", rdata);  //DOESN'T WORK

Я предлагаю изменить это на:

char rdata[1500];
...
ctrl = read(fd, rdata, sizeof(rdata) - 1);
if (ctrl == -1) {
  perror("read");
  exit(EXIT_FALURE);
}
rdata[ctrl] = '\0'; // read() doesn't add a trailing 0
printf("entered data: %s", rdata);

Обратите внимание, что recv предпочтительнее read в современных системах.

person David Ranieri    schedule 29.01.2014
comment
@AlterMann: у вас в коде переполнение буфера. Должно быть ctrl = read(fd, rdata, sizeof(rdata) - 1);. Если вы прочитаете полные 1500 байт, нулевой байт будет за пределами массива. - person DoxyLover; 29.01.2014
comment
@DoxyLover, я думаю, вы ошибаетесь: pubs.opengroup.org/onlinepubs/ 009604499/functions/read.html, взгляните на пример в конце. - person David Ranieri; 29.01.2014
comment
@AlterMann: разница в том, что в этом примере они не записывают лишний нулевой байт. В вашем коде read() может считывать 1500 байт (sizeof(rdata)), заполняя буфер. В этом случае ваше последнее задание запишет в rdata[1500], что приведет к переполнению массива. Я поддерживаю свой комментарий! - person DoxyLover; 29.01.2014
comment
@DoxyLover, упс, ты прав, теперь я вижу свою ошибку, спасибо за исправление. - person David Ranieri; 29.01.2014
comment
Да, есть переполнение стека. Еще раз спасибо! ^^ - person hoherprotektor; 30.01.2014