Hard pin thread for 1 cpu with disabled interrupts, sheduler etc.
Andrey Smagin
samspeed at mail.ru
Sat Nov 7 22:58:25 UTC 2020
Hi, I wrote some kernel module with realtime kernel thread for latency test.
With enabled interrupts latensy very bad for gpio realtime driving.
Adding begin\end critical section make jitter 200ns(its perfect) but hang kernel
after 15 seconds of work on my orange pi-zero.
How to disable watchdog or any else ?
#include <sys/types.h>
#include <sys/module.h>
#include <sys/systm.h> /* uprintf */
#include <sys/errno.h>
#include <sys/param.h> /* defines used in kernel.h */
#include <sys/kernel.h> /* types used in module initialization */
#include <sys/kthread.h>
#include <sys/proc.h>
#include <sys/sched.h>
#include <sys/cpuset.h>
#include <sys/timetc.h>
#include <sys/time.h>
#include <sys/mutex.h>
static int dTimeMax = 0;
static int dTimeMin = 0x7FFFFFFF;
static unsigned int dTimeAvg = 0;
static unsigned int IntCount = 0;
static int Tick;
static volatile int ThreadExit;
static struct thread *ThreadData;
static cpuset_t CpuSet;
static u_int64_t MaxTimer = 0, MinTimer = 0, Timer = 0;
static void ThreadFunc()
{
cpuset_setthread( ThreadData->td_tid, &CpuSet );
thread_lock( ThreadData );
sched_class( ThreadData, PRI_REALTIME );
thread_unlock( ThreadData );
sched_pin();
while( ThreadExit == 0 )
{
u_int T1,T2;
for( ; !ThreadExit ; Timer++)
{
T1=timecounter->tc_get_timecount(timecounter);
T2=timecounter->tc_get_timecount(timecounter);
Tick = T2 - T1;
if ( Tick > dTimeMax ) { MaxTimer = Timer; dTimeMax = Tick; }
if ( Tick < dTimeMin ) { MinTimer = Timer; dTimeMin = Tick; }
if ( Tick > 1 )
{
IntCount++;
if ( dTimeAvg > 0 )
dTimeAvg = ( dTimeAvg * 15 + Tick * 16 ) / 16;
else
dTimeAvg = Tick*16;
}
}
}
ThreadExit = 2;
sched_unpin();
kthread_exit();
}
static struct kthread_desc ThreadDesc = { "gpio_rt_thread", ThreadFunc, &ThreadData };
static int gpio_rt_loader(struct module *m, int what, void *arg)
{
int err = 0;
switch (what) {
case MOD_LOAD: /* kldload */
ThreadExit = 0;
memset( &CpuSet, 0, sizeof(CpuSet) );
CPU_SET( 3, &CpuSet );
kthread_start( &ThreadDesc );
uprintf("GPIO realtime extenions KLD loaded.\n");
break;
case MOD_UNLOAD:
ThreadExit = 1;
while( ThreadExit == 1 );
uprintf("GPIO jitter dTimeMax = %d (%lld) \tdTimeAvg = %d \tdTimeMin = %d(%lld) \t%lld\t%d\t\n", dTimeMax, MaxTimer, dTimeAvg/16, dTimeMin, MinTimer, Timer, IntCount );
uprintf("GPIO realtime extenions KLD unloaded.\n");
break;
default:
err = EOPNOTSUPP;
break;
}
return(err);
}
static moduledata_t gpio_rt_mod = { "gpio_rt", gpio_rt_loader, NULL };
DECLARE_MODULE(gpio_rt, gpio_rt_mod, SI_SUB_KLD, SI_ORDER_ANY);
--
Andrey Smagin
More information about the freebsd-hackers
mailing list