2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 SNMP мониторинг
Сообщение18.06.2018, 06:13 
Здравствуйте. Видел много подобного на микроконтроллерах Arduino, но мне очень захотелось всё сделать вручную почти с нуля и создать следующую систему: микроконтроллер (МК), к которому подключены датчики (например, датчик температуры), сервер и программу (ПО), которую можно установить на свой ПК и мониторить по SNMP данные с датчиков (температуру).

Подскажите, с чего начать и какие тонкости важно учесть? Посоветуйте, пожалуйста, полезные материалы, которые можно изучить для осуществления цели или, возможно, существует похожий написанный пример (я имею в виду всё, кроме ПО).

Планирую использовать STM32.
Правильна ли следующая схема: ПО с частотой 1 раз/с отправляет запрос серверу, который берет значение из базы данных MIB? Как выглядит сам сервер: отдельная плата или можно использовать тот же МК? Как данные с датчика, которые поступили в МК, отправляются в MIB? Значение с датчика запрашивается независимо от запроса ПО или можно сделать, чтобы шел запрос от ПО и только тогда данные с датчика записывались в MIB и передавались на экран? Много ли нужно памяти: прийдётся ли подключать дополнительную?

 
 
 
 Re: SNMP мониторинг
Сообщение18.06.2018, 20:18 
Аватара пользователя
topSC в сообщении #1320706 писал(а):
Как выглядит сам сервер: отдельная плата или можно использовать тот же МК?

Не просто можно, а я бы сказал что нужно.
topSC в сообщении #1320706 писал(а):
Как данные с датчика, которые поступили в МК, отправляются в MIB?

MIB это очень громкое название. На самом деле это просто переменная с древовидной структурой или можете массивом оформить. Структуру дерева вы сами придумываете и по запросам клиентов пересылаете данные клиенту, по протоколу SNMP.

То есть в SNMP к вам приходит запрос в виде строка с позицией в дереве к примеру «.1.3.6.1.4.1.9.2.9.9.0». Вы по запросу находите элемент в дереве. И просто отсылаете этот элемент в обратную сторону к клиенту.

Для одного датчика кода немного. Сверить запрос с заранее заготовленным шаблоном и выдать ответ подставив в заготовку ответа измеренное значение с датчика. Для одного датчика у вас даже дерева не будет только одна переменная для позиции «.0».


topSC в сообщении #1320706 писал(а):
Значение с датчика запрашивается независимо от запроса ПО или можно сделать, чтобы шел запрос от ПО и только тогда данные с датчика записывались в MIB и передавались на экран?

Лучше независимо - но я думаю для вас это пока трудно.

(Оффтоп)

Давно хотел написать о плюсах SNMP https://yadi.sk/i/wdXLMzhH3Y5Ykj не судите строго написал как говорят на одном дыхании и можно более детально развернуть ответ.

 
 
 
 Re: SNMP мониторинг
Сообщение19.07.2018, 18:20 
Pavia, спасибо за ответ. Я перешел к практической реализации, поэтому изложу, что именно пока сделал. Спойлер: я настроил IDE, протестил железо, осталось только код написать.

У меня Windows 7 x64, STM32F401RE Nucleo и Arduino Ethernet Shield W5100. Пункты 0,1,2,3 и 21,22 нужно выполнить именно в порядке их номера, так как бывают проблемы. Остальные уже по логике.

