2014-03-06 115 views
1

我試圖從USB到串口轉換器發送帶校驗和的消息並返回。 但我不能讓它工作出於某種原因,即使艱難,我已經嘗試了一個洞天。我開始認爲硬件出了問題,但我認爲在放棄之前先問問你們是個好主意......我正在使用cygwin在Windows計算機上執行和編譯程序。校驗和串口通信

我希望在程序運行時附上終端的圖片,但是您必須具有> 10的聲望,而我不是:(所以我將不得不描述它。 。 我收到來自終端的以下信息,當我嘗試發送「A」

輸入消息:一
校驗你的信息發送是:97
您的郵件發送是:一個
a @
收到消息的校驗和爲:97
消息不是pr妥善收到!
您收到以下內容: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)?我很感謝在這件事情上的任何幫助! 最好的問候亨利克

+0

意見:如果要添加校驗碼,請考慮使用32位CRC校驗碼而不是簡單的校驗和。字節校驗和在256個校驗和錯誤中未能表示一次錯誤。我更喜歡40億分之一的失敗率。 CRC還會檢查更多類型的錯誤,例如添加/缺少'\ 0'。 – chux

回答

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){ 
1
buff2s[strlen(buff2s)]=calculatedCS; //adds a checksum 
buff2s[strlen(buff2s)]='\0'; //adds a new string terminator 

壞:-(

僅僅因爲你的字符串中有一個空終止並不意味着它是空值超出了所有的方式,你的第一個「strlen的」告訴您當前到底是您覆蓋與校驗,但在「新終結者」雲可能在任何地方,而是執行此操作。

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

(理想情況下,檢查緩衝區溢出,以及...)