Jump to content

    

Передача структуры по Ethernet (STM32F407)

Здравствуйте. На просторах интернета нашел старый пример реализации передачи Ethernet пакета с использованием DMA. В нем производится запись и передача значений 0x01 и 0x02. Код программы:

 

#include "stm32f40x.h"
#include "stm32_eth.h"
#include <stdio.h>
#include "delay.h"

//PHY_ADDRESS
#define PHY_ADDRESS       0x01F /* PHY_ADDRESS TE-STM32F407 Board */ 
#define RMII_MODE          /*MII mode or RMII mode*/

#define MY_MAC_ADD_0 0x33
#define MY_MAC_ADD_1 0x35
#define MY_MAC_ADD_2 0x43
#define MY_MAC_ADD_3 0x38
#define MY_MAC_ADD_4 0xF3
#define MY_MAC_ADD_5 0xA3


#define ETH_RXBUFNB        8 
#define ETH_TXBUFNB        2 

ETH_InitTypeDef ETH_InitStructure;
ETH_DMADESCTypeDef  DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB];
u8 Rx_Buff[ETH_RXBUFNB][ETH_MAX_PACKET_SIZE], Tx_Buff[ETH_TXBUFNB][ETH_MAX_PACKET_SIZE]; 

int main(void)
{
SysTick_Config(SystemCoreClock/1000);
RCC_Configuration();
NVIC_Configuration();
GPIO_PinRemapConfig(GPIO_Remap_ETH, DISABLE); 
GPIO_ETH_MediaInterfaceConfig(GPIO_ETH_MediaInterface_MII);
RCC->CFGR |= RCC_CFGR_MCO_HSE;
GPIO_Configuration();
  
 ETH_DeInit();
 ETH_SoftwareReset();
 while(ETH_GetSoftwareResetStatus()==SET);

 ETH_StructInit(&ETH_InitStructure);
 /*------------------------   MAC   -----------------------------------*/
 ETH_InitStructure.ETH_AutoNegotiation = ETH_AutoNegotiation_Enable ;  
 ETH_InitStructure.ETH_Speed = ETH_Speed_100M;                                      
 ETH_InitStructure.ETH_LoopbackMode = ETH_LoopbackMode_Disable;
 ETH_InitStructure.ETH_Mode = ETH_Mode_FullDuplex;
 ETH_InitStructure.ETH_RetryTransmission = ETH_RetryTransmission_Disable;
 ETH_InitStructure.ETH_AutomaticPadCRCStrip = ETH_AutomaticPadCRCStrip_Disable;  
 ETH_InitStructure.ETH_ReceiveAll = ETH_ReceiveAll_Enable;
 ETH_InitStructure.ETH_BroadcastFramesReception = ETH_BroadcastFramesReception_Disable;      
 ETH_InitStructure.ETH_PromiscuousMode = ETH_PromiscuousMode_Disable;
 ETH_InitStructure.ETH_MulticastFramesFilter = ETH_MulticastFramesFilter_Perfect; 
 ETH_InitStructure.ETH_UnicastFramesFilter = ETH_UnicastFramesFilter_Perfect; 
 /* Configure ETHERNET */
 Value = ETH_Init(&ETH_InitStructure, PHY_ADDRESS);
 
 /* Initialize Tx Descriptors list: Chain Mode */
 ETH_DMATxDescChainInit(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
 /* Initialize Rx Descriptors list: Chain Mode  */
 ETH_DMARxDescChainInit(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);

 //Разрешаем прием
 DMARxDscrTab -> Status = ETH_DMARxDesc_OWN;
 
 /* Enable MAC and DMA transmission and reception */
 ETH_Start();  

while(1)
{
    TransmitPacket();
}

}

Функция TransmitPacket:
 

void TransmitPacket(void)
{
if ((DMATxDscrTab->Status & ETH_DMARxDesc_OWN)==0)
{    
            //Сначала отключаем передачу
            ETH_DMATransmissionCmd(DISABLE);
        
                        Tx_Buff[0][20] = 0x01;
                        Tx_Buff[0][21] = 0x02;

            //отдаем дескриптор в руки DMA Ethernet
            DMATxDscrTab -> Status = ETH_DMARxDesc_OWN | ETH_DMATxDesc_TCH | ETH_DMATxDesc_TTSE |
                        ETH_DMATxDesc_LS | ETH_DMATxDesc_FS;
                        
                        //разрешаем отправку
            ETH_DMATransmissionCmd(ENABLE);

}

Возможно ли по такой же схеме передать структуру? То есть чтобы в анализаторе пакетов было нечто подобное:

gg.JPG.7aacda986782b21c117d896a1045c5df.JPG

 

Кусок этой структуры сформировал, но как засунуть её в пакет не понимаю.

struct APDU {
2     int8_t savPDU_tag;
3     int8_t savPDU_length; // razmer APDU
4     int8_t noASDU_tag;
5     int8_t noASDU_length; // razmer noASDU
6     int8_t noASDU;
7     int8_t SequenceofASDU_tag;
8     int8_t SequenceofASDU_length; // razmer vseh ASDU
9     struct ASDU_LE ASDU1;
10 };

 

Share this post


Link to post
Share on other sites

Я так не делал но вот моё имхо:

Ваша структура это набор данных в памяти начиная с какого-то адреса , массив тоже самое.Нужно взять указатель на структуру, определить длину структуры в памяти и поэлементно скопировать в транспортный массив всю структуру в цикле, как будто она массив в памяти.

Share this post


Link to post
Share on other sites
9 minutes ago, Lmx2315 said:

Я так не делал но вот моё имхо:

Ваша структура это набор данных в памяти начиная с какого-то адреса , массив тоже самое.Нужно взять указатель на структуру, определить длину структуры в памяти и поэлементно скопировать в транспортный массив всю структуру в цикле, как будто она массив в памяти.

А при этом на выходе в анализаторе получится просто упорядоченный набор цифр, или же именно набор параметров + их значения?

То есть я не совсем понимаю существует ли вообще возможность передачи именно структуры, или же указывая в Ethertype (тип Ethernet пакета) конкретное интересующее значение она формируется автоматически, а дальше, как вы и сказали, с учетом длины нужно поэлементно передать численные значения, а они сами автоматически присвоются параметрам по порядку?

Share this post


Link to post
Share on other sites
12 минут назад, remixx сказал:

А при этом на выходе в анализаторе получится просто упорядоченный набор цифр, или же именно набор параметров + их значения?

Вы считаете что в структуре хранятся названия переменных? Если да то вы ошибаетесь. В структуре просто лежат ваши данные и всё. И выдаваться будут ваши данные.

Причём они могут выдаваться ещё и не так как вы ожидаете а в перевёрнутом виде -  почитайте в интернете https://ru.wikipedia.org/wiki/Порядок_байтов

12 минут назад, remixx сказал:

То есть я не совсем понимаю существует ли вообще возможность передачи именно структуры, или же указывая в Ethertype (тип Ethernet пакета) конкретное интересующее значение она формируется автоматически, а дальше, как вы и сказали, с учетом длины нужно поэлементно передать численные значения, а они сами автоматически присвоются параметрам по порядку?

Ну если у вас приём и передача идёт на схожие устройства которые одинаково понимают расположение данных в памяти, то можно было бы сделать функции которые принимают указатель на структуру и в таком виде её и передают , а на приёме ожидают именно эту структуру и именно её и выдают. Но у вас же есть промежуточное звено ввиде транспортного массива и вы хотите передавать через него.

Share this post


Link to post
Share on other sites

С этого надо начинать

C4D.jpg.6a0debcca65d943cb1b74a0c760fdc4e.jpg

Share this post


Link to post
Share on other sites
1 час назад, remixx сказал:

То есть я не совсем понимаю существует ли вообще возможность передачи именно структуры,

Существует: json. Но это гораздо сложнее, чем просто запихнуть пакет в ethernet, как хотите вы.

Share this post


Link to post
Share on other sites

Похоже, что ТС увидел как WireShark распарсил принятый пакет как IEC61850 и захотел заполнить поля данного протокола своими значениями.

Share this post


Link to post
Share on other sites

1) Чтобы структура попала в пакет можно использовать стандартную функцию memcpy(buf + смещение, var_APDU, sizeof(APDU));

2) Компилятор может "раздуть" структуру и при memcpy попадет не то что нужно. Нужно вставлять что-то типа #pragma pack(1).

3) u8 Tx_Buff - тут тоже может быть засада. DMA обычно требует выравнивание на 4 байта. Лучше объявить буфер в виде long или #pragma align

4)Ну и найти собственно функцию которая составляет/вставляет в пакет остальные требуемые поля - MAC, IP, порты, длины передачи, CRC и т.д. в соотвествии с ваши TCP или UDP

Share this post


Link to post
Share on other sites
9 часов назад, x893 сказал:

С этого надо начинать

Не совсем, с книги передачи данных, стандартных протоколов и методов...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now