Настройка Eclipse IDE
0. Установил JDK (jdk-8u172)
1. Установил Eclipse: скопировал в C:\STM32Toolchain
2. В Eclipse Help -> Install new software -> CDT -> CDT Main Features (Если нет в списке, то Add -> CDT http://download.eclipse.org/tools/cdt/releases/9.5)
3. Help -> Install new software -> Add -> GNU ARM Eclipse Plug-ins http://gnuarmeclipse.sourceforge.net/updates
4. Скачал gcc-arm-none-eabi-7-2018-q1-update-win64.exe и установил в C:\STM32Toolchain\gnu-arm\
5. Скачал Build tools и установил в C:\STM32Toolchain\Build Tools
6. В Eclipse File -> New -> C Project -> Hello World ARM Cortex-M C / C ++ -> Flash 512 -> RAM 96 -> Use sys calls Freestanding -> Trace output None -> Vendow CMSIS name stm32f4xx -> Имя GNU Tools для ARM Embedded Processors (arm-none-eabi-gcc) -> C:\STM32Toolchain\gnu-arm\…\bin
7. Извлёк STM32Cube в C:\STM32Toolchain и переименовал в STM32Cube_FW_F4
8. В проекте Eclipse удаляем
/system/include/cmsis/[stm32f4xx.h,system_stm32f4xx.h]
/system/src/cmsis/[system_stm32f4xx.c,vectors_stm32f4xx.c]
9. Из STM32Cube_FW_F4/Drivers/CMSIS/Device/ST/STM32F4xx/Include всё копируем в Eclipse /system/include/cmsis
10. Из STM32Cube_FW_F4/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc копируем startup_stm32f401xe.s в Eclipse /system/src/cmsis и переименуем в startup_stm32f401xe.S (большая S в расширении)
11. Из STM32Cube_FW_F4/Drivers/CMSIS/Device/ST/STM32F4xx/Source/Templates копируем system_stm32f4xx.c в Eclipse /system/src/cmsis
12. Window -> Preferences -> C/C++ -> Build -> Environment -> Add -> Path в "Name" и C:\STM32Toolchain\Build Tools;${Path} в "Value" -> "OK" -> "Apply".
13. Eclipse -> Project -> Properties -> C/C++ Build -> Settings -> Tool Settings -> Cross ARM C Compiler -> Preprocessor -> Add -> макрос STM32F401xE
14. Eclipse -> /Idscripts/mem.Id меняем адрес внутренней памяти и сохраняем
Используется синтаксис C
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K

Подключим библиотеки Wiz-Net для работы STM32 с Ethernet W5100 и проверим всё в тестовом скетче.

15. ioLibrary распакуем, переименуем в ioLibrary_Driver и копируем в проект Eclipse. Правой кнопкой мыши на ioLibrary_Driver -> Resource Configurations -> Exclude from builds -> выключаем Debug и Release
16. Project -> Properties -> C/C++ Build -> Settings -> Cross ARM C Compiler -> Includes -> Add ->
"../ioLibrary_Driver/Ethernet"
"../ioLibrary_Driver/Ethernet/W5100"
Apply and Close
17. … -> Cross ARM C++ Compiler -> Includes -> … (повторяем)
18. Открываем ioLibrary_Driver/Ethernet/wizchip_conf.h -> заменяем и сохраняем
  1. #define _WIZCHIP_ W5100 // W5100, W5100S, W5200, W5300, W5500 

Рассмотрим TCP-сервер, который принимает соединения на порту 5000. Каждый раз, когда соединение устанавливается с удаленным одноранговым узлом, оно отправляет приветственное сообщение в сокет и автоматически закрывает соединение. Это просто тестовая программа, которая позволяет нам проверить, работает ли Arduino Ethernet Shield.

19. Удаляем старые и копируем новые файлы из TCP server в проект, а именно
src/..files..
system/src/stm32f4xx/..files.. (нужно удалить файлы вида ***template.c)
system/include/stm32f4xx/..files.. (нужно удалить файлы вида ***template.c)
include/..files..
20. Если работаем в старом проекте или его копии, то удаляем Debug. И вообще всегда удаляем Debug перед сборкой, так как случаются страшные глюки.
Project -> Build project Ошибок быть не должно.

Работа с железом
21. Установил ST Link drivers for STM32Nucleo board (009, затем 007 - тут нужно подключить плату)
22. Установил ST-Link Utility, подключил плату, проверил, что она корректно обнаруживается (Target -> Connect)
23. Втыкаем Arduino Ethernet Shield в STM32 Nucleo. Затем подключаемся коннекторами:
Arduino ICSP PIN 1 (MISO) to Nucleo PIN PB_14
Arduino ICSP PIN 4 (MOSI) to Nucleo PIN PB_15
Arduino ICSP PIN 3 (SCK) to Nucleo PIN PB_13
Arduino D10 PIN (SS) to Nucleo PIN PB_12

Есть одна тонкость: у меня китайская реплика Arduino Ethernet Shield W5100 и при подключении патч корда напрямую к компьютеру он может просто не заработать (припаян резистор в 10 раз больше нужного - в интернете куча тем по этому вопросу). Поэтому я подключаюсь к своему маршрутизатору (фирма Tenda).

24. В main.c меняем настройки сети. Мой маршрутизатор работает в диапазоне 192.168.0.100 - 192.168.0.200 (пропишите свободный для Arduino), маска 255.255.255.0, а его адрес 192.168.0.1. MAC адрес для Arduino выбирается случайно (можно не менять, а можно свой придумать). Соответственно, мои настройки такие:
Используется синтаксис C
wiz_NetInfo netInfo = { .mac  = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}, // Mac address
                          .ip   = {192, 168, 0, 107},                   // IP address
                          .sn   = {255, 255, 255, 0},                   // Subnet mask
                          .gw   = {192, 168, 0, 1}};                    // Gateway address

