char buf [] / pointer发生更改

时间:2015-12-27 19:23:31

标签: c

首先我的环境:GCC 4.9.2,Debian Linux 3.16 x86_64。我正在研究其他人的代码,所以我随时都要改变一些事情(我希望我能解决问题......)。我遇到了一个SIGSEGV,但似乎gdb在我的程序中找不到指向堆栈的痕迹(嗯)。所以我已经使用了printf' s。长话短说(太迟了),我想我已经追溯到这个:

在我的main()例程中,我有这段代码:

char buffer[256] = { [0 ... 255] = 0x00 }; // Neat, not seen this before

此缓冲区在各个地方使用,代码限制读取的典型读取为100或更少字节。但我注意到,当代码运行时缓冲区的地址发生变化(在main()中仍然存在):

i = 0x82; // char i;
fprintf(stderr, "C &buffer = %p\n", buffer);
BP_WriteToPirate(fd, &i);
fprintf(stderr, "D &buffer = %p\n", buffer);

编译后:

gcc -g3 -Wall -Os -DTRUE=1 -DFALSE=0 -DVERSION=\"V0.15\"   -c -o main.o main.c
gcc -g3 -o spisniffer serial.o buspirate.o main.o cleanup.o 

然后我看到了这一点输出:

    C &buffer = 0x7fffffffe290
    W> 0x82 size = 1 (1)
    D &buffer = 0x7fffffffe200

其间的代码是:

uint32_t BP_WriteToPirate(int fd, char *val) {
    int res = -1;
    char ret = 0;

    write(fd, val, 1);

    if (disable_comport != 1) {  //if comport is enable, we need a response from the port
        res = serial_read(fd, &ret, 1);

        if( ret != 0x01) {
            if (modem==TRUE){
                printf("Modem responded with %i byte and with a value of 0X%X\n",res,ret);
            } else {
                printf("ERROR\n");
                return -1;
            }
        }
    }

    return 0;
}

如果我用char * buffer = malloc(sizeof(char)* 256)替换char buffer [256]声明,则问题似乎不再发生。

我是在看一个愚蠢的错误,还是在系统调用/库中有错误?关于调试技巧的任何指示?

3 个答案:

答案 0 :(得分:1)

使用工具Valgrind在程序中查找无效的读/写

答案 1 :(得分:0)

这可能不是您观察到令人惊讶的行为的原因,但传递给fprintf说明符的%p的指针应该是void *或者这样投射:

fprintf(stderr, "C &buffer = %p\n", (void*)buffer);

问题的一个更可能原因是buffer函数中不同范围内main的多个定义。提供显示问题的实际代码,没有最小的可编译可验证示例,我们只能猜测。

编辑:查看您发布的代码,它似乎不是后者。非常有趣......

答案 2 :(得分:0)

以下文件都干净利落地编译。

我在ubuntu linux 14.04上使用gcc -Wall -Wextra -pedantic -Wconversion -std=c99 -c来编译每个文件

请注意,为获得干净的编译,代码有很多小的改动。

你可以执行一个'差异' ' CMP'或类似的功能,以突出显示为获得清洁编译所做的更改。

