static void timerHandler(int sig, siginfo_t *si, void *uc)
{
timer_t *tidp;
tidp = si->si_value.sival_ptr;
if (*tidp == firstTimerID)
TASK1(Task2ms_Raster);
else if (*tidp == secondTimerID)
TASK2(Task10ms_Raster);
else if (*tidp == thirdTimerID)
TASK3(Task100ms_Raster);
}
static int makeTimer(char *name, timer_t *timerID, int expireMS, int intervalMS)
{
//sigset_t mask;
struct sigevent te;
struct itimerspec its;
struct sigaction sa;
int sigNo = SIGRTMIN;
/* Set up signal handler. */
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = timerHandler;
sigemptyset(&sa.sa_mask);
if (sigaction(sigNo, &sa, NULL) == -1)
{
perror("sigaction");
}
/* Set and enable alarm */
te.sigev_notify = SIGEV_SIGNAL;
te.sigev_signo = sigNo;
te.sigev_value.sival_ptr = timerID;
timer_create(CLOCK_REALTIME, &te, timerID);
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = intervalMS * 1000000;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = expireMS * 1000000;
timer_settime(*timerID, 0, &its, NULL);
return 1;
}
int CreateSocket()
{
socklen_t len = sizeof(client);
// Socket creation for UDP
acceptSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (acceptSocket == -1)
{
printf("Failure: socket creation is failed, failure code\n");
return 1;
}
else
{
printf("Socket started!\n");
}
//non blocking mode
/* rc = ioctl(acceptSocket, FIONBIO, (char *)&flag);
if (rc < 0)
{
printf("\n ioctl() failed \n");
return 0;
}*/
//Bind the socket
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
rc = bind(acceptSocket, (struct sockaddr*) &addr, sizeof(addr));
if (rc == -1)
{
printf("Failure: listen, failure code:\n");
return 1;
}
else
{
printf("Socket an port %d \n", port);
}
if (acceptSocket == -1)
{
printf("Fehler: accept, fehler code:\n");
return 1;
}
else
{
while (rc != -1)
{
rc = recvfrom(acceptSocket, buf, 256, 0, (struct sockaddr*) &client,
&len);
if (rc == 0)
{
printf("Server has no connection..\n");
break;
}
if (rc == -1)
{
printf("something went wrong with data %s", strerror(errno));
break;
}
XcpIp_RxCallback((uint16) rc, (uint8*) buf, (uint16) port);
makeTimer("First Timer", &firstTimerID, 2, 2); //2ms
makeTimer("Second Timer", &secondTimerID, 10, 10); //10ms
makeTimer("Third Timer", &thirdTimerID, 100, 100); //100ms
while (1)
;;
}
}
close(acceptSocket);
return 0;
}
int main()
{
Xcp_Initialize();
CreateSocket();
return 2;
}
void XcpApp_IpTransmit(uint16 XcpPort, Xcp_StatePtr8 pBytes, uint16 numBytes)
{
if ((long) XcpPort == port)
{
sentbytes = sendto(acceptSocket, (char*) pBytes, (long) numBytes, 0,
(struct sockaddr*) &client, sizeof(client));
}
XcpIp_TxCallback(port, (uint16) sentbytes);
}
Я работаю над клиентской и серверной архитектурой. Код сервера показан выше, и я создал сокет, чтобы получить запрос от клиента через IP-адрес и номер порта. Сервер ожидает запроса от клиента и отправляет ответ клиенту. когда он получает данные от клиента, он должен вызывать задачу таймера (т.е. callBackTimers в моем коде), для этого я также создал таймер для вызова задачи на каждые 2 мс, 10 мс и 100 мс.
Мой вопрос: в режиме отладки - контроль достигает вызова функции maketimer, но он не запускается автоматически (я не добавил точку останова). он останавливается при maketimer3. Как заставить его работать без остановки?
Как я уже сказал в предыдущем вопросе, это, вероятно, связано с вашей функцией CreateSocket
, а именно:
while(rc!=-1)
{
rc=recvfrom(acceptSocket,buf, 256, 0, (struct sockaddr*) &client, &len);
if(rc==0)
{
printf("Server has no connection..\n");
break;
}
if(rc==-1)
{
printf("something went wrong with data %s", strerror(errno));
break;
}
XcpIp_RxCallback( (uint16) rc, (uint8*) buf, (uint16) port );
makeTimer("First Timer", &firstTimerID, 2, 2); //2ms
makeTimer("Second Timer", &secondTimerID, 10, 10); //10ms
makeTimer("Third Timer", &thirdTimerID, 100, 100); //100ms
while(1)
;;
}
Вы каждый раз создаете новые таймеры через этот цикл. Вы никогда не удаляете их. Существует ограничение на количество таймеров, которые вы можете создать. От man (2) timer_create
:
Ядро предварительно распределяет "сигнал в реальном времени в реальном времени" для каждого таймера, созданного с помощью функции timer_create(). Следовательно, количество таймеров ограничено пределом ресурса RLIMIT_SIGPENDING (см. Setrlimit (2)).
Вы не проверяете статус кода возврата timer_create
и я предполагаю, что у вас закончились таймеры, а после этого они просто терпят неудачу.
(Кстати, не уверен, что такое while(1);;
должен это делать. Я понимаю разочарование, которое вы должны чувствовать, но это становится чем-то вроде движущейся цели.)
Вот поспешно (но я думаю, точнее) нарезал версию вашего кода. Из-за вашего while(1);
в CreateSocket
он просто собирается создать 3 таймера. Если вы запустите его, вы увидите, что запущены TASKS1/2/3. Это само по себе не является вашей проблемой.
#define _POSIX_C_SOURCE 199309
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
timer_t firstTimerID, secondTimerID, thirdTimerID;
void TASK1() {printf("task 1\n");}
void TASK2() {printf("task 2\n");}
void TASK3() {printf("task 3\n");}
static void timerHandler(int sig, siginfo_t *si, void *uc)
{
timer_t *tidp;
tidp = si->si_value.sival_ptr;
if (*tidp == firstTimerID)
TASK1();
else if (*tidp == secondTimerID)
TASK2();
else if (*tidp == thirdTimerID)
TASK3();
}
static int makeTimer(char *name, timer_t *timerID, int expireMS, int intervalMS)
{
//sigset_t mask;
struct sigevent te;
struct itimerspec its;
struct sigaction sa;
int sigNo = SIGRTMIN;
/* Set up signal handler. */
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = timerHandler;
sigemptyset(&sa.sa_mask);
if (sigaction(sigNo, &sa, NULL) == -1)
{
perror("sigaction");
}
/* Set and enable alarm */
te.sigev_notify = SIGEV_SIGNAL;
te.sigev_signo = sigNo;
te.sigev_value.sival_ptr = timerID;
timer_create(CLOCK_REALTIME, &te, timerID);
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = intervalMS * 1000000;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = expireMS * 1000000;
timer_settime(*timerID, 0, &its, NULL);
return 1;
}
int CreateSocket()
{
int rc = 5;
while (rc != -1)
{
makeTimer("First Timer", &firstTimerID, 2, 2); //2ms
makeTimer("Second Timer", &secondTimerID, 10, 10); //10ms
makeTimer("Third Timer", &thirdTimerID, 100, 100); //100ms
while (1);;
}
return 0;
}
int main()
{
CreateSocket();
return 2;
}
Позаботьтесь о проблеме с петлей и посмотрите, куда вы должны идти оттуда. Создайте 3 таймера. Если вы хотите, чтобы они уходили только один раз на один сокет, то либо не имеют значения интервала, чтобы они не повторяли или не выключали таймеры (т.е. нулевое значение значения/интервала) после первого раза, когда они уходят, Но в любом случае вы должны их повторно использовать.
makeTimer()
?