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