NutConfos.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NUTCONFOS_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <string.h>
#include <ctype.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "XVarBank.h"
#include "NutConfos.h"
#if defined(NUTOS)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Return the effective server name.
*
* \return Pointer to the print server name
*/
char *NutGetPrintServerName(void)
{
_PrintRecord *prnrec = GrabPrintRecord();
static char name[16];
int sch;
memcpy(name, prnrec->PrintServerName, sizeof(name));
/*
* Is it the effective name ?
*/
for (sch = 0; name[sch] && sch < sizeof(name); sch++)
if (!isprint(name[sch])) {
sprintf(name, "XP-%02X%02X%02X",
prnrec->UniqueMAC[3], prnrec->UniqueMAC[4], prnrec->UniqueMAC[5]);
/*
* Restore the print server name
*/
memcpy(prnrec->PrintServerName, name, sizeof(prnrec->PrintServerName));
break;
}
return (char *)name;
}
/*!
* \brief Save print server name in non-volatile memory.
*
* \param name Name of the print server.
*/
void NutSetPrintServerName(char *name)
{
_PrintRecord *prnrec = GrabPrintRecord();
memcpy(prnrec->PrintServerName, name, sizeof(prnrec->PrintServerName));
}
/*!
* \brief Load Nut/OS configuration from non-volatile memory.
*
* This routine is automatically called during system
* initialization.
*
* \return 0 if OK, -1 if configuration isn't available.
*/
int NutLoadConfig(void)
{
_PrintCfg *prncfg = GrabPrintConfig();
confos = prncfg->confos;
if (confos.size != sizeof(CONFOS) || confos.magic[0] != 'O' || confos.magic[1] != 'S') {
return -1;
}
return 0;
}
/*!
* \brief Save Nut/OS configuration in non-volatile memory.
*
* \return 0 if OK, -1 on failures.
*/
int NutSaveConfig(void)
{
_PrintCfg *prncfg = GrabPrintConfig();
confos.size = sizeof(CONFOS);
confos.magic[0] = 'O';
confos.magic[1] = 'S';
prncfg->confos = confos;
return 0;
}
#endif
NutConfos.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef NUTCONFOS_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NUTCONFOS_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/*!
* \brief Non-volatile memory location.
*
* Offset into non-volatile memory, where Nut/OS stores the system
* configuration. The default may be overridden by the Configurator.
*/
#ifndef CONFOS_EE_OFFSET
#define CONFOS_EE_OFFSET 0
#endif
#define CONFOS_EE_MAGIC "OS"
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Operating system configuration type.
*/
typedef struct _CONFOS CONFOS;
/*!
* \struct _CONFOS confos.h sys/confos.h
* \brief Operating system configuration structure.
*
* Applications may directly access the global variable \ref confos to
* read or modify the current configuration.
*/
#if defined(__ICCARM__)
#pragma diag_suppress = Pa039 // Use of address of unaligned structure member
#pragma pack ( 1 )
#endif
struct _CONFOS {
/*! \brief Size of this structure.
*
* Used by Nut/Net to verify, that the structure contents is valid
* after reading it from non-volatile memory.
*/
u_char size;
/*! \brief Magic cookie.
*
* Contains CONFOS_EE_MAGIC.
*/
u_char magic[2];
/*! \brief Host name of the system.
*/
char hostname[16];
};
#if defined(__ICCARM__)
#pragma pack ( )
#endif
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
#ifdef NUTCONFOS_C
#define EXTERN
#else
#define EXTERN extern
#endif
/*!
* \brief Global system configuration structure.
*
* Contains the current system configuration. Nut/OS will load
* this structure from non-volatile memory during initialization.
*/
EXTERN CONFOS confos;
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
#if defined(NUTOS)
char *NutGetPrintServerName(void);
void NutSetPrintServerName(char *);
int NutLoadConfig(void);
int NutSaveConfig(void);
#else
#define NutGetPrintServerName() ""
#define NutSetPrintServerName(name)
#define NutLoadConfig() (0)
#define NutSaveConfig() (0)
#endif
#undef EXTERN
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
NutDebug.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NUTDEBUG_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "NutThread.h"
#include "NutTimer.h"
#include "NutEvent.h"
#include "NutHeap.h"
#include "NutDebug.h"
#if defined(NUTOS)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
static char *states[] = { "TRM", "RUN", "RDY", "SLP" };
/* 12345678 12345678 1234 123 12345678 12345678 12345678 123456789 */
static const char qheader[] = "Handle Name Prio Sta Queue Timer StackPtr FreeMem\r\n";
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Dump system queue contents.
*
* \param stream Pointer to a previously opened stream associated to
* a debug device.
* \param tdp Pointer to the queue.
*
* \warning Interrupts are disabled inside this funtion.
*/
void NutDumpThreadQueue(FILE * stream, NUTTHREADINFO * tdp)
{
static const char fmt[] = "%08lX %-8s %4u %s %08lX %08lX %08lX %9lu %s\r\n";
if (tdp == SIGNALED)
fputs("SIGNALED\r\n", stream);
else {
while (tdp) {
fprintf(stream, fmt, (uptr_t) tdp, tdp->td_name, tdp->td_priority,
states[tdp->td_state], (uptr_t) tdp->td_queue,
(uptr_t) tdp->td_timer, tdp->td_sp,
(uptr_t) tdp->td_sp - (uptr_t) tdp->td_memory,
*((u_long *) tdp->td_memory) != DEADBEEF
&& *((u_long *) (tdp->td_memory + 4)) != DEADBEEF
&& *((u_long *) (tdp->td_memory + 8)) != DEADBEEF
&& *((u_long *) (tdp->td_memory + 12)) != DEADBEEF ? "FAIL" : "OK");
tdp = tdp->td_qnxt;
}
}
}
/*!
* \brief Dump system thread list.
*
* \param stream Pointer to a previously opened stream associated to
* a debug device.
*
* \warning Interrupts are disabled inside this funtion.
*/
void NutDumpThreadList(FILE * stream)
{
static const char fmt1[] = "%08lX %-8s %4u %s %08lX %08lX %08lX %9lu %s";
static const char fmt2[] = " %08lX";
NUTTHREADINFO *tqp;
NUTTHREADINFO *tdp;
fputs(qheader, stream);
tdp = nutThreadList;
while (tdp) {
fprintf(stream, fmt1, (uptr_t) tdp, tdp->td_name, tdp->td_priority,
states[tdp->td_state], (uptr_t) tdp->td_queue,
(uptr_t) tdp->td_timer, tdp->td_sp,
(uptr_t) tdp->td_sp - (uptr_t) tdp->td_memory, *((u_long *) tdp->td_memory) != DEADBEEF ? "FAIL" : "OK");
if (tdp->td_queue) {
tqp = *(NUTTHREADINFO **) (tdp->td_queue);
if (tqp == SIGNALED)
fputs("SIGNALED", stream);
else {
while (tqp) {
fprintf(stream, fmt2, (uptr_t) tqp);
tqp = tqp->td_qnxt;
}
}
}
fputs("\r\n", stream);
tdp = tdp->td_next;
}
}
/*!
* \brief Dump system timer list.
*
* \param stream Pointer to a previously opened stream associated to
* a debug device.
*
* \warning Interrupts are disabled inside this funtion.
*/
void NutDumpTimerList(FILE * stream)
{
static const char wname[] = "NutThreadWake";
static const char tname[] = "NutEventTimeout";
static const char theader[] = "Address Ticks Left Callback\r\n";
static const char fmt1[] = "%08lX%6lu%6lu ";
static const char fmt2[] = "%09lX";
static const char fmt3[] = "(%08lX)\r\n";
NUTTIMERINFO *tnp;
if ((tnp = nutTimerList) != 0) {
fputs(theader, stream);
while (tnp) {
fprintf(stream, fmt1, (uptr_t) tnp, tnp->tn_ticks, tnp->tn_ticks_left);
if (tnp->tn_callback == NutThreadWake)
fputs(wname, stream);
else if (tnp->tn_callback == NutEventTimeout)
fputs(tname, stream);
else
fprintf(stream, fmt2, (u_long) ((uptr_t) tnp->tn_callback) << 1);
fprintf(stream, fmt3, (uptr_t) tnp->tn_arg);
tnp = tnp->tn_next;
}
}
}
/*!
* \brief Control OS tracing.
*
* \param stream Pointer to a previously opened stream associated to
* a debug device or null to disable trace output.
* \param flags Flags to enable specific traces.
*/
void NutTraceOs(FILE * stream, u_char flags)
{
if (stream)
__os_trs = stream;
if (__os_trs)
__os_trf = flags;
else
__os_trf = 0;
}
/*!
* \brief Dump free node list of heap memory.
*
* \param stream Pointer to a previously opened stream associated to
* a debug device.
*/
void NutDumpHeap(FILE * stream)
{
static const char fmt1[] = "%08lx %9ld\r\n";
static const char fmt2[] = "%lu counted, but %lu reported\r\n";
static const char fmt3[] = "%lu bytes free\r\n";
HEAPNODE *node;
size_t sum = 0;
size_t avail;
fputs("\r\n", stream);
for (node = heapFreeList; node; node = node->hn_next) {
sum += node->hn_size;
fprintf(stream, fmt1, (uptr_t) node, node->hn_size);
/* TODO: Remove hardcoded RAMSTART and RAMEND */
if ((uptr_t) node < 0x20000000 || (uptr_t) node > 0x21ffffff)
break;
}
if ((avail = NutHeapAvailable()) != sum)
fprintf(stream, fmt2, sum, avail);
else
fprintf(stream, fmt3, avail);
}
/*!
* \brief Control dynamic memory tracing.
*
* \param stream Pointer to a previously opened stream or null to
* disable trace output.
* \param flags Flags to enable specific traces.
*/
void NutTraceHeap(FILE * stream, u_char flags)
{
if (stream)
__heap_trs = stream;
if (__heap_trs)
__heap_trf = flags;
else
__heap_trf = 0;
}
#endif
NutDebug.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef NUTDEBUG_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NUTDEBUG_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <stdio.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "NutThread.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
#ifdef NUTDEBUG_C
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN FILE *__os_trs;
EXTERN u_char __os_trf;
EXTERN FILE *__heap_trs;
EXTERN u_char __heap_trf;
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
#if defined(NUTOS)
void NutTraceOs(FILE *stream, u_char flags);
void NutDumpThreadQueue(FILE *stream, NUTTHREADINFO *tdp);
void NutDumpThreadList(FILE *stream);
void NutDumpTimerList(FILE *stream);
void NutTraceHeap(FILE *stream, u_char flags);
void NutDumpHeap(FILE *stream);
#else
#define NutTraceOs(stream, flags)
#define NutDumpThreadQueue(stream, tdp)
#define NutDumpThreadList(stream)
#define NutDumpTimerList(stream)
#define NutTraceHeap(stream, flags)
#define NutDumpHeap(stream)
#endif
#undef EXTERN
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
NutDevice.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef NUTDEVICE_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NUTDEVICE_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "NutFile.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
#define IFTYP_RAM 0 /*!< \brief RAM device */
#define IFTYP_ROM 1 /*!< \brief ROM device */
#define IFTYP_STREAM 2 /*!< \brief Stream device */
#define IFTYP_NET 3 /*!< \brief Net device */
#define IFTYP_TCPSOCK 4 /*!< \brief TCP socket */
#define IFTYP_CHAR 5 /*!< \brief Character stream device */
#define IFTYP_CAN 6 /*!< \brief CAN device */
#define IFTYP_BLKIO 7 /*!< \brief Block I/O device */
#define IFTYP_FS 16 /*!< \brief file system device */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Device structure type.
*/
typedef struct _NUTDEVICE NUTDEVICE;
/*!
* \brief Device structure.
*
* Each device driver provides a global variable of this type.
* Applications use NutRegisterDevice() to bind the device
* driver to the application code. Except this call, applications
* refer to device drivers by the name of the device when using
* standard C functions like _open() or fopen().
*
* More than one device driver may be available for the same
* hardware device. Typically these drivers provide the same
* name for the device and applications must not refer to
* more than one device driver with the same name.
*/
struct _NUTDEVICE {
/*!
* \brief Link to the next device structure.
*/
NUTDEVICE *dev_next;
/*!
* \brief Unique device name.
*/
char dev_name[9];
/*!
* \brief Type of interface.
*
* May be any of the following:
* - IFTYP_RAM
* - IFTYP_ROM
* - IFTYP_STREAM
* - IFTYP_NET
* - IFTYP_TCPSOCK
* - IFTYP_CHAR
*/
u_char dev_type;
/*!
* \brief Hardware base address.
*
* Will be set by calling NutRegisterDevice(). On some device
* drivers this address may be fixed.
*/
uptr_t dev_base;
/*! \brief Interrupt registration number.
*
* Will be set by calling NutRegisterDevice(). On some device
* drivers the interrupt may be fixed.
*/
u_char dev_irq;
/*! \brief Interface control block.
*
* With stream devices, this points to the IFSTREAM structure and
* with network devices this is a pointer to the IFNET structure.
*/
void *dev_icb;
/*!
* \brief Driver control block.
*
* Points to a device specific information block.
*/
void *dev_dcb;
/*!
* \brief Driver initialization routine.
*
* This routine is called during device registration.
*/
int (*dev_init) (NUTDEVICE *);
/*!
* \brief Driver control function.
*
* Used to modify or query device specific settings.
*/
int (*dev_ioctl) (NUTDEVICE *, int, void *);
/*!
* \brief Read from device.
*/
int (*dev_read) (NUTFILE *, void *, int);
/*!
* \brief Write to device.
*/
int (*dev_write) (NUTFILE *, CONST void *, int);
/*!
* \brief Open a device or file.
*/
NUTFILE * (*dev_open) (NUTDEVICE *, CONST char *, int, int);
/*!
* \brief Close a device or file.
*/
int (*dev_close) (NUTFILE *);
/*!
* \brief Request file size.
*/
long (*dev_size) (NUTFILE *);
};
/*!
* \brief Device structure type.
*/
typedef struct _NUTVIRTUALDEVICE NUTVIRTUALDEVICE;
/*!
* \brief Virtual device structure.
*/
struct _NUTVIRTUALDEVICE {
NUTVIRTUALDEVICE *vdv_next;
NUTVIRTUALDEVICE *vdv_zero;
u_char vdv_type;
int (*vdv_read) (void *, void *, int);
int (*vdv_write) (void *, CONST void *, int);
int (*vdv_ioctl) (void *, int, void *);
};
/*!
* \brief Stream interface type.
*/
typedef struct _IFSTREAM IFSTREAM;
/*!
* \brief Stream interface information structure.
*
* Deprecated structure. Device drivers should use
* the device control block.
*/
struct _IFSTREAM {
int (*if_input)(NUTDEVICE *); /*!< \brief Wait for input. */
int (*if_output)(NUTDEVICE *); /*!< \brief Initiate output. */
int (*if_flush)(NUTDEVICE *); /*!< \brief Wait until output buffer empty. */
volatile u_char if_rx_idx; /*!< \brief Next input index. */
u_char if_rd_idx; /*!< \brief Next read index. */
volatile u_char if_tx_idx; /*!< \brief Next output index. */
u_char if_wr_idx; /*!< \brief Next write index. */
volatile u_char if_tx_act; /*!< \brief Set if transmitter running. */
u_char if_last_eol; /*!< \brief Last end of line character read. */
u_char if_rx_buf[256]; /*!< \brief Input buffer. */
u_char if_tx_buf[256]; /*!< \brief Output buffer. */
};
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
#ifdef NUTDEVREG_C
#define EXTERN
#else
#define EXTERN extern
#endif
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
#ifdef NUTDEVREG_C
/*!
* \brief Linked list of all registered devices.
*/
NUTDEVICE *nutDeviceList = 0;
#else
EXTERN NUTDEVICE *nutDeviceList;
#endif
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
#if defined(NUTOS)
int NutRegisterDevice(NUTDEVICE * dev, uptr_t base, u_char irq);
NUTDEVICE *NutDeviceLookup(CONST char *name);
#else
#define NutRegisterDevice(dev, base, irq) (-1)
#define NutDeviceLookup(name) (0)
#endif
#undef EXTERN
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
NutDevreg.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NUTDEVREG_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <string.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "NutDevice.h"
#if defined(NUTOS)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Find device entry by name.
*
* \param name Unique device name.
*
* \return Pointer to the ::NUTDEVICE structure.
*/
NUTDEVICE *NutDeviceLookup(CONST char *name)
{
NUTDEVICE *dev;
for (dev = nutDeviceList; dev; dev = dev->dev_next)
if (strcmp(dev->dev_name, name) == 0)
break;
return dev;
}
/*!
* \brief Register and initialize a device.
*
* Initializes the device and adds it to the system device list.
* Applications should call this function during initialization
* for each device they intend to use.
*
* \param dev Pointer to the ::NUTDEVICE structure, which is
* provided by the device driver. This structure
* contains a hardware device name, which must be
* unique among all registered devices. Drivers may
* operate in a different mode using the same hardware,
* like interrupt driven or polling UART drivers.
* Only one of those drivers can be registered, because
* they specify the same hardware device name.
* \param base Hardware base address of this device. Set to 0,
* if the device driver has a fixed hardware address.
* \param irq Hardware interrupt used by this device. Set to 0,
* if the device driver doesn't support configurable
* interupts.
* \return 0 if the device has been registered for the first time
* and initialization was successful.
* The function returns -1 if any device with the same name
* had been registered previously, if the ::NUTDEVICE
* structure is invalid or if the device initialization
* failed.
*/
int NutRegisterDevice(NUTDEVICE * dev, uptr_t base, u_char irq)
{
int rc = -1;
//if ((void *) dev >= RAMSTART) {
if (dev) {
if (base)
dev->dev_base = base;
if (irq)
dev->dev_irq = irq;
if (NutDeviceLookup(dev->dev_name) == 0) {
if(dev->dev_init == 0 || (*dev->dev_init)(dev) == 0) {
//debug_printf("dev_init:succeed\n");
dev->dev_next = nutDeviceList;
nutDeviceList = dev;
rc = 0;
}
else
{
;//debug_printf("1:dev_init:error\n");
}
}
else
{
;//debug_printf("2");
}
}
else
{
;//debug_printf("3");
}
return rc;
}
#endif
NutEvent.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NUTEVENT_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <stdio.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "NutHeap.h"
#include "NutTimer.h"
#include "NutThread.h"
#include "NutEvent.h"
#include "XComm.h"
#ifdef NUTDEBUG
#include "NutDebug.h"
#endif
#if defined(NUTOS)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Timer callback in case of event timeout.
*
* Applications should not call this function. It is provided as a global
* to enable debugging code inspecting the callbacks in the timer list.
*
* \param timer Handle of the elapsed timeout timer.
* \param arg Handle of an event queue.
*
*/
void NutEventTimeout(NUTHANDLE timer, void *arg)
{
NUTTHREADINFO *tqp;
NUTTHREADINFO *volatile *tqpp = arg;
/* Get the queue's root atomically. */
NutEnterCritical();
tqp = *tqpp;
NutExitCritical();
/*
* A signaled queue is an empty queue. So our
* thread already left this queue.
*/
if (tqp != SIGNALED) {
/*
* Walk down the linked list and identify
* the thread by the timer id it is waiting
* for.
*/
while (tqp) {
if (tqp->td_timer == timer) {
/* Found the thread. Remove it from the event queue. */
NutEnterCritical();
*tqpp = tqp->td_qnxt;
if (tqp->td_qpec) {
if (tqp->td_qnxt) {
tqp->td_qnxt->td_qpec = tqp->td_qpec;
}
else {
*tqpp = SIGNALED;
}
tqp->td_qpec = 0;
}
NutExitCritical();
/* Add it to the queue of threads, which are ready to run. */
tqp->td_state = TDS_READY;
NutThreadAddPriQueue(tqp, (NUTTHREADINFO **) & runQueue);
/* Signal the timer entry in the thread's info structure.
This will tell the waiting thread, that it has been
woken up by a timeout. */
tqp->td_timer = SIGNALED;
break;
}
tqpp = &tqp->td_qnxt;
tqp = tqp->td_qnxt;
}
}
}
/*!
* \brief Wait for an event in a specified queue.
*
* Give up the CPU until another thread or an interrupt routine posts an
* event to this queue or until a time-out occurs, whichever comes first.
*
* If previously an event had been posted to this queue without any
* thread waiting, then the thread will not wait for a new event,
* but may still pass CPU control, if another thread with equal or
* higher priority is ready to run.
*
* \param qhp Identifies the queue to wait on.
* \param ms Maximum wait time in milliseconds. To disable timeout,
* set this parameter to NUT_WAIT_INFINITE.
*
* \return 0 if event received, -1 on timeout.
*
* \note Timeout is limited to the granularity of the system timer.
*/
int NutEventWait(volatile NUTHANDLE * qhp, u_long ms)
{
NUTTHREADINFO *tdp;
/* Get the queue's root atomically. */
NutEnterCritical();
tdp = *qhp;
NutExitCritical();
/*
* Check for posts on a previously empty queue.
*/
if (tdp == SIGNALED) {
/* Clear the singaled state. */
NutEnterCritical();
*qhp = 0;
NutExitCritical();
/*
* Even if already signaled, switch to any other thread, which
* is ready to run and has the same or higher priority.
*/
NutThreadYield();
return 0;
}
/*
* Remove the current thread from the list of running threads
* and add it to the specified queue.
*/
NutThreadRemoveQueue(runningThread, &runQueue);
NutThreadAddPriQueue(runningThread, (NUTTHREADINFO **) qhp);
/* Update our thread's state (sleeping + timer) */
runningThread->td_state = TDS_SLEEP;
if (ms) {
runningThread->td_timer = NutTimerStart(ms, NutEventTimeout, (void *) qhp, TM_ONESHOT);
}
else {
runningThread->td_timer = 0;
}
/*
* Switch to the next thread, which is ready to run.
*/
NutThreadResume();
/* If our timer handle is signaled, we were woken up by a timeout. */
if (runningThread->td_timer == SIGNALED) {
runningThread->td_timer = 0;
return -1;
}
return 0;
}
/*!
* \brief Wait for a new event in a specified queue.
*
* Give up the CPU until another thread or an interrupt routine posts
* an event to this queue or until a time-out occurs, whichever comes
* first.
*
* This call is similar to NutEventWait(), but will ignore the SIGNALED
* state of the queue. This way, previously posted events to an empty
* queue are not considered.
*
* \param qhp Identifies the queue to wait on.
* \param ms Maximum wait time in milliseconds. To disable timeout,
* set this parameter to NUT_WAIT_INFINITE.
*
* \return 0 if event received, -1 on timeout.
*
* \note Timeout is limited to the granularity of the system timer.
*/
int NutEventWaitNext(volatile NUTHANDLE * qhp, u_long ms)
{
/*
* Check for posts on a previously empty queue.
*/
NutEnterCritical();
if (*qhp == SIGNALED)
*qhp = 0;
NutExitCritical();
return NutEventWait(qhp, ms);
}
/*!
* \brief Asynchronously post an event to a specified queue.
*
* Wake up the thread with the highest priority waiting on the
* specified queue. But even if the priority of the woken thread is
* higher than the current thread's priority, the current one
* continues running.
*
* If no thread is waiting, then the queue will be set to the SIGNALED
* state.
*
* \note Interrupts must not call this function but use NutEventPostFromIrq()
* to post events to specific queues.
*
* \param qhp Identifies the queue an event is posted to.
*
* \return The number of threads woken up, either 0 or 1.
*
*/
int NutEventPostAsync(volatile NUTHANDLE * qhp)
{
NUTTHREADINFO *td;
NutEnterCritical();
td = *qhp;
NutExitCritical();
/* Ignore signaled queues. */
if (td != SIGNALED) {
/* A thread is waiting. */
if (td) {
/* Remove the thread from the wait queue. */
NutEnterCritical();
*qhp = td->td_qnxt;
if (td->td_qpec) {
if (td->td_qnxt) {
td->td_qnxt->td_qpec = td->td_qpec;
}
else {
*qhp = SIGNALED;
}
td->td_qpec = 0;
}
NutExitCritical();
/* Stop any running timeout timer. */
if (td->td_timer) {
NutTimerStop(td->td_timer);
td->td_timer = 0;
}
/* The thread is ready to run. */
td->td_state = TDS_READY;
NutThreadAddPriQueue(td, (NUTTHREADINFO **) & runQueue);
return 1;
}
/* No thread is waiting. Mark the queue signaled. */
else {
NutEnterCritical();
*qhp = SIGNALED;
NutExitCritical();
}
}
return 0;
}
/*!
* \brief Post an event to a specified queue.
*
* Wake up the thread with the highest priority waiting on this queue.
* If the priority of the waiting thread is higher or equal than the
* current thread's priority, then the current thread is stopped and
* CPU control is passed to the waiting thread.
*
* If no thread is waiting, the queue will be set to the signaled
* state.
*
* \note Interrupts must not call this function but use NutEventPostFromIrq()
* to post events to specific queues.
*
* \param qhp Identifies the queue an event is posted to.
*
* \return The number of threads woken up, either 0 or 1.
*
*/
int NutEventPost(volatile NUTHANDLE * qhp)
{
int rc;
rc = NutEventPostAsync(qhp);
/*
* If any thread with higher or equal priority is
* ready to run, switch the context.
*/
NutThreadYield();
return rc;
}
/*!
* \brief Asynchronously broadcast an event to a specified queue.
*
* Wake up all threads waiting on this queue. But even if the
* priority of any woken thread is higher than the current thread's
* priority, the current one continues running.
*
* In opposite to NutEventPostAsync(), the queue will be cleared in
* any case, even if it is in signaled state. Applications may use this
* call to make sure, that a queue is cleared before initiating some
* event triggering action.
*
* \param qhp Identifies the queue an event is broadcasted to.
*
* \return The number of threads woken up.
*
*/
int NutEventBroadcastAsync(volatile NUTHANDLE * qhp)
{
int rc = 0;
NUTTHREADINFO *tdp;
/* Get the queue's root atomically. */
NutEnterCritical();
tdp = *qhp;
NutExitCritical();
if (tdp == SIGNALED) {
NutEnterCritical();
*qhp = 0;
NutExitCritical();
}
else if (tdp) {
do {
rc += NutEventPostAsync(qhp);
/* Get the queue's updated root atomically. */
NutEnterCritical();
tdp = *qhp;
NutExitCritical();
} while (tdp && tdp != SIGNALED);
}
return rc;
}
/*!
* \brief Broadcast an event to a specified queue.
*
* Wake up all threads waiting on this queue. If the priority of any
* waiting thread is higher or equal than the current thread's
* priority, then the current thread is stopped and CPU control is
* passed to the woken up thread with the highest priority.
*
* In opposite to NutEventPost(), the queue will be cleared in any
* case, even if it is in signaled state. Applications may use this
* call to make sure, that a queue is cleared before initiating
* some event triggering action.
*
* \param qhp Identifies the queue an event is broadcasted to.
*
* \return The number of threads woken up.
*
*/
int NutEventBroadcast(volatile NUTHANDLE * qhp)
{
int rc = NutEventBroadcastAsync(qhp);
NutThreadYield();
return rc;
}
#endif
NutEvent.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef NUTEVENT_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NUTEVENT_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "NutThread.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/*!
* \brief Signaled state definition.
*
* The root of an event queue is set to this value if an event
* is posted to an empty queue. As this may happen during
* interrupts, the root of an event queue must be considered
* volatile.
*
* Timer handles in the THREADINFO structure are set to this value
* if a timeout occured while waiting for an event.
*/
#define SIGNALED ((void *)-1)
/*!
* \brief Infinite waiting time definition.
*
* Applications should use this value to disable timeout monitoring
* while waiting for an event.
*/
#define NUT_WAIT_INFINITE 0
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
#if defined(NUTOS)
/*!
* \brief Post an event to a specified queue from interrupt context.
*
* Wake up the thread with the highest priority waiting on the
* specified queue. This function is explicitly provided for IRQ
* handlers to wakeup waiting user threads.
*
* Internally a counter is used to keep track of the posted events.
* This counter will be examined when the currently running thread is
* ready to release the CPU.
*
* \note When calling this function, interrupt routines will change
* the root of an empty event queue to SIGNALED.
*
* \param qp Identifies the queue an event is posted to.
*
*/
#define NutEventPostFromIrq(qp) \
{ \
if (*qp == 0) { \
*qp = SIGNALED; \
} \
else if (*qp != SIGNALED) { \
NUTTHREADINFO *tp = (NUTTHREADINFO *)(*qp); \
tp->td_qpec++; \
} \
}
void NutEventTimeout(NUTHANDLE timer, void *arg);
int NutEventWait(volatile NUTHANDLE *qhp, u_long ms);
int NutEventWaitNext(volatile NUTHANDLE *qhp, u_long ms);
int NutEventPostAsync(volatile NUTHANDLE *qhp);
int NutEventPost(volatile NUTHANDLE *qhp);
int NutEventBroadcastAsync(volatile NUTHANDLE *qhp);
int NutEventBroadcast(volatile NUTHANDLE *qhp);
#else
#define NutEventPostFromIrq(qp)
#define NutEventTimeout(timer, arg)
#define NutEventWait(qhp, ms) (-1)
#define NutEventWaitNext(qhp, ms) (-1)
#define NutEventPostAsync(qhp) (0)
#define NutEventPost(qhp) (0)
#define NutEventBroadcastAsync(qhp) (0)
#define NutEventBroadcast(qhp) (0)
#endif
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
NutFile.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef NUTFILE_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define NUTFILE_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
#define NUTFILE_EOF ((NUTFILE *)(-1))
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
struct _NUTDEVICE;
/*!
* \brief File structure type.
*/
typedef struct _NUTFILE NUTFILE;
/*!
* \struct _NUTFILE file.h sys/file.h
* \brief File structure.
*/
struct _NUTFILE {
/*!
* \brief Link to the next file structure.
*/
NUTFILE *nf_next;
/*!
* \brief Device containing this file.
*/
struct _NUTDEVICE *nf_dev;
/*!
* \brief Device specific file control block.
*/
void *nf_fcb;
};
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif