|
|
  |
FreeModbus |
|
|
|
Mar 7 2011, 16:50
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(alux @ Mar 7 2011, 14:47)  Еще для полного счастья нужно использовать функции для записи\чтения битов ForceSingleCoil (0x05), ReadSingleCoil(0x01). Приведите, пожалуйста, пример с использованием этих функций. Флаги, битовое поле в области ввода-вывода ниже 0x1f. А какой гешефт их так описывать? При адресации можно использовать offsetof()/8, биты задавать перечислениями. Получится Код extern #ifdef CORE_32 #define CORE_WD 32 char #else #define CORE_WD 8 int #endif mb_coils[]; enum coils {foo,bar}; static inline bool coil_r(enum coils coil); static inline void coil_w(enum coils coil , bool val); bool coil_r(enum coils coil) { return (mb_coils[coil / CORE_WD] & (1 << coil & (CORE_WD-1)))?true:false; }
|
|
|
|
|
Mar 20 2011, 21:37
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
При использовании функции 0x10 PresetMultipleRegisters запрос от мастера идет как положено (проверяю в Serial Port Monitor), а ответа от слева не поступает. Функция 0x06 PresetSingleRegister работает как положено. В mbconfig.h функция 0x10 разрешена : Код #define MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED ( 1 ) В чем может быть проблема?
|
|
|
|
|
Mar 21 2011, 07:09
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
как выяснилось, проблема не в этой функции (0x10), а в адресе регистров, в которые нужно писать. У меня регистры (переменные типа int) упакованы в структуру : Код typedef struct { int NumSensorsDS; int TemperatureTC[NUM_SENSORS]; int Parameter[2][NUM_SENSORS]; int Temperature[2]; int NumSensorsTC; int Cable; int Average; int Data; long Accum; }TValue; В регистры Cable, Average записываются значения и отдается нормальный ответ от устройства при помощи ф-ций PresetSingleRegister,PresetMultipleRegisters, а если указать адрес записываемого регистра в NumSensorsTC, то запрос остается без ответа. Почему, не пойму никак?.. PS. Callback-функции написаны и работают. PS2. Вроде нашел... В Callback-функции использую ф-ции записи во флеш. Код WriteFlashByte(FLASH_PARAMETER_LOCATION + 2 + 1, *(pucRegBuffer)); WriteFlashByte(FLASH_PARAMETER_LOCATION + 2, *(pucRegBuffer + 1)); Если закоментировать эти строки, то ответ нормальный появляется. Наверно, правильно сделать так : в колбэк-функции устанавливать флаг, а в главном цикле по этому флагу писать во флеш.
|
|
|
|
|
May 14 2011, 09:03
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 31-08-10
Из: Минск-Витебск
Пользователь №: 59 203

|
Цитата который адресован ему и имеет правильный CRC, но не имеет ни функции, ни данных Если вместо функции и данных просто нули, то при проверки кода функции, если он данную ф-цию не поодерживает, должен вернуть ошибку с номером 1 (ILLEGAL FUNCTION).
|
|
|
|
|
May 17 2011, 05:04
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 31-08-10
Из: Минск-Витебск
Пользователь №: 59 203

|
По хорошему проверка должна идти в следующей очередности: 1. Длина пакета 2. CRC 3. Адрес 4. Функция 5. Данные
|
|
|
|
|
May 17 2011, 05:17
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 31-08-10
Из: Минск-Витебск
Пользователь №: 59 203

|
Для простых случаев может и можно не проверять. А если сеть протяженная, с большим количеством слейвов, помеховая обстановка серьезная - вероятность ошибок в пакете приличная, проверка crc становится обязательной.
|
|
|
|
|
May 17 2011, 06:01
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 31-08-10
Из: Минск-Витебск
Пользователь №: 59 203

|
Да согласен
Хотя у некторых есть счетчики которые считают ошибки в линии т.к. если есть ошибка, то не известно где именно и кому предназначен пакет.
Сообщение отредактировал yashok - May 17 2011, 05:39
|
|
|
|
|
Oct 17 2012, 07:26
|
Группа: Новичок
Сообщений: 3
Регистрация: 28-09-12
Из: Новосибирск
Пользователь №: 73 716

|
Доброго дня всем. Пытаюсь поднять FreeRTOS(7.2)+lwip(1.4)+FreeModbus(1.5)(TCP), FreeRTOS+lwip на LM3S9B95(board EVB-9B95) худо-бедно справился, пинги идут, httpserver_raw запустился, пробную страничку получил. А вот с modbus справится не могу. Для теста взял qModMaster, т.к. работать легко с ней(основные шаги connect->read data->disconnect я выполняю по кнопками, что упрощает тест), и параллельно для надежности нечто более сложное NI OPC Server. Connect, Disconnect работают отлично, вызываются prvxMBTCPPortAccept() и prvxMBTCPPortReceive()(здесь он уходит в prvvMBPortReleaseClient и закрывает соединение). А вот с чтением данных у меня возникли проблемы, при чтении попадаю я в prvxMBTCPPortReceive(), далее по функции доходит до (void)xMBPortEventPost(EV_FRAME_RECEIVED); и из нее не возвращается, ползу по ней дебагером Код //portevent.c BOOL xMBPortEventPost( eMBEventType eEvent ) { eMailBoxEvent = eEvent; sys_mbox_post( xMailBox, &eMailBoxEvent ); return TRUE; } он уходит в sys_mbox_post(); Код //sys_arch.c void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost ) { while( xQueueSendToBack( *pxMailBox, &pxMessageToPost, portMAX_DELAY ) != pdTRUE ); } и на сколько я понимаю крутится внутри xQueueGenericSend(). После чего отваливается ethernet, т.е. пинги не проходят вообще, да и походу роутер не видит плату, FreeRTOS в это время работает Task'и переключает исправно. Я уже даже не знаю в какую сторону копать. Порт modbus взят из демки MCF5235TCP, а LWIP где-то на просторах интернета [attachment=72049:ports_lwip.zip] [attachment=72050:port_modbus.zip]
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|