Если же вы подключились к компу, то нужно вручную прописать в IPv4, например, 192.168.0.105.
25. ST-Link Utility -> Target -> Program & Verify -> C:\STM32Toolchain\projects\test2\Debug\W5100_test.hex -> Start
26. Проверим, пингуется ли: cmd -> ping 192.168.0.107 Должны идти пакеты!
27. Проверяем TCP-сервер: откройте Telnet и напишите open 192.168.0.107 5000

Если всё ok, то увидим следующее:
Well done guys! Welcome to the IoT world. Bye!
Подключение к узлу утеряно.
Нажмите любую клавишу...

Ещё добавлю несколько аналоговых датчиков, а так уже можно переходить к написанию snmp агента.

Pavia в сообщении #1320912 писал(а):
Для одного датчика кода немного.
У меня будет порядка 10 датчиков. Я ещё не начинал писать код, но заранее хочу спросить: есть ли готовый пример, чтобы на нём тренироваться и просто модернизировать?

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

-- 19.07.2018, 17:44 --

О плюсах SNMP очень интересно и познавательно!
Цитата:
...грамотный разработчик не дожидается падения программы или косяков он использует принципы защищенного программирования. И выносит все неизвестные параметры во внешний файл. И прокидывает SNMP для горячей замены этих параметров. Выглядит это довольно круто.
Расскажите, пожалуйста, подробнее.

-- 19.07.2018, 18:07 --

topSC в сообщении #1327679 писал(а):
19. Удаляем старые и копируем новые файлы из TCP server в проект, а именно
src/..files..
system/src/stm32f4xx/..files.. (нужно удалить файлы вида ***template.c)
system/include/stm32f4xx/..files.. (нужно удалить файлы вида ***template.c)
include/..files..
Откровенно говоря, жирные файлы правильнее скопировать изначально из STM32Cube_FW_F4/Drivers/STM32F4xx_HAL_Driver/[Src, Inc]. Но тогда вылетает куча ошибок. Я не разобрался, почему так происходит, но написал письмо Carmine Noviello, который делится всем этим механизмом настройки IDE и т.д. в своём блоге. Надеюсь, он прояснит ситуацию.

 
 
 
 Re: SNMP мониторинг
