Db54 COM порты

Материал из rrv-wiki
Перейти к навигации Перейти к поиску


Спасибо Михаилу Швецову!

В общем много было попыток настроить работу эволюционной платы DB54 фирмы BECK (дальше просто плата) с устройствами подключенными к COM портам платы по следующему описанию. Иногда что то получалось иногда нет. Рекомендовалось обновить прошивку контроллера. Эти эксперименты проводятся после обновления RTOS до версии SC23/SC24 V1.30 FULL.

Итак вчитываемся в форум, скачиваем систему исполнения рекомендуемую на форуме файл и пытаемся повторить опыт.

М... да... облом, автор выложил только часть, полного пакета, а именно RTS. Тарджет используется стандартный из ChipSDK версии DK55_FP_CM. По умолчанию он устанавливается сюда: C:\Program Files\Beck IPC GmbH\CoDeSys@CHIP SDK\samples\Full\DK55\SC23\DK55_FP_CM

На всякий случай вкратце расскажу структуру (коряво и без терминов, возможно позже опишу в нормальной статье):

  • в папке RTS хранятся исходные коды, а так же собранные exe файлы выполняемые под RTOS в контроллере (исходники написаны на C++ и кое что можно править, об этом потом)
  • в папке tsp (ничего нельзя править) в этой папке описание нашей платформы для CoDeSys, что бы инсталлировать новую платформу в CODeSys необходимо выполнить скрипт tsp\install.bst

Обе папки создаются с помощью генератора платформы IEC Platform Builder где описываем особенности платформы (нам пока это не надо, пригодится, когда создадим собственную плату на микроконтроллере BECK например SC23)

И так, копируем папку C:\Program Files\Beck IPC GmbH\CoDeSys@CHIP SDK\samples\Full\DK55\SC23\DK55_FP_CM куда нибудь, например в G:\rrv-test\COM-порты\ и переходим в эту папку. Теперь переименуем rts в rts.orig и копируем на ее место RTS_DK55 папку из скаченного архива переименовав ее в rts. Внимание! тут описано более корректно и делать как описано тут.

Теперь запустим tsp\install.bst /f как говорилось выше (ключ f заменит платформу если она уже существует).

Теперь любимым ftp клиентом копируем rts\bin\myrts.exe на диск a: нашего микроконтроллера ip, логин и пароль можно задать и посмотреть здесь. И a:\AUTOEXEC.BAT приводим к виду:

myrts.exe

Теперь перезапускаем плату, новый myrts.exe запустится на контроллере автоматически.

Читаем форум и смотрим отличия главного си-шного файла платформы myrts.c (находится в папке RTS) в оригинальном примере со скаченым с форума (с верху кусок оригинального файла, с низу кусок примера с форума):

http://rrv.nsk.ru/wiki/images/myrts.c_com.jpg

как видим, что строки структуры s_SerialPortTypes:

RHI_MAXCOMPORTS,     /* NumComPorts */
  {                    /* ComPortUse[RHI_MAXCOMPORTS] */
     RHI_SERPORT_NAV,  /* ComPortUse: RHI_SERPORT_NAV or RHI_SERPORT_COM */
     RHI_SERPORT_COM,  /* ComPortUse: RHI_SERPORT_NAV or RHI_SERPORT_COM */
     RHI_SERPORT_COM,  /* ComPortUse: RHI_SERPORT_NAV or RHI_SERPORT_COM */
     RHI_SERPORT_NAV,  /* ComPortUse: RHI_SERPORT_NAV or RHI_SERPORT_COM */
     RHI_SERPORT_NAV,  /* ComPortUse: RHI_SERPORT_NAV */
     RHI_SERPORT_NAV,  /* ComPortUse: RHI_SERPORT_NAV */
     RHI_SERPORT_NAV,  /* ComPortUse: RHI_SERPORT_NAV */
     RHI_SERPORT_NAV,  /* ComPortUse: RHI_SERPORT_NAV */
  }

Отвечают за восемь COM портов начиная с нулевого, для того чтобы включить порт необходимо поменять в соответствующей строке название с RHI_SERPORT_NAV на RHI_SERPORT_COM, для отключения наоборот.

Причем как видно, на примере с форума автор отключил SPI и I2C (аналогично):

    RHI_SERPORT_NAV,     /* SPIPortUse: RHI_SERPORT_NAV or RHI_SERPORT_SPI */
    RHI_SERPORT_NAV,     /* I2CPortUse: RHI_SERPORT_NAV or RHI_SERPORT_I2C */


Для создания изначально правильно платформы, выполним следующее:

  1. Скопируем из папки C:\Program Files\Beck IPC GmbH\CoDeSys@CHIP SDK\samples\Full\DK55\SC23 файл DK55_FP_CM.xml в папку G:\rrv-test\COM-порты
  2. Откроем этот файл в IEC Platform Builder
  3. На вкладке Device снимем галочку RS232, она отвечает за связь CoDeSys c платой по первому COM-порту, но так как нам понадобятся оба COM-порта, то оставим подключение к плате только через TCP порт 1200.
  4. Теперь сохраним проект, кнопка Save
  5. Затем создадим проект нажав кнопку Make, если возникнут ошибки с нахождением библиотек, то укажите их правильный путь на вкладке Library (в моем случае не нашлась библиотека LCD_Demo.lib посмотрев исходный проект я указал C:\Program Files\Beck IPC GmbH\CoDeSys@CHIP SDK\samples\Full\DK55\LCD_Demo.lib, хотя можно было и скопировать ее в G:\rrv-test\COM-порты). Аналогично поступим с ошибкой не нахождения картинки DK55.bmp, на вкладке General изменяем путь до картинки в поле Device Bitmap). Нажимаем кнопку Make после исправления каждой ошибки до тех пор пока не устраним все ошибки и не создадим проект.
  6. Открываем проект G:\rrv-test\COM-порты\DK55_FP_CM\rts\myRts.pdl в Paradigm C++ Beck IPC Edition и правим myrts.c это файл G:\rrv-test\COM-порты\DK55_FP_CM\rts\myrts.c и меняем строку RHI_SERPORT_NAV, на RHI_SERPORT_COM, как это объяснено выше, строки RHI_SERPORT_SPI, и RHI_SERPORT_I2C, оставляем как есть, пригодится.
  7. Собираем проект C++ выбрав в меню Project -> Build All если ошибок нет и файл myrts.exe создан, то остается воспользоваться любимым FTP-клиентом и залить этот файл в контроллер читаем как. И если мы еще не правили a:\AUTOEXEC.BAT то добавляем в него строчку myrts.exe. Перезапускаем плату. Все теперь можно запускать CoDeSys, все готово.

Можно запускать CoDeSys и создавать пример из форума (Я уже выложил туда свою рабочую версию).

Программа:

http://rrv.nsk.ru/wiki/images/rs-232_COM2_pic1.jpg

И в процессе исполнения:

http://rrv.nsk.ru/wiki/images/rs-232_COM2_pic2.jpg

http://rrv.nsk.ru/wiki/images/rs-232_COM2_pic3.jpg


Приведу код программы PLC_PRG с пояснениями, дабы не набивать в последствии.

PLC_PRG:

PROGRAM PLC_PRG
VAR
    dwHandle:DWORD:=INVALID_HANDLE; (*В эту переменную помещаем результат 
                                      функции открытия порта в которой указывается адрес 
                                      привязки для конкретной реализации, если результат 16#FFFFFFFF 
                                      значит произошла ошибка, в этой демонстрационной 
                                      программе этот вариант не проверяется, 
                                      в рабочей программе проверять обязательно!  *)
    Settings:COMSETTINGSEX; (* Структура в которой хранятся параметры открываемого порта.
                               Подробности смотри на вкладке Ресурсы, 
                               в пункте Менеджер библиотек, выбрав библиотеку,
                               в нашем случае SysLibCom*)
    bSt:BOOL; (* Переменная в которую мы будем записывать результат функций: 
                 задания параметров порта и закрытия порта. Затем будем использовать 
                 эту переменную в качестве перехода к следующему блоку в случае удачного
                 исполнения функций SysComSetSettingsEx и SysComClose *)
    byBuffer:ARRAY[0..20] OF BYTE:=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 
                              (* Массив в который будем сохранять принятые байты данных
                                 в моем случае мне требуется всего 9 байт, но я взял с запасом,
                                 т.к. логика работы внешнего устройства такова,
                                 что одновременно могут быть посланы одновременно 2 набора данных
                                 то есть 18 байт, но мне нравится число 21 :) иначе бы массив 
                                 был бы byBuffer:ARRAY[0..17] OF BYTE:=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0; 
                                 в целом, в место массива можно использовать строку:
                                 byBuffer:STRING:="000000000000000000000";*)
    dwRxBytes:DWORD; (* Важная переменная, в нее мы будем записывать количество принятых байт,
                      учтите, что если массив byBuffe переполнится, то он циклически перезапишется с начала
                      тем самым часть данных будет затерта, в реальном проекте добавьте проверку, что бы размер byBuffer
                      всегда был больше, чем число принятых байт (wRxByte) *)
END_VAR

Init:

(* Здесь указанны следующие параметры RS-232: Порт:COM2, Скорость:9600бит/с, Кол-во бит данных в посылке:8,
   без паритета, 1 стоп-бит. Где взять описание см. выше структура Settings *)
Settings.Port:= COM3; (*Обратите внимание! для этих плат, для того что бы указать порт COM1 используем запись COM2
                        для COM2 указываем COM3, имеется подобное смещение, оно описано на форуме (ссылку см. выше) *)
Settings.dwBaudRate:= 9600;
Settings.cByteSize:= 8;
Settings.byParity:= 0;
Settings.byStopBits:= 0;
Settings.Size:= SIZEOF(Settings);

OpenPort:

dwHandle:= SysComOpen(Settings.Port); (*Открываем порт*)
bSt:=SysComSetSettingsEx(dwHandle, ADR(Settings)); (*Задаем параметры*)

Read:

dwTxBytes:= SysComRead(dwHandle, ADR(byBuffer), 21, 0); (*Читаем из порта, адрес передается через dwHandle, 
                                                          куда записывать, через функцию ADR вычисляющую адрес
                                                          массива в который будем принимать, сколько максимально байт
                                                          считывать (размер буфера, что бы не переполнить, при переполнении
                                                          начинает циклическую запись с начала, то есть в нашем случае 
                                                          22 байт запишется в нулевую ячейку массива byBuffer)
                                                          0 последним означает задержку таймаута, возможно Вам
                                                          потребуется другое например 250 (что означает, 
                                                          таймаут 250 миллисекунд)*)

Затем идет ветвление. Если что то было считанно, то закрываем порт. В рабочей программе возможно мы захотим как то обработать принятые данные :) И вообще не будем закрывать порт, а начнем читать дальше, в общем это на ваш вкус. Если же мы ничего не считали, то выдерживаем паузу (если требуется) и снова читаем. У меня реально считывание требуется раз в 1 сек, так что я выбрал задержку 0.1 сек, у вас возможно она будет другой. Внимание! Если вы у блока ставите минимальное время исполнения, то если блок выполнился раньше, этого временного интервала, то выполнение начинается сначала (требуется проверка этого постулата). Будте осторожней, например если в таком блоке будет например функция открытия порта, то программа будет остановлена системой Watchdog.

ClosePort:

bSt:=SysComClose(dwHandle);