Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Кармин Новиелло - Освоение STM32.pdf
Скачиваний:
2739
Добавлен:
23.09.2021
Размер:
47.68 Mб
Скачать

Разработка IoT-приложений

726

Чтобы отключиться от удаленного узла, мы можем воспользоваться функцией:

 

int8_t disconnect(uint8_t sn);

Если мы, наоборот, собираемся создать серверное приложение, то после того, как сокет будет сконфигурирован с помощью функции socket(), мы можем перевести его в режим прослушивания с помощью функции:

int8_t listen(uint8_t sn);

Как только соединение установлено, мы можем получать и отправлять данные с помо-

щью функций recv() и send().

26.2.2.2. Управление сокетами в режиме UDP

UDP – это сетевой протокол передачи без установления соединения, поэтому нам не нужно явно создавать подключения, чтобы начать обмен байтами с удаленным узлом.

Чтобы отправить массив байтов удаленному узлу, когда сокет находится в режиме UDP, мы можем воспользоваться функцией:

int32_t sendto(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port);

в то время как для получения байтов от удаленного узла мы можем воспользоваться функцией:

int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port);

26.2.3. Перенаправление ввода-вывода на сокет TCP/IP

В Главе 8 мы увидели, как перенаправить функции Си ввода-вывода терминала, такие как printf() и scanf(), на интерфейс UART. Во время разработки IoT-приложений очень удобно перенаправить ввод-вывод на сетевой сокет, чтобы мы могли отлаживать наше устройство через сетевое соединение. Это действительно полезно, особенно если устройство не находится под нашим прямым контролем.

Данная операция достаточно проста при использовании микросхемы W5500 и соответствующей библиотеки сокетов. Функцию RetargetInit() можно переписать следующим образом:

Имя файла: system/src/retarget/retarget-tcp.c

12 #ifdef RETARGET_TCP

13

14#define STDIN_FILENO 0

15#define STDOUT_FILENO 1

16#define STDERR_FILENO 2

18#ifndef RETARGET_PORT

19#define RETARGET_PORT 5000

20#endif

errno = EBADF;

Разработка IoT-приложений

727

22 int8_t gSock = -1;

23

24uint8_t RetargetInit(int8_t sn) {

25gSock = sn;

26

27/* Отключение буферизации ввода-вывода для потока STDOUT,

28* чтобы символы отправлялись сразу после печати. */

29setvbuf(stdout, NULL, _IONBF, 0);

30

31/* Открытие сокета sn в режиме TCP с номером порта,

32* равным значению макроса RETARGET_PORT */

33if(socket(sn, Sn_MR_TCP, RETARGET_PORT, 0) == sn) {

34if(listen(sn) == SOCK_OK)

35return 1;

36}

37return 0;

38}

Код действительно говорит сам за себя. Функция RetargetInit() принимает номер сокета, который для микросхемы W5500 находится в диапазоне от 0 до 7. Функция таким образом конфигурирует сокет и переводит его в режим прослушивания. Функцию _write() можно перестроить следующим образом:

Имя файла: system/src/retarget/retarget-tcp.c

48int _write(int fd, char* ptr, int len) {

49int sentlen = 0;

50int buflen = len;

51

52if(getSn_SR(gSock) == SOCK_ESTABLISHED) {

53if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {

54while(1) {

55sentlen = send(gSock, (void*) ptr, buflen);

56if (sentlen == buflen)

57return len;

58else if (sentlen > 0 && sentlen < buflen) {

59buflen -= sentlen;

60ptr += (len - buflen);

61}

62else if (sentlen < 0)

63return EIO;

64}

65}

66} else if(getSn_SR(gSock) != SOCK_LISTEN) {

67/* Удаленный узел закрыл соединение? */

68close(gSock);

69RetargetInit(gSock);

70}

71

72