Сообщение19.07.2018, 22:32 
Как я понял, все необходимые мне инструменты находятся в папке ioLibrary_Driver/Internet/SNMP
Лучше их корректировать или просто по кусочкам копировать в main.c?
У меня в c/c++ мало практики, поэтому на данном этапе я просто пытаюсь понять в какой очередности и какие функции должны быть использованы.
Подключаем ethernet модуль
код: [ скачать ] [ спрятать ]
Используется синтаксис C
int main(void)
{
  uint8_t retVal, sockStatus;
  int16_t rcvLen;
  uint8_t rcvBuf[20], bufSize[] = {2, 2, 2, 2};

  HAL_Init();
 
  /* Configure the System clock to 84 MHz */
  SystemClock_Config();
 
  MX_GPIO_Init();
  MX_SPI2_Init();
  MX_USART2_UART_Init();

  PRINT_HEADER();

  reg_wizchip_cs_cbfunc(cs_sel, cs_desel);
  reg_wizchip_spi_cbfunc(spi_rb, spi_wb);

  wizchip_init(bufSize, bufSize);
  wiz_NetInfo netInfo = { .mac  = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}, // Mac address
                          .ip   = {192, 168, 0, 107},                                   // IP address
                          .sn   = {255, 255, 255, 0},                                   // Subnet mask
                          .gw   = {192, 168, 0, 1}};                                    // Gateway address
  wizchip_setnetinfo(&netInfo);
  wizchip_getnetinfo(&netInfo);
  PRINT_NETINFO(netInfo);
 

Затем нужно запустить агент и по кругу считывать данные, вроде бы. Пытаюсь понять, куда OIDы, но ещё не достаточно, наверное, медитировал.
код: [ скачать ] [ спрятать ]
Используется синтаксис C
dataEntryType snmpData[] =
{
    // System MIB
        // SysDescr Entry
        {8, {0x2b, 6, 1, 2, 1, 1, 1, 0},
        SNMPDTYPE_OCTET_STRING, 30, {"WIZnet Embedded SNMP Agent"},
        NULL, NULL},

        // SysObjectID Entry
        {8, {0x2b, 6, 1, 2, 1, 1, 2, 0},
        SNMPDTYPE_OBJ_ID, 8, {"\x2b\x06\x01\x02\x01\x01\x02\x00"},
        NULL, NULL},

        // SysUptime Entry
        {8, {0x2b, 6, 1, 2, 1, 1, 3, 0},
        SNMPDTYPE_TIME_TICKS, 0, {""},
        currentUptime, NULL},

        // sysContact Entry
        {8, {0x2b, 6, 1, 2, 1, 1, 4, 0},
        SNMPDTYPE_OCTET_STRING, 30, {"http://www.wizwiki.net/forum"},
        NULL, NULL},

        // sysName Entry
        {8, {0x2b, 6, 1, 2, 1, 1, 5, 0},
        SNMPDTYPE_OCTET_STRING, 30, {"http://www.wiznet.co.kr"},
        NULL, NULL},

        // Location Entry
        {8, {0x2b, 6, 1, 2, 1, 1, 6, 0},
        SNMPDTYPE_OCTET_STRING, 30, {"4F Humax Village"},
        NULL, NULL},

        // SysServices
        {8, {0x2b, 6, 1, 2, 1, 1, 7, 0},
        SNMPDTYPE_INTEGER, 4, {""},
        NULL, NULL},

        // OID Test #1 (long-length OID example, 19865)
        {0x0a, {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x9b, 0x19, 0x01, 0x00},
        SNMPDTYPE_OCTET_STRING, 30, {"long-length OID Test #1"},
        NULL, NULL},

        // OID Test #2 (long-length OID example, 22210)
        {0x0a, {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0xad, 0x42, 0x01, 0x00},
        SNMPDTYPE_OCTET_STRING, 35, {"long-length OID Test #2"},
        NULL, NULL},

        // OID Test #2: SysObjectID Entry
        {0x0a, {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0xad, 0x42, 0x02, 0x00},
        SNMPDTYPE_OBJ_ID, 0x0a, {"\x2b\x06\x01\x04\x01\x81\xad\x42\x02\x00"},
        NULL, NULL},
};
 

Что тут за что отвечает?

 
 
 [ Сообщений: 4 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group