检查总和和串口通信

时间:2014-03-06 17:44:37

标签: c string serial-port checksum

我正在尝试从USB到串口转换器发送带有校验和的消息,然后再返回。 但是,由于某种原因,我无法让它工作,即使是艰难的我也试过了一天。我开始认为硬件有问题,但我认为在放弃之前问你们是个好主意...我正在使用cygwin在Windows计算机上执行和编译程序。

我希望在程序运行时附上终端的图片,但你必须拥有> 10的声誉我不是:(。所以我将不得不描述它.... 。 当我尝试发送'a'时,我从终端获得以下信息。

输入消息:a 您要发送的邮件的校验和是:97
您要发送的信息是:a 一个@
收到的消息的校验和是:97
消息未正确收到!
您收到以下内容:a 一个@

我收到了我发送的内容,但'a'的支票金额应该是'a'对吗?所以应该发送的字符串是“aa”而不是“a” 一个@“或者我完全迷失在这里。

我附上了以下代码的相关部分(printWhite()等更改了文本的颜色,仅此而已)

void main(){
     regularSend(); 
     regularReceive();
}

void regularSend(){ 
    char buff2s[20];
    unsigned char calculatedCS;
    printf("Enter a message: ");
    fgets(buff2s,15,stdin); // string input from keyboard
    calculatedCS=checkSum(buff2s,strlen(buff2s));
    printf("The checksum for your message to send is: %i\n",calculatedCS); 
    buff2s[strlen(buff2s)]=calculatedCS; //adds a checksum
    buff2s[strlen(buff2s)]='\0'; //adds a new string terminator
    printf("Your message to send is: %s\n",buff2s);
    bytes_written=write(fd,buff2s,strlen(buff2s));
    sleep(1); 
}



 void regularReceive(){
    unsigned char buffR[20];
    unsigned char rCS;
    bytes_read=read(fd,buffR,sizeof(buffR)-1);
            if(strlen(buffR)<1){ 
                printRed();
                printf(" No reply from the serial device! \n");
                printWhite();
            }
            else{
                rCS=checkSum(buffR,strlen(buffR)-2); //1 byte extra now
                printf("The checksum of the received message is: %i\n", rCS);
                true_or_false=check_checkSum(buffR,strlen(buffR)-1);
                    if(true_or_false==1){
                        buffR[strlen(buffR)-1]='\0'; //removes checksum
                        printf("Your message was: %s\n",buffR);
                    }
                    else{
                    printRed();
                    printf("The message wasn't properly received!\n");
                    printWhite();
                    printf("You received the following: %s\n\n",buffR);
                }
            }
}

unsigned char checkSum(char buff[], unsigned char nbrOfBytes){
    unsigned char ic;
    unsigned int t_cSum=0;
        for (ic=0;ic<nbrOfBytes-1;ic++){
            t_cSum=t_cSum+buff[ic];
        }
    return (unsigned char) t_cSum; //returns a 8bit checksum
}
unsigned char check_checkSum(char buffR_t[], unsigned char nbrOfBytes){ //<- check this
    unsigned char r_cSum=checkSum(buffR_t,nbrOfBytes-1); //calculates the expected value of the checksum byte
        if(r_cSum==(unsigned char)buffR_t[nbrOfBytes-2]){
            printGreen();
            printf("A message has been received! \n");
            printWhite();
            return 1;
        }
        else{
            return 0;
        }
}

是否有人能够发现我的错误(我几乎可以肯定至少有2个)?我很感激在这件事上有任何帮助! 最好的问候Henrik

2 个答案:

答案 0 :(得分:1)

 buff2s[strlen(buff2s)]=calculatedCS; //adds a checksum
 buff2s[strlen(buff2s)]='\0'; //adds a new string terminator

坏: - (

仅仅因为你的字符串有一个空终止符并不意味着它的空值一直都是空的。你的第一个&#39; strlen&#39;告诉你当前的结局。你用校验和覆盖了那个,但是新的终结符&#39;可能在任何地方。这样做。

 int len = strlen(buff2s);
 buff2s[len]=calculatedCS; //adds a checksum
 buff2s[len+1]='\0'; //adds a new string terminator

(理想情况下,检查缓冲区溢出......)

答案 1 :(得分:1)

正如@Roddy所指出的,代码不好用它用校验和覆盖字符串的\0,然后尝试在潜在未终止的字符串的下一行中找到字符串长度!

buff2s[strlen(buff2s)]=calculatedCS; //adds a checksum
buff2s[strlen(buff2s)]='\0'; //adds a new string terminator

推荐:

size_t len = strlen(buff2s);
calculatedCS = checkSum(buff2s, len);
buff2s[len] = calculatedCS; //adds a checksum
buff2s[++len] = '\0'; //adds a new string terminator
bytes_written=write(fd, buff2s, len + 1);  

自使用字符串以来,更改校验和生成器和检查器以确保它不会创建'\0'

unsigned char checkSum(char buff[], size_t nbrOfBytes){
    size_t ic;
    unsigned int t_cSum = 0;
    for (ic=0; ic<nbrOfBytes-1; ic++){
        t_cSum += buff[ic];
    }
    return (unsigned char) (t_cSum % 255 + 1);
}

RegularReceive()无效。建议通过fgetc()阅读,直到'\0'出现。 (或超时或缓冲区已满)。特别是以下内容很危险,因为我们不知道buffR'\0'结尾,而下一个函数是strlen(buffR)

bytes_read = read(fd, buffR, sizeof(buffR)-1);
if(strlen(buffR)<1){