Неудачная попытка использовать поток и таймер для отправки двух разных сообщений с UDP - PullRequest
1 голос
/ 23 сентября 2019

Я хочу отправить два разных типа сообщений с сервера на клиент.Я создал две функции data_signal() и probe_signal() для каждого из этих двух разных сообщений.

Функция data_signal() будет периодически отправлять определенное сообщение с интервалом CLOCK_SECOND * 1 клиенту.

Я использую таймер для интервала CLOCK_SECOND * 30 duration, чтобы периодически вызывать probe_signal() для отправки другого сообщения клиенту.

В настоящее время функция data_signal() работает, как и ожидалось.Однако функция probe_signal() не отправляет свое сообщение клиенту.

Я проверил это, просто напечатав сообщение на стороне клиента, и сообщение "probe_signal ()" не было получено.

Более того, если я прокомментирую uip_udp_packet_send(conn, buf, strlen(buf)); строку data_signal(), я смогу получить сообщение от probe_signal().Я думаю, что эта проблема возникает из-за того, что я использую одно и то же соединение UDP

Код:


#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"

#define DEBUG DEBUG_FULL
#include "net/ip/uip-debug.h"
#include "net/ip/uiplib.h"
#include "net/ipv6/uip-icmp6.h"

#include <string.h>
#define SERVER_IP             "fe80::9a07:2dff:fe3c:8d01" //"::"

#define CLIENT_PORT           61617
#define SERVER_PORT           61616

#define PING_TIMEOUT              (CLOCK_SECOND / 4)
#define CLIENT_SEND_INTERVAL      (CLOCK_SECOND * 1)

#define UDP_LEN_MAX           255
/*---------------------------------------------------------------------------*/
static uip_ipaddr_t server_addr;
static struct uip_icmp6_echo_reply_notification icmp_notification;
static uint8_t echo_received;
static struct uip_udp_conn *conn;

static struct etimer timer;
static char buf[UDP_LEN_MAX];
static uint16_t packet_counter;
static uint16_t probe_packet_counter;
static uint16_t actualSent_packet_counter;
static int flag;

/*---------------------------------------------------------------------------*/
PROCESS(ipv6_ble_client_process, "IPv6 over BLE - client process");
AUTOSTART_PROCESSES(&ipv6_ble_client_process);
/*---------------------------------------------------------------------------*/
void icmp_reply_handler(uip_ipaddr_t *source, uint8_t ttl,
                   uint8_t *data, uint16_t datalen)
{
  PRINTF("echo response received\n");
  echo_received = 1;
}
/*---------------------------------------------------------------------------*/
static void tcpip_handler(void)
{


}
/*---------------------------------------------------------------------------*/
static void
data_signal(void)
{

    sprintf(buf, "Current packet count is: %04u!",packet_counter);
    PRINTF("send message: <%s>\n", buf); /*This printf is commented for understanding the low level code*/
    uip_udp_packet_send(conn, buf, strlen(buf));
    packet_counter++;
}


static void probe_signal(void)
{   
    sprintf(buf, "%04u", probe_packet_counter);
    uip_udp_packet_send(conn, buf, strlen(buf));
    printf("Probe signal is sent");
}

/*---------------------------------------------------------------------------*/


PROCESS_THREAD(ipv6_ble_client_process, ev, data)
{
    static struct timer t;  
    PROCESS_BEGIN();
    PRINTF("CC26XX-IPv6-over-BLE client started\n");

    conn = udp_new(&server_addr, UIP_HTONS(SERVER_PORT), NULL);
    udp_bind(conn, UIP_HTONS(CLIENT_PORT));
    timer_set(&t, CLOCK_SECOND * 30);

    etimer_set(&timer, CLIENT_SEND_INTERVAL);

    while(1) 
    {
        if(timer_expired(&t))
        {   
            flag =1;
            if(flag==1)
            {
                probe_signal();
                timer_reset(&t);
                printf("Timer is reset\n");
            }

        }
        PROCESS_YIELD();
        if((ev == PROCESS_EVENT_TIMER) && (data == &timer)) 
        {
            data_signal();    
            etimer_set(&timer, CLIENT_SEND_INTERVAL);
        } 
        else if(ev == tcpip_event) 
        {
            printf("TCPIP event occured\n");
            tcpip_handler();
        }
    }

  PROCESS_END();
}
/*---------------------------------------------------------------------------*/

Может кто-нибудь подсказать, как решить эту проблему, это было бы очень полезно.

1 Ответ

1 голос
/ 23 сентября 2019

Я могу решить эту проблему, изменив код:

  • Изменен тип таймера на etimer
  • Ожидал событие etimer, а затем вызвал probe_signal().

