- Using Moxa NPort 5450 Serial to IP Server with Linux Kernel Version 3.8.0 (tested with Ubuntu 13.04)
- Contents
- Building the Patched Driver
- Changes for Linux Kernel 3.8.0
- Driver Support for Other Moxa Products
- References
- Работаем со старым промышленным софтом под linux или как подружить wine и RS-485
- Установка Wine
- Установка драйвера MOXA Uport 1150
- Настройка WINE для работы с СОМ-портами и ПО
- Всё это прогрызание кактуса выполнялось для запуска определенных видов промышленного ПО и каждое работало по своему
Using Moxa NPort 5450 Serial to IP Server with Linux Kernel Version 3.8.0 (tested with Ubuntu 13.04)
Unfortunately, Moxa’s NPort Real TTY Driver for Linux is currently (version 1.18, released 2012/03/20) not compatible with Linux kernel 3.8.0. When I tried to install this driver for the NPort 5450 Serial to IP Server on my Ubuntu 13.04 machine (currently with kernel 3.8.0-27), the driver didn’t compile. It turned out, that it is possible to patch the driver source code in order to get it work with Linux kernel 3.8.0 – here is a short documentation what I did.
Contents
Building the Patched Driver
- Download the NPort Real TTY Driver for Linux in version 1.18.7 Build 13050317 from this forum post (unofficial build, Russian forum)
- Prepare the code base for compilation:
user@ubuntu:~$ tar -xzvf npreal2_1.18.7_Build_13050317.tgz -C /tmp user@ubuntu:~$ cd /tmp/moxa user@ubuntu:/tmp/moxa$ wget https://downloads.rene-schwarz.com/download/npreal2.c_1-18-7_b13050317.patch user@ubuntu:/tmp/moxa$ patch < npreal2.c_1-18-7_b13050317.patch
- Extract the driver source code to /tmp (line 1).
- Download the patch for npreal2.c from here (lines 2 et seq.).
- Patch the C source file npreal2.c (line 4).
user@ubuntu:/tmp/moxa$ sudo ./mxinst
Changes for Linux Kernel 3.8.0
The changes that were necessary to let the driver compile against the Linux kernel 3.8.0 are the following (identical to the patch provided above):
--- npreal2.c Fri May 03 11:52:43 2013 +++ npreal2.c Tue Aug 06 16:58:36 2013 @@ -426,6 +426,39 @@ static struct semaphore npvar_tmp_buf_sem = MUTEX; #endif +#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0)) +struct n_tty_data < + unsigned int column; + unsigned long overrun_time; + int num_overrun; + + unsigned char lnext:1, erasing:1, raw:1, real_raw:1, icanon:1; + unsigned char echo_overrun:1; + + DECLARE_BITMAP(process_char_map, 256); + DECLARE_BITMAP(read_flags, N_TTY_BUF_SIZE); + + char *read_buf; + int read_head; + int read_tail; + int read_cnt; + int minimum_to_wake; + + unsigned char *echo_buf; + unsigned int echo_pos; + unsigned int echo_cnt; + + int canon_data; + unsigned long canon_head; + unsigned int canon_column; + + struct mutex atomic_read_lock; + struct mutex output_lock; + struct mutex echo_lock; + raw_spinlock_t read_lock; +>; +#endif + #if (LINUX_VERSION_CODE < VERSION_CODE(2,4,0)) static struct inode_operations npreal_net_iops; #endif @@ -3436,7 +3469,21 @@ >#endif -#if ((LINUX_VERSION_CODE > VERSION_CODE(2,6,15)) || ((LINUX_VERSION_CODE == VERSION_CODE(2,6,15)) && defined(FEDORA))) +#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0)) +static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) +< + /* Dumb strategy for now - should keep some stats */ + /* printk("Flip dispose %p\n", b); */ + if (b->size >= 512) + kfree(b); + else + < + b->next = tty->port->buf.free; + tty->port->buf.free = b; + > +> +#endif +#if ((LINUX_VERSION_CODE > VERSION_CODE(2,6,15) && LINUX_VERSION_CODE < VERSION_CODE(3,8,0)) || ((LINUX_VERSION_CODE == VERSION_CODE(2,6,15)) && defined(FEDORA))) static void tty_buffer_free(struct tty_struct *tty, struct tty_buffer *b) < /* Dumb strategy for now - should keep some stats */ @@ -3514,11 +3561,20 @@ tty->ldisc.receive_buf(tty, cp, fp, count); //DBGPRINT(MX_DEBUG_TRACE, "flush %d bytes\n", count); #else - spin_lock_irqsave(&tty->buf.lock, flags); +#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0)) + spin_lock_irqsave(&tty->port->buf.lock, flags); + head = tty->port->buf.head; +#else + spin_lock_irqsave(&tty->port->buf.lock, flags); head = tty->buf.head; +#endif if (head != NULL) < +#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0)) + tty->port->buf.head = NULL; +#else tty->buf.head = NULL; +#endif for (;;) < count = head->commit - head->read; @@ -3545,17 +3601,29 @@ cp = head->char_buf_ptr + head->read; fp = head->flag_buf_ptr + head->read; head->read += count; +#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0)) + spin_unlock_irqrestore(&tty->port->buf.lock, flags); +#else spin_unlock_irqrestore(&tty->buf.lock, flags); +#endif #if (LINUX_VERSION_CODE >= VERSION_CODE(2,6,27)) disc->ops->receive_buf(tty, cp, fp, count); #else disc->receive_buf(tty, cp, fp, count); #endif +#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0)) + spin_lock_irqsave(&tty->port->buf.lock, flags); + > + tty->port->buf.head = head; + > + spin_unlock_irqrestore(&tty->port->buf.lock, flags); +#else spin_lock_irqsave(&tty->buf.lock, flags); > tty->buf.head = head; > spin_unlock_irqrestore(&tty->buf.lock, flags); +#endif tty_ldisc_deref(disc); #endif > @@ -4303,6 +4371,7 @@ int cnt; struct npreal_struct *info; struct tty_struct * tty; + struct n_tty_data *ldata; /* * Get the node pointer, and quit if it doesn't exist. @@ -4350,6 +4419,10 @@ up(&info->rx_semaphore); goto done; > +#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0)) + ldata = tty->disc_data; +#endif + #if (LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)) #if 1 if(!info->tty->low_latency) @@ -4392,8 +4465,11 @@ * that erase characters will be handled. Other excess * characters will be beeped. */ - - if (!tty->icanon || tty->canon_data) +#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0)) + if (!ldata->icanon || ldata->canon_data) +#else + if (!tty->icanon || tty->canon_data) +#endif < #if (LINUX_VERSION_CODE < VERSION_CODE(2,1,0)) if (!set_bit(TTY_THROTTLED,&tty->flags)) @@ -4408,9 +4484,15 @@ up(&info->rx_semaphore); goto done; > +#if (LINUX_VERSION_CODE >= VERSION_CODE(3,8,0)) + if (!ldata->icanon || ldata->canon_data) + < + if ((cnt = MIN(cnt,(N_TTY_BUF_SIZE-1) - ldata->read_cnt )) icanon || tty->canon_data) < if ((cnt = MIN(cnt,(N_TTY_BUF_SIZE-1) - tty->read_cnt ))Driver Support for Other Moxa Products
This driver should also work for other Moxa products, namely the following ones:
- CN2510 Series
- CN2610/2650 Series
- MiiNePort E1 Series
- MiiNePort E2 Series
- MiiNePort E3 Series
- MiiNePort W1 Series
- NE-4000T/NE-4000T-ST
- NE-4100T
- NE-4110A
- NE-4110S
- NE-4120A
- NE-4120S
- NPort 5110/5130/5150 Series
- NPort 5110A/5130A/5150A Series
- NPort 5130
- NPort 5150
- NPort 5150AI-M12/5250AI-M12/5450AI-M12 Series
- NPort 5210/5230/5232 Series
- NPort 5210A/5230A/5250A Series
- NPort 5230 Series
- NPort 5410/5430/5450 Series
- NPort 5430 Series
- NPort 5450 Series
- NPort 5600-8-DT/5650-8-DT Series
- NPort 5610/5630 Series
- NPort 5610-8-DTL/5650-8-DTL Series
- NPort 5650 Series
- NPort 6150 Series
- NPort 6250 Series
- NPort 6450 Series
- NPort 6610/6650 Series
- NPort DE-311M
- NPort Express DE-211
- NPort Express DE-311
- NPort IA5150/5250 Series
- NPort IA5150A/IA5250A/IA5450A Series
- NPort P5150A Series
- NPort S8455/S8458 Series
- NPort Server Lite DE-301/302/304/331/332/334
- NPort Server Pro DE-303, DE-308
- NPort W2004 Series
- NPort W2150/2250 Plus
- NPort W2150A/W2250A
- NPort W2250/2150
- WE-2100T
References
Работаем со старым промышленным софтом под linux или как подружить wine и RS-485
В свете недавних указов президента посыпались вопросы от заказчиков, а есть ли %конфигуратор устройства не поддерживаемый цать лет, разработчики которого уволились или сбежали из России% под linux?
В следствие чего была из синей ленты, остатков бубна и обрывочных знаний по linux данная инструкция.
Надеюсь она пригодится коллегам, занимающимся наладкой и эксплуатацией АСУ ТП
Не забываем, что мы должны использовать отечественное ПО, в следствие чего дистрибутив будет Astra Linux SE 1.7.1 ОРЕЛ
Предполагается, что система установлена и подключена к интернету.
В качестве СОМ-порта использовался MOXA Uport 1150, перед настройкой необходимо подключить MOXA Uport к USB-порту ПК. При использовании другого устройства его необходимо настроить в соответствии с поставляемым мануалом.
Установка Wine
Основная инструкция (актуальная) тут.
нас интересует "Установка Wine версии 7.3 в Astra Linux Special Edition РУСБ.10015-01 (очередное обновление 1.7)"
1. Скачать пакет Wine 7.3 отсюда и пакет ia32-libs отсюда.
2. Открыть терминал Fly и ввести команды по порядку:
sudo apt install ia32-libs
sudo apt install libc6-i386
sudo dpkg -i ~/Загрузки/ia32-libs_20220330+1.7se_amd64.deb
# Имя текущей версии пакета, со временем она может быть изменена.
sudo dpkg -i ~/Загрузки/wine_7.3-0-astra-se17_amd64.deb
# Имя текущей версии пакета, со временем она может быть изменена.
sudo apt install ca-certificates libmspack0 cabextract
sudo mv winetricks /usr/bin
# для быстрого запуска из консоли
Рабочая директория WINE будет находится по адресу /opt/wine-7.3/bin/
Установка драйвера MOXA Uport 1150
Драйвер под конкретную версию ядра нужно качать с оф сайта
посмотреть версию ядра можно командой в терминале uname -r
На текущий момент это 5.10, скачать драйвер v.5.1.
1. Открываем терминал fly и вводим последовательно команды:
sudo apt install make linux-headers setserial autotools-dev
sudo cp /home/user/Загрузки/moxa-uport-1100-series-linux-kernel-5.x-driver-v5.1 moxa-uport-1100-series-linux-kernel-5.x-driver-v5.1
sudo tar xvfz moxa-uport-1100-series-linux-kernel-5.x-driver-v5.1.tgz
# Если во время выполнения команды "make install" возникает ошибка, то выполняем
# "sudo apt install --reinstall linux-headers-$(uname -r)" и повторно выполняем "make install";
2. Переводим Uport в режим 485 2W с помощью команды в терминале: setserial /dev/ttyUSB0 port 1
номер порта можно посмотреть командой sudo ls /dev/ttyU*
Настройка WINE для работы с СОМ-портами и ПО
С помощью файлового менеджера (проводника) идем в /opt/wine-7.3/bin/ и запускаем regedit
В разделе реестра [HKEY_LOCAL_MACHINE\Software\Wine\Ports] создаем СТРОКОВУЮ переменную:
Запускаем winecfg и меняем версию windows на Windows XP или windows 2003:
Применяем и закрываем Winecfg.
Далее создаем символическую ссылку на нужный нам СОМ-порт:
sudo ln -s /dev/ttyUSB0 ~/.wine/dosdevices/com1
Если com1 уже существует, можно удалить его и заново создать ссылку:
sudo rm ~/.wine/dosdevices/com1
sudo ln -s /dev/ttyUSB0 ~/.wine/dosdevices/com1
Чтобы не менять права на СОМ-порт, необходимо добавить текущего пользователя в dialout командой:
sudo adduser dialout
затем ВЫЙТИ из системы и зайти заново.
Скачиваем ПО в любую папку в домашней директории и запускаем из менеджера файлов (проводника) двойным щелчком. в списке выбора приложений жмем на другая. и выбираем wine из /opt/wine-7.3/bin/:
Чтобы в следующий раз exe формат открывался через WINE можно установить его по умолчанию:
Далее можно пользоваться необходимым ПО.
Всё это прогрызание кактуса выполнялось для запуска определенных видов промышленного ПО и каждое работало по своему
Сканер устройств по com порту - при открытии будет спрашивать о замене sys файлов - ответить нет.
Может долго искать или падать с ошибками - просто перезапустить. Если будет находить приборы на других СОМ-портах или долго виснуть, то лучше удалить все символические ссылки на СОМ-порты кроме нужного:
sudo rm ~/.wine/dosdevices/comN
где N - номер лишнего СОМ-порта.
Конфигуратор оборудования - может падать с ошибками - просто перезапустить.
В целом 3 из 5 программ отработали без замечаний.
Автора данной статьи можно пинать ногами, обзывать ламером не умеющим в linux, но предлагать как нужно было сделать проще и быстрее.