Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

modbus TCP yardım

Başlatan magnetron, 06 Ekim 2023, 14:38:14

magnetron

merhaba forum,

modbus TCP kullanarak STM32F4' ten MACH3 CNC programına bağlanmaya çalışıyorum
tokalaşma kısmını yaptım

ama data gönderme kısmını yapamadım

mach 3 den test amaçlı 16 nolu function code (write - 2 word) gönderiyorum
mesaj gidiyor LEDi yakıyor ama
mach 3 gönderdiğim responsu bir türlü beğenmiyor receive timout veriyor
simplymodbus 'un tcp client programı da responsu kabul etmiyor - 5 gündür uğraşıyorum

TCP header içinde pseudo CRC denilen bir alan var
bundan şüpheleniyorum

response ve pseudo CRC kodunu ve wireshark görüntüsünü ekliyorum

yardım ederseniz sevinirim - nereye bakıyım, döküman tavsiyenizi bekliyorum - teşekkür

void MAC_Send_PDU_Response(void){

    unsigned int i = 0,len=0;
    unsigned int ipcrc = 0;
//    unsigned long fcs=0;


        for(i = 0; i < 6; i++){
            netConfig.RemoteMACAddress[i]=uip_buf[6+i];
            ethOutputBuffer[i] = netConfig.RemoteMACAddress[i];
            ethOutputBuffer[i+6] = netConfig.LocalMACAddress[i];
        }

        ethOutputBuffer[12] = ETHTYPE_IP_HIGH;                        //IP Ethernet Type
        ethOutputBuffer[13] = ETHTYPE_IP_LOW;                            //IP Ethernet Type

        ethOutputBuffer[14] = IP_VHL;
        ethOutputBuffer[15] = IP_TOS;
        ethOutputBuffer[16] = (char)( (IP_HEADER_LEN + TCPSYNACK_HEADER_LEN +12/*+ TCPOPTION_LEN*/) >> 8 );    //len high
        ethOutputBuffer[17] = (char)( (IP_HEADER_LEN + TCPSYNACK_HEADER_LEN +12/*+ TCPOPTION_LEN*/) );            //len low
        ethOutputBuffer[18] = IP_ID_HIGH;
        ethOutputBuffer[19] = IP_ID_LOW;
        ethOutputBuffer[20] = IP_OFFSET_HIGH;
        ethOutputBuffer[21] = IP_OFFSET_LOW;
        ethOutputBuffer[22] = IP_TTL;
        ethOutputBuffer[23] = IP_PROTO_TCP;
                                                                                                        //warning! must be zero before calc
        ethOutputBuffer[24] = 0;                                                //ip chksum addrs high
        ethOutputBuffer[25] = 0;                                                //ip chksum addrs low

        for(i = 0; i < 4; i++){
            ethOutputBuffer[26+i] = netConfig.LocalIPAddress[i];
            netConfig.RemoteIPAddress[i]=uip_buf[26+i];
            ethOutputBuffer[30+i] = netConfig.RemoteIPAddress[i];
        }

        ethOutputBuffer[34] = 0x1;//
        ethOutputBuffer[35] = 0xf6; //    port 502

        ethOutputBuffer[36] = uip_buf[34];//
        ethOutputBuffer[37] = uip_buf[35];//    remote port

        uint32_t *seqnmbr = &ethOutputBuffer[38], *inseqnmbr =&uip_buf[38];
        uint32_t *acknmbr = &ethOutputBuffer[42], *inacknmbr = &uip_buf[42];

        uint32_t dummy;
        dummy=bigtolitle(inseqnmbr)+12;
        *seqnmbr = bigtolitle(&dummy);
        dummy=bigtolitle(inseqnmbr)+17;
        *acknmbr = bigtolitle(&dummy);

        ethOutputBuffer[46] = 0x50;
        ethOutputBuffer[47] = 0x18; // PSH | ACK
        ethOutputBuffer[48] = 0X05;        // window
        ethOutputBuffer[49] = 0x78;
        ethOutputBuffer[50] = 0;
        ethOutputBuffer[51] = 0;        // checksum
        ethOutputBuffer[52] = 0;        // urgent
        ethOutputBuffer[53] = 0;

        ipcrc = MAC_CalculateCRC(IP_HEADER_LEN, &ethOutputBuffer[14]);
        ethOutputBuffer[24] = (char)(ipcrc >> 8);                                                        //ip chksum addrs high
        ethOutputBuffer[25] = (char)ipcrc;                                                                    //ip chksum addrs low

//        MBAP HEADER
        ethOutputBuffer[54]= uip_buf[54];    //Transaction Identifier
        ethOutputBuffer[55]= uip_buf[55];

        ethOutputBuffer[56]= 0x00;            // Protocol Identifier
        ethOutputBuffer[57]= 0x00;

        ethOutputBuffer[58]= 0;//
        ethOutputBuffer[59]= 6;//        Length Field

        ethOutputBuffer[60]= uip_buf[60];    //unit id
        ethOutputBuffer[61]= 0x10;            // function code

        ethOutputBuffer[62]= uip_buf[62];        // data field
        ethOutputBuffer[63]= uip_buf[63];

        ethOutputBuffer[64]= uip_buf[64];        // data field
        ethOutputBuffer[65]= uip_buf[65];

//        len = (uint16_t)uip_buf[58]<<8 | (uint16_t)uip_buf[59];

//        for (i=0;i<len;i++) ethOutputBuffer[60+i]= uip_buf[60+i];

        ipcrc = MAC_TCP_Pseudo_CRC(20 ,12);
        ethOutputBuffer[50] = (char)(ipcrc >> 8);
        ethOutputBuffer[51] = (char)ipcrc;

        memcpy(&uip_buf[0],&ethOutputBuffer[0], 60 + 6);//copy string
        tapdev_send(uip_buf,60 + 6);

}


/ Network  UDP Pseude CRC ************************************************************************
unsigned int MAC_TCP_Pseudo_CRC(uint16_t headerl, unsigned int gdatalen)
{
        unsigned char ethpseudo[100];
        unsigned char i = 0;
        unsigned int crc=0;

        for(i = 0; i < 4; i++){
            ethpseudo[i] = ethOutputBuffer[26+i];                    //local ip
            ethpseudo[4+i] = ethOutputBuffer[30+i];                //remote ip
        }

        ethpseudo[9] = 6 + headerl+gdatalen;                                    //null
        ethpseudo[8] = 0;

        for(i = 0; i < headerl+gdatalen ; i++){
            ethpseudo[10+i] = ethOutputBuffer[34+i];
        }

        crc = MAC_CalculateCRC(10 + headerl+gdatalen , &ethpseudo[0]);

        return crc;
}



magnetron

#1
yukardaki checksum hesaplaması tamamen yanlışmış
RFC ve stackoverflow dan okuduklarımla checksum kısmını çözdüm

ama gene MACH3 ile haberleşme sorunum var
modbus write komutu verince MACH3 receive timeout alarmı veriyor yani benim responsumu beğenmiyor

şu anda sequence number ve acknowledgement number dan şüpheleniyorum
bunları da internetten bulduğum gibi yaptım ama sorun devam ediyor

acaba bunların nasıl set edileceği hakkında iyi bir döküman biliyor musunuz

bir de response içinde bu SYN ACK gibi flaglerin hangisi set olucak bilginiz var mı

teşekkür