Из событий и планирования из Документация: процессы и события :

Contiki-NG построен на основе модели выполнения на основе событий, где процессыобычно выполняют работу, прежде чем сообщить планировщику, что они ожидают события, и тем самым приостановить выполнение.Такими событиями могут быть истечение времени таймера, входящего сетевого пакета или доставляемого сообщения последовательной линии.

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

И из раздела Приостановка и выход изтот же документ:

В отличие от этого, PROCESS_YIELD () вернет управление планировщику, не ожидая повторного планирования вскоре после этого.Вместо этого он будет ожидать входящее событие, аналогичное PROCESS_WAIT_EVENT_UNTIL (), но без обязательного аргумента условия.

Обсуждение библиотеки Etimer можно найти по адресу Таймеры в contiki-Репозиторий os github:

Библиотека Contiki etimer предоставляет механизм таймера, который генерирует синхронизированные события.Таймер события отправит событие PROCESS_EVENT_TIMER процессу, который установил таймер по истечении таймера события.Библиотека etimer использует clock_time () в модуле часов для получения текущего системного времени.

Обновленный код:


#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"

#define DEBUG DEBUG_FULL
#include "net/ip/uip-debug.h"
#include "net/ip/uiplib.h"
#include "net/ipv6/uip-icmp6.h"

#include <string.h>
#define SERVER_IP             "fe80::9a07:2dff:fe3c:8d01" //"::"

#define CLIENT_PORT           61617
#define SERVER_PORT           61616

#define PING_TIMEOUT              (CLOCK_SECOND / 4)
#define CLIENT_SEND_INTERVAL      (CLOCK_SECOND * 1)
#define PROBE_SIGNAL_INTERVAL      (CLOCK_SECOND * 30)

#define UDP_LEN_MAX           255
/*---------------------------------------------------------------------------*/
static uip_ipaddr_t server_addr;
static struct uip_icmp6_echo_reply_notification icmp_notification;
static uint8_t echo_received;
static struct uip_udp_conn *conn;

static struct etimer timer,probe_timer;
static char buf[UDP_LEN_MAX];
static uint16_t packet_counter;
static uint16_t probe_packet_counter;
static uint16_t actualSent_packet_counter;
static int flag;

/*---------------------------------------------------------------------------*/
PROCESS(ipv6_ble_client_process, "IPv6 over BLE - client process");
AUTOSTART_PROCESSES(&ipv6_ble_client_process);
/*---------------------------------------------------------------------------*/
void icmp_reply_handler(uip_ipaddr_t *source, uint8_t ttl,
                   uint8_t *data, uint16_t datalen)
{
  PRINTF("echo response received\n");
  echo_received = 1;
}
/*---------------------------------------------------------------------------*/
static void tcpip_handler(void)
{


}
/*---------------------------------------------------------------------------*/
static void
data_signal(void)
{

    sprintf(buf, "Current packet count is: %04u!",packet_counter);
    PRINTF("send message: <%s>\n", buf); /*This printf is commented for understanding the low level code*/
    uip_udp_packet_send(conn, buf, strlen(buf));
    packet_counter++;
}


static void probe_signal(void)
{   
    sprintf(buf, "%04u", probe_packet_counter);
    uip_udp_packet_send(conn, buf, strlen(buf));
    printf("Probe signal is sent");
}

/*---------------------------------------------------------------------------*/


PROCESS_THREAD(ipv6_ble_client_process, ev, data)
{
    PROCESS_BEGIN();
    PRINTF("CC26XX-IPv6-over-BLE client started\n");

    conn = udp_new(&server_addr, UIP_HTONS(SERVER_PORT), NULL);
    udp_bind(conn, UIP_HTONS(CLIENT_PORT));

    etimer_set(&probe_timer, PROBE_SIGNAL_INTERVAL);  // set up a timer event for calling probe_signal() function

    etimer_set(&timer, CLIENT_SEND_INTERVAL);  // set up a timer event for calling data_signal() function

    while(1) 
    {
        PROCESS_YIELD();     // yield waiting for an timer event or other event
        if((ev == PROCESS_EVENT_TIMER) && (data == &timer)) 
        {
            // timer event received so process it and then reschedule again.
            data_signal();    
            etimer_set(&timer, CLIENT_SEND_INTERVAL);
        }
        if((ev == PROCESS_EVENT_TIMER) && (data == &probe_timer)) 
        {
            // timer event received so process it and then reschedule again.
            probe_signal();    
            etimer_set(&timer, PROBE_SIGNAL_INTERVAL);
        } 
        else if(ev == tcpip_event) 
        {
            printf("TCPIP event occured\n");
            tcpip_handler();
        }
    }

  PROCESS_END();
}
...