涉及的一些变化:

  1. 更正了printusage()函数
  2. 中的用法语句
  3. 更正了#include语句列表
  4. i的声明更正为unsigned char而不是char
  5. 根据需要更正了从intssize_tsize_t的某些其他变量的声明
  6. speed_t删除了两个不同的typedef,因此代码使用thermos.h头文件中的typedef
  7. 将函数的返回类型从uint32_t更改为int32_t,以便在发生错误时函数返回正确的-1
  8. 更正了代码的缩进以确保一致性/可读性
  9. for function:BP_WriteToPirate()将正确的第二个参数类型从int*转移到unsigned int*
  10. t_opt.c_...标记的参数正确转换为unsigned int而非默认int,但仅适用于未定义的NJC
  11. 修改了某些错误消息的内容以包含strerror(errno)字符串
  12. 更正从serial_read()退出并始终NUL终止输入缓冲区
  13. 为FALSE和TRUE添加#defines
  14. 从参数列表输入速度时,使用atol()而不是atoi(),因此数据类型将与typedef speed_t
  15. 匹配
  16. 一个仍然存在的问题是粘贴到cfsetispeed的实际值(& t_opt,speed);和cfsetospeed(& t_opt,speed);`函数必须来自thermos.h中定义的集合,而不是实际的波特率,因为参数必须是有效位图之一,而不是某些long int。
  17. 警告:我的系统没有调制解调器也没有'总线盗版`所以无法执行大量测试:没有(或坏)参数:输出如下:

    -------------------------------------------------------
    
     Bus Pirate binary mode SPI SNIFFER utility v0.2 (CC-0)
     http://dangerousprototypes.com
    
    -------------------------------------------------------
    
    
    &buffer = 0x7ffed4128010
    ERROR: Invalid argument(s).
    
    Help Menu
    
    
    -------------------------------------------------------
    
     Usage:              
       ./untitled  -d device -e 1 -p 0 
    
       Example Usage:   ./untitled -d /dev/ttyUSB0 -s 115200 -e 1 -p 0 
    
               Where: -d device is port e.g.  /dev/ttyUSB0
                      -s Speed is port Speed  default is 115200 
                      -e ClockEdge is 0 or 1  default is 1 
                      -p Polarity  is 0 or 1  default is 0 
                      -r RawData is 0 or 1    default is 0 
    
    
    -------------------------------------------------------
    

    具有相当好的参数,输出如下:

    ./untitled -d /dev/ttyUSB0 -s 115200 -e 1 -p 0 -r 0 
    -------------------------------------------------------
    
     Bus Pirate binary mode SPI SNIFFER utility v0.2 (CC-0)
     http://dangerousprototypes.com
    
    -------------------------------------------------------
    
    
    &buffer = 0x7ffd5a4b35f0
    A &buffer = 0x7ffd5a4b35f0
    Parameters used: Device = /dev/ttyUSB0,  Speed = 115200, Clock Edge= 1, Polarity= 0
     Opening Bus Pirate on /dev/ttyUSB0 at 115200bps...
    Could not open serial port due to: No such file or directory.Error opening serial port
    

    当我修改代码以忽略打开串口的失败时,结果是:使用相同的计数序列永远重复。

    0 Sync (0x00/0)
    0 Sync (0x00/1)
    0 Sync (0x00/2)
    ...
    0 Sync (0x00/120)
    0 Sync (0x00/121)
    0 Sync (0x00/122)
    0 Sync (0x00/0)
    

    并且堆栈指针没有移位,因此buffer []数组没有移动

    的main.c

    /*
     * This file is part of the Bus Pirate project (http://code.google.com/p/the-bus-pirate/).
     *
     * Written and maintained by the Bus Pirate project and http://dangerousprototypes.com
     *
     * To the extent possible under law, the project has
     * waived all copyright and related or neighboring rights to Bus Pirate. This
     * work is published from United States.
     *
     * For details see: http://creativecommons.org/publicdomain/zero/1.0/.
     *
     *    This program is distributed in the hope that it will be useful,
     *    but WITHOUT ANY WARRANTY; without even the implied warranty of
     *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     */
    
    // added
    #define _GNU_SOURCE
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h> // getopt(), usleep()
    #include <string.h> // strdup()
    #include <errno.h>
    
    #include <stdint.h>
    #include <signal.h>
    
    #define FALSE (0)
    #define TRUE (~FALSE)
    
    #ifdef WIN32
        #include <conio.h>
        #include <windef.h>
    #else
        //#include <curses.h>
    #endif
    
    #include "buspirate.h"
    #include "serial.h"
    
    int modem;   //set this to TRUE of testing a MODEM
    int verbose;
    int disable_comport = 0;   //1 to say yes, disable comport, any value to enable port default is 0 meaning port is enable.
    int dumphandle;     // use by dump file when using the -d dumfile.txt parameter
    char *dumpfile;
    
    #define SPI 0x01
    
    int print_usage(char * appname)
    {
        //print usage
        printf("\n\n");
    
        // added '-d com1 in two places
        printf("-------------------------------------------------------\n");
        printf("\n");
        printf(" Usage:              \n");
        printf("   %s  -d device -e [0|1] -p [0|1] -d deviceName\n ",appname);
        printf("\n");
        printf("   Example Usage:   %s -d /dev/ttyUSB0 -s 115200 -e 1 -p 0 \n",appname);
        printf("\n");
        printf("           Where: -d device is port e.g.  /dev/ttyUSB0\n");
        printf("                  -s Speed is port Speed  default is 115200 \n");
        printf("                  -e ClockEdge is 0 or 1  default is 1 \n");
        printf("                  -p Polarity  is 0 or 1  default is 0 \n");
        printf("                  -r RawData is 0 or 1    default is 0 \n");
        printf("\n");
    
        printf("\n");
    
        printf("-------------------------------------------------------\n");
    
        return 0;
    }
    
    
    int main(int argc, char** argv)
    {
        int opt;
        int fd;
        int res;
        int c;
        int new_state;
        int state = 0;
    
        //char buffer[256] = { [0 ... 255] = 0x00 };
        char buffer[256] = {  0x00 };
        //char *buffer = malloc(sizeof(char) * 256);
        unsigned char i; // was char i;
    
        char *param_port      = NULL;
        char *param_polarity  = NULL;
        char *param_clockedge = NULL;
        char *param_rawdata   = NULL;
        char *param_speed     = NULL;
        int   speed;
    
        printf("-------------------------------------------------------\n");
        printf("\n");
        printf(" Bus Pirate binary mode SPI SNIFFER utility v0.2 (CC-0)\n");
        printf(" http://dangerousprototypes.com\n");
        printf("\n");
        printf("-------------------------------------------------------\n");
        printf("\n\n");
    
        fprintf(stderr, "&buffer = %p\n", buffer);
    
        if (argc <= 1)
        {
            printf("ERROR: Invalid argument(s).\n\n");
            printf("Help Menu\n");
            print_usage(argv[0]);
            exit(-1);
        }
    
        while ((opt = getopt(argc, argv, "ms:p:e:d:r:")) != -1)
        {
            // printf("%c  \n",opt);
            switch (opt)
            {
                case 'd':  // device   eg. com1 com12 etc
                    if ( param_port != NULL)
                    {
                        printf("Device/PORT error!\n");
                        exit(-1);
                    }
                    param_port = strdup(optarg);
                    break;
    
                case 'e':      // clock edge
                    if (param_clockedge != NULL)
                    {
                        printf("Clock Edge should be 0 or 1\n");
                        exit(-1);
                    }
                    param_clockedge = strdup(optarg);
                    break;
    
                case 'p':
                    if (param_polarity != NULL)
                    {
                        printf("Polarity must be 0 or 1\n");
                        exit(-1);
                    }
                    param_polarity = strdup(optarg);
                    break;
    
                case 's':
                    if (param_speed != NULL)
                    {
                        printf("Speed should be set: eg  115200 \n");
                        exit(-1);
                    }
                    param_speed = strdup(optarg);
                    speed       = atoi(param_speed);
                    break;
    
                case 'r':      // raw data
                    if (param_rawdata != NULL)
                    {
                        printf("Raw Data should be 0 or 1\n");
                        exit(-1);
                    }
                    param_rawdata = strdup(optarg);
                    break;
    
                case 'm':       // modem debugging for testing
                    modem =TRUE;    // enable modem mode
                    break;
    
                default:
                    printf("Invalid argument %c", opt);
                    print_usage(argv[0]);
                    //exit(-1);
                    break;
            }
        } // end while
    
    
        fprintf(stderr, "A &buffer = %p\n", buffer);
    
        if (param_port==NULL)
        {
            printf("No serial port set\n");
            print_usage(argv[0]);
            exit(-1);
        }
    
        if (param_clockedge==NULL)
        {
            param_clockedge=strdup("1");
        }
    
        if (param_polarity==NULL)
        {
            param_polarity=strdup("0");
        }
    
        if (param_speed==NULL)
        {
            param_speed = strdup("115200");
            speed = 115200;
        }
    
        if (param_rawdata==NULL)
        {
            param_rawdata=strdup("0");
        }
    
        printf("Parameters used: Device = %s,  Speed = %s, Clock Edge= %s, Polarity= %s\n",param_port,param_speed,param_clockedge,param_polarity);
    
        //
        // Open serial port
        //
        printf(" Opening Bus Pirate on %s at %dbps...\n", param_port, speed);
        fd = serial_open(param_port);
        if (fd < 0)
        {
            fprintf(stderr, "Error opening serial port\n");            //serial_write( fd, "\x0E", 1);
            //serial_write( fd, &'0x0E', 1);
            return -1;
        }
    
        //
        // Enter binary mode, then enter a protocol mode
        //
        serial_setup(fd, (speed_t) speed);
    
        //printf(" Starting SPI sniffer...\n");
        if (modem == TRUE)
        {    // connected to modem for testing response
    
            serial_write( fd, "ATI3\x0D\0",5 );
            usleep(1);
            res= serial_read(fd, buffer, sizeof(buffer));
            printf("\n %s\n",buffer);
    
            serial_write( fd, "ATI4\x0D\0",5 );
            usleep(1);
            res= serial_read(fd, buffer, sizeof(buffer));
            printf("\n %s\n",buffer);
    
            serial_write( fd, "ATI7\x0D\0",5 );
            usleep(1);
            res= serial_read(fd, buffer, sizeof(buffer));
            printf("\n %s\n",buffer);
        }
    
        else
        {
            fprintf(stderr, " Configuring Bus Pirate...\n");
            fprintf(stderr, "B &buffer = %p\n\n", buffer);
            BP_EnableMode(fd, SPI); //enter BBIO then SPI
            //
            //Start sniffer
            //
    
            //configure according to user settings
            //1000wxyz - SPI config, w=HiZ/3.3v, x=CKP idle, y=CKE edge, z=SMP sample
            i = 0x80;
    
            if(strncmp(param_clockedge, "1", 1)==0)
            {
                i |= 0x02;
            }
    
            if(strncmp(param_polarity, "1", 1)==0)
            {
                i |= 0x04;
            }
    
            fprintf(stderr, "C &buffer = %p\n", buffer);
            BP_WriteToPirate(fd, &i);
            fprintf(stderr, "D &buffer = %p\n", buffer);
    
            // start the sniffer
            fprintf(stderr, "start the sniffer\n");
    
            // Yes this is goofy but it kept trying to writ 0xffffff82 instead of 0x0E
            char t[] = { 0x0E, 0x00 };
    
            serial_write( fd, t, 1);
    
            //
            // Done with setup
            //
            fprintf(stderr, "E &buffer = %p\n", buffer);
    
        }
    
        printf("Happy sniffing! Ctrl-C (^C) to stop.\n");
    
        // 000011XX - Sniff SPI traffic when CS low(10 ^N)/all(01 ^M)
        // 0x60 = `  30khz
        // 0x61 = a 125khz
        // 0x67 = b 250khz
        // 0x67 = c 1.0 Mhz
        // 0x67 = d 2.0 Mhz
        // 0x67 = e 2.6 Mhz
        // 0x67 = f 4.0 Mhz
        // 0x67 = g 8.0 Mhz
        //
        // Loop and print input from the serial port
        /*
        ** ###
        ** ### @FIXME: Major issue with a SIGSEGV but I can't figure it out!
        ** ###
        ** ### If I attempt to use char buffer[256] it moves from one address to
        ** ### another in the code above (is that normal?). So I'm guessing
        ** ### something in the BP_WriteToPirate() (above) is wrong as this is where
        ** ### the change occurs. I've malloc'd a buffer of 256 bytes and the code
        ** ### seems happier (ie, no SIGSEGV but no solution either).
        ** ###
        */
        fprintf(stderr, "X FD = %d &buffer = %p\n" , fd, buffer);
    
        while(1)
        {
            usleep(1);
            //res = serial_read(fd, ptr, 100);
            res = serial_read(fd, buffer, 100);
    
            if(res == -1)
            {
                // For some reason we get an error
                // So close the port and reopen it
                fprintf(stderr, "(%d) Read errno: %s\n", fd, strerror(errno));
                if(errno == EBADF)
                { // 9
                    close(fd);
    
                    fd = serial_open(param_port);
                    if (fd < 0)
                    {
                        fprintf(stderr, "Error opening serial port\n");
                        return -1;
                    }
    
                    //
                    // Enter binary mode, then enter a protocol mode
                    //
                    serial_setup(fd, (speed_t) speed);
                }
            }
    
            else if(res > 0)
            {
                for(c = 0; c < res; c++)
                {
                    if(strncmp(param_rawdata, "1", 1)==0)
                    {
                        printf("%02X ", (uint8_t) buffer[c]);
                    }
    
                    else
                    {
                        switch(state)
                        {
                            default:
                            // fall through
                            case 0: // waiting CS active
                                if (buffer[c] == 0x5B)
                                {
                                    printf("[");
                                    new_state = 1;
                                }
    
                                else
                                {
                                    printf("0 Sync (0x%02x/%d)\n", buffer[c], c);
                                    new_state = 0;
                                }
                                break;
    
                            case 1: // check for data or CS inactive
                                if (buffer[c] == 0x5C)
                                {
                                    new_state = 2;
                                }
    
                                else if (buffer[c] == 0x5D)
                                {
                                    printf("]\n");
                                    new_state = 0;
                                }
    
                                else
                                {
                                    printf("1 Sync (0x%02x)\n", buffer[c]);
                                    new_state = 0;
                                }
                                break;
    
                            case 2: // MPI
                                printf("0x%02X(", (uint8_t) buffer[c]);
                                new_state = 3;
                                break;
    
                            case 3: // MPO
                                printf("0x%02X)", (uint8_t) buffer[c]);
                                new_state = 1;
                                break;
                        } // end switch
                        state = new_state;
                    } // end if
                } // end for
            } // end if
        }    // ^C to stop
    
    
    
        free(param_port);
        free(param_speed);
        return 0;
    }
    

    serial.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <errno.h>
    
    #include <string.h>
    
    #include "serial.h"
    
    extern int disable_comport;
    extern char *dumpfile;
    
    int serial_setup(int fd, speed_t speed)
    {
        struct termios t_opt;
    
    #ifdef NJC
        int s = tcgetattr(cm11, &oldsb);
    
        if (s < 0)
        {
            perror("ttopen tcgetattr");
            exit(1);
        }
    
        newsb = oldsb;
    #ifndef BUSPIRATE_h_
    #define BUSPIRATE_h_
    
    #include <stdint.h>
    
    
    int32_t BP_WriteToPirate(int fd, unsigned char * val);
    void BP_EnableMode(int fd, char bbmode);
    
    #endif
    
        newsb.c_iflag = IGNBRK | IGNPAR;
        newsb.c_oflag = 0;
        newsb.c_lflag = ISIG;
        newsb.c_cflag = (CLOCAL | B4800 | CS8 | CREAD);
    
        for (s = 0; s < NCC; s++)
        {
            newsb.c_cc[s] = 0;
        }
    
        newsb.c_cc[VMIN]   = 1;
        newsb.c_cc[VTIME]  = 0;
    
        tcsetattr(cm11, TCSADRAIN, &newsb);
    #else
        /* set the serial port parameters */
        fcntl(fd, F_SETFL, 0);
        tcgetattr(fd, &t_opt);
    
        cfsetispeed(&t_opt, speed);
        cfsetospeed(&t_opt, speed);
    
        t_opt.c_cflag |= (unsigned)(CLOCAL | CREAD);
        t_opt.c_cflag &= (unsigned)~PARENB;
        t_opt.c_cflag &= (unsigned)~CSTOPB;
        t_opt.c_cflag &= (unsigned)~CSIZE;
        t_opt.c_cflag |= (unsigned)CS8;
        t_opt.c_lflag &= (unsigned)~(ICANON | ECHO | ECHOE | ISIG);
        t_opt.c_iflag &= (unsigned)~(IXON | IXOFF | IXANY);
        t_opt.c_oflag &= (unsigned)~OPOST;
        t_opt.c_cc[VMIN] = 0;
        //t_opt.c_cc[VTIME] = 10;
        t_opt.c_cc[VTIME] = 1;
    
        tcflush(fd, TCIFLUSH);
    
        tcsetattr(fd, TCSANOW, &t_opt);
    #endif
        return 0;
    } // end function: serial_setup
    
    
    int serial_write(int fd, char *buf, int size)
    {
        ssize_t ret = 0;
    
        ret = write(fd, buf, (size_t)size);
    
        fprintf(stderr, "W> ");
    
        for(int i = 0; i < size; i++)
        {
            fprintf(stderr, "0x%02x ", (unsigned char) buf[i]);
        }
    
        fprintf(stderr, "size = %d (%ld)\n", size, ret);
    
        return (int)ret;
    } // end function; serial_write
    
    
    int serial_read(int fd, char *buf, int size)
    {
        ssize_t len = 0;
        ssize_t ret = 0;
        int     timeout = 0;
    
        while ( len < size)
        {
            //fprintf(stderr, "FD = %d &buffer = %p (%d)\n" , fd, buf, sizeof(buf));
            ret = read(fd, buf+len, (size_t)(size-len));
            if (ret == -1)
            {
                buf[len] = '\0';
                return -1;
            }
    
            if (ret == 0)
            {
                timeout++;
    
                if (timeout >= 10)
                {
                    break;      // Break out and return from this function
                }
    
                else
                {
                    continue;   // Just continue the loop
                }
            }
    
            len += ret;
        } // end while
    
        //if( len > 255)
        //{
        //    buf[255] = 0x00;    // Buffer's length is 256
        //}
    
        //else
        //{
            buf[len] = 0x00;
        //}
        return (int)len;
    } // end function: serial_read
    
    
    int serial_open(char *port)
    {
        int fd;
        fd = open(port, O_RDWR | O_NOCTTY);
    
        if (fd == -1)
        {
            fprintf(stderr, "Could not open serial port due to: %s.", strerror( errno ) );
            return -1;
        }
    
        return fd;
    } // end function: serial_open
    
    
    int serial_close(int fd)
    {
        close(fd);
    
        return 0;
    } // end function: serial_close
    

    buspirate.c

    #define _GNU_SOURCE
    
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    #include <unistd.h>
    #include "serial.h"
    #include "buspirate.h"
    
    //static struct BP_t pBP;
    //static uint8_t BP_reversebyte(uint8_t c);
    //static char bpbuf[4096];
    //static int bpbufcnt;
    
    extern int disable_comport;
    extern int dumphandle;
    extern int verbose;
    extern int modem;
    
    // added
    #define FALSE (0)
    #define TRUE (~FALSE)
    
    
    // low lever send command, get reply function
    int32_t BP_WriteToPirate(int fd, char *val)
    {
        int res = -1;
        char ret = 0;
    
        serial_write(fd, val, 1);
    
        if (disable_comport != 1)
        {  //if comport is enable, we need a response from the port
            res = serial_read(fd, &ret, 1);
    
            if( ret != 0x01)
            {
                if (modem==TRUE)
                {
                printf("Modem responded with %i byte and with a value of 0X%X\n",res,ret);
                }
    
                else
                {
                    printf("ERROR\n");
                    return -1;
                }
            }
        }
    
        return 0;
    } // end function: BP_WriteToPirate
    
    
    /*
    ** Put the Buspirate into raw binary mode by sending 20 nulls
    ** expect BBIO1
    ** Then put it into SPI raw mode by sending it 0x01
    ** expect SPI1
    */
    void BP_EnableMode(int fd, char bbmode)
    {
        int ret;
        char tmp[100] = { 0x00 };
        int done = 0;
        //int cmd_sent = 0;
        int tries = 0;
    
        printf(" Entering binary mode...\n");
        if (fd == (-1))
        {   //added because the fd has already returned null
            printf("Port does not exist!");
            return;
        }
    
        // -[ BBIO1 - Binary mode ]-------------------------------------------------
        while (!done)
        {
            tmp[0] = 0x00;
    
            serial_write(fd, tmp, 1);
            tries++;
            usleep(1);
    
            ret = serial_read(fd, tmp, 5);
    
            if (modem==TRUE)
            {
                // ???
                printf("\nModem Responded = %i\n", ret);
                done=1;
            }
    
            else
            {
                if (ret != 5 && tries > 20)
                {
                    fprintf(stderr, "Buspirate did not respond correctly :( %i \n", ret );
                    exit(-1);
                }
    
                else if (strncmp(tmp, "BBIO1", 5) == 0)
                {
                    printf("read returned %i:%s\n", ret, tmp);
                    done=1;
                }
            }
    
            if (tries > 25)
            {
                printf("Buspirate:Too many tries in serial read! -exiting \n - chip not detected, or not readable/writable\n");
                exit(-1);
            }
        } // end while
    
        // -----------------------------------------------------------------------
        printf("BP found\n");
    
        // -[ SPI mode ]------------------------------------------------------------
        // 00000001 - Enter raw SPI mode, display version string
        //
        // Once in raw bitbang mode, send 0x01 to enter raw SPI mode. The
        // Bus Pirate responds 'SPIx', where x is the raw SPI protocol
        // version (currently 1). Get the version string at any time by
        // sending 0x01 again.
        done = 0;
        tmp[0] = bbmode;
        tmp[1] = 0x01;
        //printf("Sending 0X%02X to port\n",tmp[0]);
        serial_write(fd, tmp, 1);
        //tries++;
        usleep(1);
    
        ret = serial_read(fd, tmp, 5);
    
        if (modem == TRUE)
        {
                printf("Modem Responded = %i with value %#X\n",ret,tmp[0]);
        }
    
        else
        {
            if ( (ret >= 4) && (strncmp(tmp, "SPI1", 4) == 0))
            {
                printf("In SPI mode (%d/%s)\n", ret, tmp);
            }
    
            else
            {
                fprintf(stderr, "Buspirate did not respond correctly :( %i [ ", ret );
                // reusing tries instead of creating a new var, yeah, just lazy ;-)
                for(tries = 0; tries < ret; tries++)
                {
                    fprintf(stderr, "0x%02x ", tmp[tries]);
                }
                fprintf(stderr, "] %s\n", tmp);
    
                printf("Sending 0X%02X to port\n", 0x01);
                tmp[0] = 0x01;
                tmp[1] = 0x01;
                serial_write(fd, tmp, 1);
                usleep(1);
    
                if ( (ret==4) && (strncmp(tmp, "SPI1", 4) == 0))
                {
                    fprintf(stderr, "Yea: %s [ ", tmp ); //
                }
    
                else
                {
                    ret = serial_read(fd, tmp, 5);
    
                    printf("Sending 0X%02X to port\n", 0x01);
                    tmp[0] = 0x01;
                    tmp[1] = 0x01;
                    serial_write(fd, tmp, 2);
                    usleep(1);
    
                    ret = serial_read(fd, tmp, 5);
    
                    if ( (ret==4) && (strncmp(tmp, "SPI1", 4) == 0))
                    {
                        fprintf(stderr, "Yea: %s [ ", tmp ); //
                    }
    
                    else
                    {
                        if((ret==5) && (strncmp(tmp, "SPI1", 5) == 0))
                        {
                            fprintf(stderr, "Yea: %s [ ", tmp ); //
                        }
    
                        else
                        {
                            fprintf(stderr, "Buspirate did not respond correctly :( %i [ ", ret );
    
                            // reusing tries instead of creating a new var, yeah, just lazy ;-)
                            for(tries = 0; tries < ret; tries++)
                            {
                                fprintf(stderr, "0x%02x ", tmp[tries]);
                            }
    
                            fprintf(stderr, "] %s\n", tmp);
    
                            exit(-1);
                        }
                    }
                } // End if SPI1 else
            }
        }
    } // end function: BP_EnableMode
    

    serial.h

    #ifndef MYSERIAL_H_
    #define MYSERIAL_H_
    /*
    #ifdef WIN32
        #include <windows.h>
        #include <time.h>
        #define O_NOCTTY 0
        #define O_NDELAY 0
        #define B115200 115200
        #define B921600 921600
        #define OS WINDOWS
        int write(int fd, const void* buf, int len);
        int read(int fd, void* buf, int len);
        int close(int fd);
        int open(const char* path, unsigned long flags);
        int __stdcall select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfs, const struct timeval* timeout);
    #else
        #include <unistd.h>
        #include <termios.h>
        #include <sys/select.h>
        #include <sys/types.h>
        #include <sys/time.h>
        #ifdef MACOSX
            #include <IOKit/serial/ioss.h>
            #include <sys/ioctl.h>
            #define B1500000 1500000
            #define B1000000 1000000
            #define B921600  921600
        #endif
    #endif
    */
    
    #include <stdint.h>
    
    #ifdef WIN32
    #include <windows.h>
    #include <time.h>
    
    #define B115200 115200
    #define B921600 921600
    
    typedef long speed_t;
    #else
    
    #include <unistd.h>
    #include <termios.h>
    #include <sys/select.h>
    #include <sys/types.h>
    #include <sys/time.h>
    
    #endif
    
    int serial_setup(int fd, speed_t speed);
    int serial_write(int fd, char *buf, int size);
    int serial_read(int fd, char *buf, int size);
    int serial_open(char *port);
    int serial_close(int fd);
    
    
    #endif
    

    buspirate.h

    #ifndef BUSPIRATE_h_
    #define BUSPIRATE_h_
    
    #include <stdint.h>
    
    
    int32_t BP_WriteToPirate(int fd, unsigned char * val);
    void BP_EnableMode(int fd, char bbmode);
    
    #endif