Project

General

Profile

Работа с Ethernet (Си) » History » Version 15

krufter_multiclet, 04/22/2013 12:31 PM

1 1 krufter_multiclet
h1. Работа с Ethernet (Си) 
2 4 krufter_multiclet
3 4 krufter_multiclet
Рассмотрим простой пример по отправке одного пакета с заданным IP-адресом в виде широковещательной рассылки.
4 4 krufter_multiclet
Но сначала заметим, что настройка микросхемы, реализующей физический уровень Ethernet происходит программно.
5 4 krufter_multiclet
6 4 krufter_multiclet
На Си реализованы функции записи и чтения в регистры микросхемы, реализующей физический уровень Ethernet.
7 5 krufter_multiclet
8 5 krufter_multiclet
1) Функция записи в регистры PHY
9 5 krufter_multiclet
10 5 krufter_multiclet
<pre>
11 5 krufter_multiclet
void mdio_wr(int phy_addr, int reg, int data)
12 5 krufter_multiclet
</pre> 
13 5 krufter_multiclet
14 5 krufter_multiclet
phy_addr - адрес микросхемы PHY (по умолчанию 0x00)
15 5 krufter_multiclet
reg - номер регистра
16 5 krufter_multiclet
data - значение для установки в регистр
17 5 krufter_multiclet
18 5 krufter_multiclet
2) Функция чтения регистра PHY
19 5 krufter_multiclet
20 5 krufter_multiclet
<pre>
21 5 krufter_multiclet
int mdio_rd(int phy_addr, int reg)
22 5 krufter_multiclet
</pre>
23 5 krufter_multiclet
24 5 krufter_multiclet
phy_addr - адрес микросхемы PHY (по умолчанию 0x00)
25 5 krufter_multiclet
reg - номер регистра
26 5 krufter_multiclet
Функция возвращает 32 разрядное значение регистра
27 6 krufter_multiclet
28 6 krufter_multiclet
29 6 krufter_multiclet
Перейдём непосредственно к рассмотрению примеров отправки и приёма пакетов.
30 6 krufter_multiclet
31 7 krufter_multiclet
h2. а) Передача пакета по Ethernet
32 6 krufter_multiclet
33 9 krufter_multiclet
Перед передачей пакета необходимо учесть, что области размещения дескрипторов передачи и приёма должны быть 
34 10 krufter_multiclet
выравнены на 1 килобайт. Области памяти, содержащие данные для передачи или принятые данные должны быть
35 10 krufter_multiclet
выравнены на 4 байта.
36 8 krufter_multiclet
37 11 krufter_multiclet
h3. 1. Объявим переменные и массивы данных с выравниванием
38 11 krufter_multiclet
39 11 krufter_multiclet
<pre>
40 11 krufter_multiclet
    static unsigned char buf_tx_desc[2048];
41 11 krufter_multiclet
    static unsigned char buf_rx_desc[2048];
42 11 krufter_multiclet
    unsigned int buf_tx[400];
43 11 krufter_multiclet
    unsigned int buf_rx[400];
44 11 krufter_multiclet
    unsigned char *eth_tx_desc;
45 11 krufter_multiclet
    unsigned char *eth_rx_desc;
46 11 krufter_multiclet
    
47 11 krufter_multiclet
    eth_tx_desc=(unsigned char *)(((int)buf_tx_desc+1024)& ~(1024-1)); //указатель на область памяти дескрипторов передачи
48 11 krufter_multiclet
    eth_rx_desc=(unsigned char *)(((int)buf_rx_desc+1024)& ~(1024-1)); //указатель на область памяти дескрипторов приема
49 11 krufter_multiclet
</pre>
50 8 krufter_multiclet
 
51 6 krufter_multiclet
52 12 krufter_multiclet
2. Сформируем простую функцию передачи данных
53 12 krufter_multiclet
54 13 krufter_multiclet
<pre>
55 12 krufter_multiclet
void send_pack(unsigned int *buf_tx, int size, unsigned char *eth_tx_desc)
56 12 krufter_multiclet
{
57 12 krufter_multiclet
   int pre;
58 12 krufter_multiclet
   GPIOA->BPS = 0x0000FFFF; //разрешаем альтернативные функции порта для работы Ethernet
59 12 krufter_multiclet
   ETH->TDP = 0xE0200000 + (unsigned int)(eth_tx_desc); //задаём область размещения дескрипторов передачи
60 12 krufter_multiclet
   pre = 0xE0200000 + (unsigned int)buf_tx; //область размещения данных в ПД
61 12 krufter_multiclet
62 14 krufter_multiclet
   //переворачиваем pre из big endian в little endian и формируем вторую часть дескриптора передачи
63 12 krufter_multiclet
   eth_tx_desc[3] = (pre & 0xFF);
64 12 krufter_multiclet
   eth_tx_desc[2] = ((pre & 0xFF00)>>8);
65 12 krufter_multiclet
   eth_tx_desc[1] = ((pre & 0xFF0000)>>16);
66 12 krufter_multiclet
   eth_tx_desc[0] = ((pre & 0xFF000000)>>24);
67 1 krufter_multiclet
  
68 15 krufter_multiclet
   pre = (size & 0x3FF) + 0x1800; //первая часть дескриптора передачи EN+WP - "1"
69 14 krufter_multiclet
   
70 14 krufter_multiclet
   eth_tx_desc[7] = (pre & 0xFF);
71 14 krufter_multiclet
   eth_tx_desc[6] = ((pre & 0xFF00)>>8);
72 14 krufter_multiclet
   eth_tx_desc[5] = 0x00;
73 14 krufter_multiclet
   eth_tx_desc[4] = 0x00;
74 14 krufter_multiclet
   
75 15 krufter_multiclet
   ETH->CR = 0x00000001; //разрешаем передачу
76 14 krufter_multiclet
   while((ETH->CR & 1) != 0);
77 12 krufter_multiclet
}
78 13 krufter_multiclet
</pre>
79 12 krufter_multiclet
80 12 krufter_multiclet
81 12 krufter_multiclet
82 12 krufter_multiclet
83 6 krufter_multiclet
84 6 krufter_multiclet