i want create gateway pass messages can bus , lcm , vice-versa. if message in lcm sent @ specific frequency, copy on can bus should sent @ exact same frequency.
how solve this?
in mind thought 2 threads, 1 each direction converting message 1 system in loop. 2 threads coordinated timer set frequency lower maximum message passing frequency possible. timer sents signal threads after each cycle. threads wait event @ end of each loop, i.e. sleep , free resources until event occures. implemented idea resulting frequencies not constant. doing conceptually wrong?
a solution should run on windows, utilize either native windows api or boost threads example. gateway should real-time capable.
for windows, timesetevent can used set event @ regular interval, although msdn lists obsolete function. replacement timesetevent uses callback function, you'd have set event in callback function.
you can increase tick rate it's default 64hz == 15.625 ms down 1 ms using timebeginperiod
some games have threads run @ fixed frequencies, , poll high frequency counter , sleep when there's enough delay time remaining in current cycle. prevent drift, delay based off original reading of high frequency counter. example code windows xp compatible, sleep(1) can take 2 milliseconds. dwlatestep diagnostic aid , incremented if code exceeds cycle period.
/* code thread run @ fixed frequency */ typedef unsigned long long ui64; /* unsigned 64 bit int */ #define freq 400 /* frequency */ dword dwlatestep; /* late step count */ large_integer liperffreq; /* 64 bit frequency */ large_integer liperftemp; /* used query */ ui64 ufreq = freq; /* process frequency */ ui64 uorig; /* original tick */ ui64 uwait; /* tick rate / freq */ ui64 urem = 0; /* tick rate % freq */ ui64 uprev; /* previous tick based on original tick */ ui64 udelta; /* current tick - previous */ ui64 u2ms; /* 2ms of ticks */ ui64 i; /* ... */ /* wait event start thread */ queryperformancefrequency(&liperffreq); u2ms = ((ui64)(liperffreq.quadpart)+499) / ((ui64)500); timebeginperiod(1); /* set period 1ms */ sleep(128); /* wait stabilize */ queryperformancecounter((plarge_integer)&liperftemp); uorig = uprev = liperftemp.quadpart; for(i = 0; < (ufreq*30); i++){ /* update uwait , urem based on urem */ uwait = ((ui64)(liperffreq.quadpart) + urem) / ufreq; urem = ((ui64)(liperffreq.quadpart) + urem) % ufreq; /* wait uwait ticks */ while(1){ queryperformancecounter((plarge_integer)&liperftemp); udelta = (ui64)(liperftemp.quadpart - uprev); if(udelta >= uwait) break; if((uwait - udelta) > u2ms) sleep(1); } if(udelta >= (uwait*2)) dwlatestep += 1; uprev += uwait; /* fixed frequency code goes here */ /* along type of break when done */ } timeendperiod(1); /* restore period */
Comments
Post a Comment