📄 n_core.c
字号:
/*
* Copyright (c) 2004-2005, Dennis Kuschel.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* @file n_core.c
* @brief nano layer, core file
* @author Dennis Kuschel
*
* This file is originally from the pico]OS realtime operating system
* (http://picoos.sourceforge.net).
*
* CVS-ID $Id: n_core.c,v 1.8 2005/02/22 20:39:27 dkuschel Exp $
*/
#define _N_CORE_C
#include "../src/nano/privnano.h"
/* check features */
#if NOSCFG_FEATURE_CPUUSAGE != 0
#if POSCFG_FEATURE_SLEEP == 0
#error POSCFG_FEATURE_SLEEP not enabled
#endif
#if POSCFG_FEATURE_IDLETASKHOOK == 0
#error POSCFG_FEATURE_IDLETASKHOOK not enabled
#endif
#if POSCFG_FEATURE_JIFFIES == 0
#error POSCFG_FEATURE_JIFFIES not enabled
#endif
#endif
#if POSCFG_TASKSTACKTYPE == 0
#if NOSCFG_FEATURE_MEMALLOC == 0
#error NOSCFG_FEATURE_MEMALLOC not enabled
#endif
#endif
/*---------------------------------------------------------------------------
* PROTOTYPES, TYPEDEFS AND VARIABLES
*-------------------------------------------------------------------------*/
/* imports */
#if (NOSCFG_FEATURE_MEMALLOC != 0) && (NOSCFG_MEM_MANAGER_TYPE == 1)
extern void nos_initMem(void);
#endif
#if (NOSCFG_FEATURE_CONIN != 0) || (NOSCFG_FEATURE_CONOUT != 0)
extern void nos_initConIO(void);
#endif
#if NOSCFG_FEATURE_BOTTOMHALF != 0
extern void nos_initBottomHalfs(void);
#endif
#if NOSCFG_FEATURE_REGISTRY != 0
extern void nos_initRegistry(void);
#endif
/* private */
static void nano_init(void *arg);
#if NOSCFG_FEATURE_CPUUSAGE != 0
static void nano_idlehook(void);
static void nano_initCpuUsage(void);
static unsigned long idle_counter_g = 0;
static unsigned long idle_loops_g;
static unsigned long idle_loops_100p_g;
static UVAR_t idle_predivide_g;
static JIF_t idle_jiffies_g = 0;
#define IDLE_MULBITS 11 /* = 2048; 2048 / 20 = 102.4 ~ 100% */
#define IDLE_PREDIVIDER (1<<IDLE_MULBITS)
#define IDLE_MIN_TICKS 200
#define IDLE_FAST_DIV 4
#if HZ >= (IDLE_MIN_TICKS * IDLE_FAST_DIV)
#define IDLE_PERIOD (HZ / IDLE_FAST_DIV)
#define IDLE_INIT_MULT IDLE_FAST_DIV
#else
#define IDLE_PERIOD HZ
#define IDLE_INIT_MULT 1
#endif
#endif /* NOSCFG_FEATURE_CPUUSAGE */
struct {
POSTASKFUNC_t func;
void *arg;
} taskparams_g;
/*---------------------------------------------------------------------------
* CPU USAGE MEASUREMENT
*-------------------------------------------------------------------------*/
#if NOSCFG_FEATURE_CPUUSAGE != 0
static void nano_idlehook(void)
{
JIF_t jif;
POS_LOCKFLAGS;
jif = jiffies;
POS_SCHED_LOCK;
if (POS_TIMEAFTER(jif, idle_jiffies_g))
{
idle_loops_g = idle_counter_g;
idle_jiffies_g = jif + HZ;
idle_counter_g = 0;
}
else
{
idle_counter_g++;
}
POS_SCHED_UNLOCK;
}
/*-------------------------------------------------------------------------*/
static void nano_initCpuUsage(void)
{
(void) posInstallIdleTaskHook(nano_idlehook);
posTaskSleep(1);
idle_jiffies_g = jiffies + IDLE_PERIOD;
idle_counter_g = 0;
posTaskSleep(IDLE_PERIOD + 2);
#if IDLE_INIT_MULT > 1
idle_loops_g *= IDLE_INIT_MULT;
#endif
idle_loops_100p_g = idle_loops_g;
if (idle_loops_100p_g == 0)
idle_loops_100p_g = 1;
idle_predivide_g = 0;
if (idle_loops_100p_g > 1L*(IDLE_PREDIVIDER << (31-(2*IDLE_MULBITS))))
{
idle_predivide_g = 1;
idle_loops_100p_g /= IDLE_PREDIVIDER;
}
}
/*-------------------------------------------------------------------------*/
UVAR_t nosCpuUsage(void)
{
unsigned long tmp;
UINT_t p;
JIF_t jif;
POS_LOCKFLAGS;
jif = jiffies;
POS_SCHED_LOCK;
tmp = idle_loops_g;
if (POS_TIMEAFTER(jif, idle_jiffies_g + HZ))
{
idle_jiffies_g = jif + HZ;
idle_counter_g = 0;
idle_loops_g = 0;
}
POS_SCHED_UNLOCK;
if (idle_predivide_g != 0)
tmp /= IDLE_PREDIVIDER;
tmp = idle_loops_100p_g - tmp;
if ((long)tmp < 0)
return 0;
p = ((UINT_t) ((tmp << IDLE_MULBITS) / idle_loops_100p_g)) / 20;
if (p > 100) p = 100;
return (UVAR_t) p;
}
#endif /* NOSCFG_FEATURE_CPUUSAGE */
/*---------------------------------------------------------------------------
* NANO LAYER SEMAPHORE FUNCTIONS
*-------------------------------------------------------------------------*/
#if NOSCFG_FEATURE_SEMAPHORES != 0
#if NOSCFG_FEATURE_REGISTRY != 0
NOSSEMA_t nosSemaCreate(INT_t initcount, UVAR_t options, const char *name)
{
POSSEMA_t sem;
REGELEM_t re;
re = nos_regNewSysKey(REGTYPE_SEMAPHORE,
name == NULL ? (const char*)"s*" : name);
if (re == NULL)
return NULL;
(void) options;
sem = posSemaCreate(initcount);
if (sem == NULL)
{
nos_regDelSysKey(REGTYPE_SEMAPHORE, NULL, re);
}
else
{
nos_regEnableSysKey(re, sem);
POS_SETEVENTNAME(sem, re->name);
}
return (NOSSEMA_t) sem;
}
#if POSCFG_FEATURE_SEMADESTROY != 0
void nosSemaDestroy(NOSSEMA_t sema)
{
if (sema != NULL)
{
nos_regDelSysKey(REGTYPE_SEMAPHORE, sema, NULL);
posSemaDestroy((POSSEMA_t) sema);
}
}
#endif /* POSCFG_FEATURE_SEMADESTROY */
#endif /* NOSCFG_FEATURE_REGISTRY */
#endif /* NOSCFG_FEATURE_SEMAPHORES */
/*---------------------------------------------------------------------------
* NANO LAYER MUTEX FUNCTIONS
*-------------------------------------------------------------------------*/
#if NOSCFG_FEATURE_MUTEXES != 0
#if NOSCFG_FEATURE_REGISTRY != 0
NOSMUTEX_t nosMutexCreate(UVAR_t options, const char *name)
{
POSMUTEX_t mtx;
REGELEM_t re;
re = nos_regNewSysKey(REGTYPE_MUTEX,
name == NULL ? (const char*)"m*" : name);
if (re == NULL)
return NULL;
(void) options;
mtx = posMutexCreate();
if (mtx == NULL)
{
nos_regDelSysKey(REGTYPE_MUTEX, NULL, re);
}
else
{
nos_regEnableSysKey(re, mtx);
POS_SETEVENTNAME(mtx, re->name);
}
return (NOSMUTEX_t) mtx;
}
#if POSCFG_FEATURE_MUTEXDESTROY != 0
void nosMutexDestroy(NOSMUTEX_t mutex)
{
if (mutex != NULL)
{
nos_regDelSysKey(REGTYPE_MUTEX, mutex, NULL);
posMutexDestroy((POSMUTEX_t) mutex);
}
}
#endif /* POSCFG_FEATURE_MUTEXDESTROY */
#endif /* NOSCFG_FEATURE_REGISTRY */
#endif /* NOSCFG_FEATURE_MUTEXES */
/*---------------------------------------------------------------------------
* NANO LAYER MESSAGE BOX FUNCTIONS
*-------------------------------------------------------------------------*/
#if NOSCFG_FEATURE_MSGBOXES != 0
void* nosMessageAlloc(UINT_t msgSize)
{
void *buf;
#if POSCFG_MSG_MEMORY != 0
if (msgSize > POSCFG_MSG_BUFSIZE)
return NULL;
buf = posMessageAlloc();
#else
#if NOSCFG_FEATURE_MEMALLOC == 0
#error NOSCFG_FEATURE_MEMALLOC not enabled
#endif
buf = nosMemAlloc(msgSize);
#endif
return buf;
}
void nosMessageFree(void *buf)
{
#if POSCFG_MSG_MEMORY != 0
posMessageFree(buf);
#else
nosMemFree(buf);
#endif
}
VAR_t nosMessageSend(void *buf, NOSTASK_t taskhandle)
{
VAR_t rc;
rc = posMessageSend(buf, (POSTASK_t) taskhandle);
#if POSCFG_MSG_MEMORY == 0
if (rc != E_OK)
nosMemFree(buf);
#endif
return rc;
}
#endif /* NOSCFG_FEATURE_MSGBOXES */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -