реклама на сайте
подробности

 
 
> COM-порт - МК, Управление устройствами на МК с компьютера
Tiny
сообщение Aug 22 2010, 12:31
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 82
Регистрация: 10-07-06
Пользователь №: 18 720



Вопрос к тем, кто работал по данной теме.
100 устройств. На каждом установлен по одному MEGA16, которые должны при поступлении команды от компьютера сбросить один из 13 пинов устройства на ноль.
Реализовал следующим образом. Компьютерную часть программы писал на Borland Builder C++. На удаленном компьютере нажимается кнопка, соответствующая команда (3 знака - номер устройства + 2 знака - номер пина, например 00101 - 1-е устройство, 1 пин) поступает на сервер. С сервера через СОМ-порт на UART МК.
Для МК писал в CodeVision AVR. При получении сигнала происходит прерывание UART, полученные данные перекодируются из кода ASCII в десятичные и сохраняются. Если номер устройства совпал с реальным номером данной платы (задается положением переключателей на потре B ), то анализируются полученные данные. Соответствующий пин порта А или С сбрасывается на 0, обратно для подтверждения отправляется полученный код, предварительно перекодировав его обратно в код ASCII из десятичных.
МК работает с кварцевой стабилизацией 14400кГц. (Реально стоит 14,31818, другого пока не нашел). Скорость UART 14400кГц.
С одним МК работает. Когда достану преобразователь RS232-RS485 - подключу в линию другие устройства.
Возникает вопрос. Когда будут подключены 100 устройств на 100МК и с Интернета на сервер будут одновременно обращаться десятки команд, будет ли все это работать?
При передаче команды вначале идет старт-бит, данные, стоп-бит. В эту процедуру никто посторонний не влезет. Так для передачи 00101 от 1-го пользователя эта процедура должна произойти 5 раз. А не получится ли так, что после передачи двух младших разрядов сюда вклинется другой пользователь передающий команду, допустим 05603?


Сообщение отредактировал Tiny - Aug 22 2010, 12:34
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
defunct
сообщение Aug 22 2010, 23:11
Сообщение #2


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Tiny @ Aug 22 2010, 15:31) *
Так для передачи 00101 от 1-го пользователя эта процедура должна произойти 5 раз. А не получится ли так, что после передачи двух младших разрядов сюда вклинется другой пользователь передающий команду, допустим 05603?

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


Цитата(Tiny @ Aug 22 2010, 18:25) *
Посылка одного разряда кода занимает один байт. Но всего в коде таких разрядов 5 (00101). В коде информация об адресе назначения, но не отправителя. В момент между разрядами от одного клиента может попасть разряд от другого.
Я вношу полученные данные в переменные. Собираются все разряды, анализируется этому ли устройству адресовалось и только то устройство, которому адресовалось выполняет команду и отправляет код обратно.


Есть 100 TCP сокетов - клиенты, и есть 100 исполнительных устройств.

Заводите как минимум два треда. Один обслуживает сокеты, второй - uart.
Создаете некую Cmd структуру, которая может быть например такой:

Код
typedef struct tagCMD
{
    PTCP_SOCKET  socket;
    U8  cmd[ MAX_CMD_LEN ];
    int  cmd_len;
    
    U8  resp[ MAX_RESP_LEN ];
    int  resp_len;
} CMD, *PCMD;


далее принимаете любую "хню" из некоего сокета-клиента, выделяете структурку и заполняете ее как-то так:

Код
OnSocketReadEvent( PTCP_SOCKET socket ...)
{
    pCmd  = (PCMD)Heap_Alloc( sizeof( CMD) );
    pCmd->socket = socket;  // <--- это клиент, который послал команду
    pCmd->cmd_len = socket->bytes_to_read;
    socket->read( pCmd->cmd, pCmd->cmd_len);
    ...


ставите ее в очередь на исполнение для другого треда:
Код
    enqueue( GlobalCmdQueue, pCmd);
}



в другом треде, делаете буквально так:

Код
while(TRUE)
{
    // спим пока нет события записи в очередь
    GlobalCmdQueueEvent->WaitFor( infinite );

    while ( (pCmd = dequeue( GlobalCmdQueue)) != NULL )
    {
        // отправка на исполнительный девайс
        Com->write( pCmd->cmd, pCmd->len);
        ...
        // чтение ответа от девайса
        Com->read( pCmd->resp, &pCmd->resp_len);

        // отправка результата клиенту
        pCmd->socket->write( pCmd->resp, pCmd->resp_len);

        // освобождение памяти
        Heap_Free( pCmd );
    }
}



Вот собсно и все...
Go to the top of the page
 
+Quote Post
Tiny
сообщение Aug 23 2010, 04:44
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 82
Регистрация: 10-07-06
Пользователь №: 18 720



Спасибо большое всем за помощь. Буду переваривать всю полученную информацию.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 25th July 2025 - 01:52
Рейтинг@Mail.ru


Страница сгенерированна за 0.01418 секунд с 7
ELECTRONIX ©2004-2016