📄 support.c
字号:
cyg_uint32 res;
static unsigned long seed = 0xDEADB00B;
HAL_CLOCK_READ(&res); // Not so bad... (but often 0..N where N is small)
seed = ((seed & 0x007F00FF) << 7) ^
((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits
(res << 13) ^ (res >> 9); // using the clock too!
return (int)seed;
}
void
get_random_bytes(void *buf, size_t len)
{
unsigned long ranbuf, *lp;
lp = (unsigned long *)buf;
while (len > 0) {
ranbuf = arc4random();
*lp++ = ranbuf;
len -= sizeof(ranbuf);
}
}
void
read_random_unlimited(void *buf, size_t len)
{
get_random_bytes(buf, len);
}
void
microtime(struct timeval *tp)
{
*tp = ktime;
log(LOG_DEBUG, "%s: = %d.%d\n", __FUNCTION__, tp->tv_sec, tp->tv_usec);
ktime.tv_usec++; // In case clock isn't running yet
}
void
getmicrotime(struct timeval *tp)
{
*tp = ktime;
log(LOG_DEBUG, "%s: = %d.%d\n", __FUNCTION__, tp->tv_sec, tp->tv_usec);
ktime.tv_usec++; // In case clock isn't running yet
}
void
getmicrouptime(struct timeval *tp)
{
*tp = ktime;
log(LOG_DEBUG, "%s: = %d.%d\n", __FUNCTION__, tp->tv_sec, tp->tv_usec);
ktime.tv_usec++; // In case clock isn't running yet
}
// Taken from kern/kern_clock.c
/*
* Compute number of ticks in the specified amount of time.
*/
#ifndef LONG_MAX
#define LONG_MAX 0x7FFFFFFF
#endif
int
tvtohz(struct timeval *tv)
{
register unsigned long ticks;
register long sec, usec;
/*
* If the number of usecs in the whole seconds part of the time
* difference fits in a long, then the total number of usecs will
* fit in an unsigned long. Compute the total and convert it to
* ticks, rounding up and adding 1 to allow for the current tick
* to expire. Rounding also depends on unsigned long arithmetic
* to avoid overflow.
*
* Otherwise, if the number of ticks in the whole seconds part of
* the time difference fits in a long, then convert the parts to
* ticks separately and add, using similar rounding methods and
* overflow avoidance. This method would work in the previous
* case but it is slightly slower and assumes that hz is integral.
*
* Otherwise, round the time difference down to the maximum
* representable value.
*
* If ints have 32 bits, then the maximum value for any timeout in
* 10ms ticks is 248 days.
*/
sec = tv->tv_sec;
usec = tv->tv_usec;
if (usec < 0) {
sec--;
usec += 1000000;
}
if (sec < 0) {
#ifdef DIAGNOSTIC
if (usec > 0) {
sec++;
usec -= 1000000;
}
printf("tvotohz: negative time difference %ld sec %ld usec\n",
sec, usec);
#endif
ticks = 1;
} else if (sec <= LONG_MAX / 1000000)
ticks = (sec * 1000000 + (unsigned long)usec + (tick - 1))
/ tick + 1;
else if (sec <= LONG_MAX / hz)
ticks = sec * hz
+ ((unsigned long)usec + (tick - 1)) / tick + 1;
else
ticks = LONG_MAX;
if (ticks > INT_MAX)
ticks = INT_MAX;
return ((int)ticks);
}
void
get_mono_time(void)
{
panic("get_mono_time");
}
void
csignal(pid_t pgid, int signum, uid_t uid, uid_t euid)
{
panic("csignal");
}
int
bcmp(const void *_p1, const void *_p2, size_t len)
{
int res = 0;
unsigned char *p1 = (unsigned char *)_p1;
unsigned char *p2 = (unsigned char *)_p2;
while (len-- > 0) {
res = *p1++ - *p2++;
if (res) break;
}
return res;
}
int
copyout(const void *s, void *d, size_t len)
{
memcpy(d, s, len);
return 0;
}
int
copyin(const void *s, void *d, size_t len)
{
memcpy(d, s, len);
return 0;
}
void
ovbcopy(const void *s, void *d, size_t len)
{
memmove(d, s, len);
}
// ------------------------------------------------------------------------
// THE NETWORK THREAD ITSELF
//
// Network software interrupt handler
// This function is run as a separate thread to allow
// processing of network events (mostly incoming packets)
// at "user level" instead of at interrupt time.
//
// The actual handlers are 'registered' at system startup
//
// The set of handlers
static netisr_t *_netisr_handlers[NETISR_MAX+1];
struct ifqueue ipintrq;
#ifdef INET6
struct ifqueue ip6intrq;
#endif
char *hostname = "eCos_node";
// Register a 'netisr' handler for a given level
int
register_netisr(int level, netisr_t *fun)
{
CYG_ASSERT(level <= NETISR_MAX, "invalid netisr level");
CYG_ASSERT(_netisr_handlers[level] == 0, "re-registered netisr");
_netisr_handlers[level] = fun;
return 0; // ignored
}
//int unregister_netisr __P((int));
static void
cyg_netint(cyg_addrword_t param)
{
cyg_flag_value_t curisr;
int lvl, spl;
while (true) {
curisr = cyg_flag_wait(&netint_flags, NETISR_ANY,
CYG_FLAG_WAITMODE_OR|CYG_FLAG_WAITMODE_CLR);
spl = splsoftnet(); // Prevent any overlapping "stack" processing
for (lvl = NETISR_MIN; lvl <= NETISR_MAX; lvl++) {
if (curisr & (1<<lvl)) {
CYG_ASSERT(_netisr_handlers[lvl] != 0, "unregistered netisr handler");
(*_netisr_handlers[lvl])();
}
}
splx(spl);
}
}
// This just sets one of the pseudo-ISR bits used above.
void
setsoftnet(void)
{
// This is called if we are out of MBUFs - it doesn't do anything, and
// that situation is handled OK, so don't bother with the diagnostic:
// diag_printf("setsoftnet\n");
// No need to do this because it is ignored anyway:
// schednetisr(NETISR_SOFTNET);
}
/* Update the kernel globel ktime. */
static void
cyg_ktime_func(cyg_handle_t alarm,cyg_addrword_t data)
{
cyg_tick_count_t now = cyg_current_time();
ktime.tv_usec = (now % hz) * tick;
ktime.tv_sec = 1 + now / hz;
}
static void
cyg_ktime_init(void)
{
cyg_handle_t ktime_alarm_handle;
static cyg_alarm ktime_alarm;
cyg_handle_t counter;
// Do not start at 0 - net stack thinks 0 an invalid time;
// Have a valid time available from right now:
ktime.tv_usec = 0;
ktime.tv_sec = 1;
cyg_clock_to_counter(cyg_real_time_clock(),&counter);
cyg_alarm_create(counter,
cyg_ktime_func,
0,
&ktime_alarm_handle,
&ktime_alarm);
/* We want one alarm every 10ms. */
cyg_alarm_initialize(ktime_alarm_handle,cyg_current_time()+1,1);
cyg_alarm_enable(ktime_alarm_handle);
}
int
cyg_ticks(void)
{
cyg_tick_count_t now = cyg_current_time();
return (int)now;
}
//
// Network initialization
// This function is called during system initialization to setup the whole
// networking environment.
// Linker magic to execute this function as 'init'
extern void cyg_do_net_init(void);
extern void ifinit(void);
extern void loopattach(int);
extern void bridgeattach(int);
// Internal init functions:
extern void cyg_alarm_timeout_init(void);
extern void cyg_tsleep_init(void);
static void
cyg_net_init_devs(void *ignored)
{
cyg_netdevtab_entry_t *t;
// Initialize all network devices
for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
log(LOG_INIT, "Init device '%s'\n", t->name);
if (t->init(t)) {
t->status = CYG_NETDEVTAB_STATUS_AVAIL;
} else {
// What to do if device init fails?
t->status = 0; // Device not [currently] available
}
}
#if 0 // Bridge code not available yet
#if NBRIDGE > 0
bridgeattach(0);
#endif
#endif
}
SYSINIT(devs, SI_SUB_DEVICES, SI_ORDER_FIRST, cyg_net_init_devs, NULL)
void
cyg_net_init(void)
{
static int _init = false;
struct init_tab_entry *init_entry;
if (_init) return;
cyg_do_net_init(); // Just forces linking in the initializer/constructor
// Initialize interrupt "flags"
cyg_flag_init(&netint_flags);
// Initialize timeouts and net service thread (pseudo-DSRs)
cyg_alarm_timeout_init();
// Initialize tsleep/wakeup support
cyg_tsleep_init();
// Initialize network memory system
cyg_kmem_init();
// Initialize network time
cyg_ktime_init();
// Create network background thread
cyg_thread_create(CYGPKG_NET_THREAD_PRIORITY, // Priority
cyg_netint, // entry
0, // entry parameter
"Network support", // Name
&netint_stack[0], // Stack
STACK_SIZE, // Size
&netint_thread_handle, // Handle
&netint_thread_data // Thread data structure
);
cyg_thread_resume(netint_thread_handle); // Start it
// Run through dynamic initializers
for (init_entry = __NET_INIT_TAB__; init_entry != &__NET_INIT_TAB_END__; init_entry++) {
log(LOG_INIT, "[%s] Init: %s(%p)\n", __FUNCTION__, init_entry->name, init_entry->data);
(*init_entry->fun)(init_entry->data);
}
log(LOG_INIT, "[%s] Done\n", __FUNCTION__);
// Done
_init = true;
}
#include <net/if.h>
#include <net/netdb.h>
#include <net/route.h>
externC void if_indextoname(int indx, char *buf, int len);
typedef void pr_fun(char *fmt, ...);
static void
_mask(struct sockaddr *sa, char *buf, int _len)
{
char *cp = ((char *)sa) + 4;
int len = sa->sa_len - 4;
int tot = 0;
while (len-- > 0) {
if (tot) *buf++ = '.';
buf += diag_sprintf(buf, "%d", *cp++);
tot++;
}
while (tot < 4) {
if (tot) *buf++ = '.';
buf += diag_sprintf(buf, "%d", 0);
tot++;
}
}
static void
_show_ifp(struct ifnet *ifp, pr_fun *pr)
{
struct ifaddr *ifa;
char name[64], addr[64], netmask[64], broadcast[64];
if_indextoname(ifp->if_index, name, 64);
(*pr)("%-8s", name);
TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
if (ifa->ifa_addr->sa_family != AF_LINK) {
getnameinfo (ifa->ifa_addr, ifa->ifa_addr->sa_len, addr, sizeof(addr), 0, 0, 0);
getnameinfo (ifa->ifa_dstaddr, ifa->ifa_dstaddr->sa_len, broadcast, sizeof(broadcast), 0, 0, 0);
_mask(ifa->ifa_netmask, netmask, 64);
(*pr)("IP: %s, Broadcast: %s, Netmask: %s\n", addr, broadcast, netmask);
(*pr)(" ");
if ((ifp->if_flags & IFF_UP)) (*pr)("UP ");
if ((ifp->if_flags & IFF_BROADCAST)) (*pr)("BROADCAST ");
if ((ifp->if_flags & IFF_LOOPBACK)) (*pr)("LOOPBACK ");
if ((ifp->if_flags & IFF_RUNNING)) (*pr)("RUNNING ");
if ((ifp->if_flags & IFF_PROMISC)) (*pr)("PROMISC ");
if ((ifp->if_flags & IFF_MULTICAST)) (*pr)("MULTICAST ");
if ((ifp->if_flags & IFF_ALLMULTI)) (*pr)("ALLMULTI ");
(*pr)("MTU: %d, Metric: %d\n", ifp->if_mtu, ifp->if_metric);
(*pr)(" Rx - Packets: %d, Bytes: %d", ifa->if_data.ifi_ipackets, ifa->if_data.ifi_ibytes);
(*pr)(", Tx - Packets: %d, Bytes: %d\n", ifa->if_data.ifi_opackets, ifa->if_data.ifi_obytes);
}
}
}
static int
_dumpentry(struct radix_node *rn, void *vw)
{
struct rtentry *rt = (struct rtentry *)rn;
struct sockaddr *dst, *gate, *netmask, *genmask;
char addr[32], *cp;
pr_fun *pr = (pr_fun *)vw;
dst = rt_key(rt);
gate = rt->rt_gateway;
netmask = rt_mask(rt);
genmask = rt->rt_genmask;
if ((rt->rt_flags & (RTF_UP | RTF_WASCLONED)) == RTF_UP) {
if (netmask == NULL) {
return 0;
}
_inet_ntop(dst, addr, sizeof(addr));
(*pr)("%-15s ", addr);
if (gate != NULL) {
_inet_ntop(gate, addr, sizeof(addr));
(*pr)("%-15s ", addr);
} else {
(*pr)("%-15s ", " ");
}
if (netmask != NULL) {
_mask(netmask, addr, sizeof(addr));
(*pr)("%-15s ", addr);
} else {
(*pr)("%-15s ", " ");
}
cp = addr;
if ((rt->rt_flags & RTF_UP)) *cp++ = 'U';
if ((rt->rt_flags & RTF_GATEWAY)) *cp++ = 'G';
if ((rt->rt_flags & RTF_STATIC)) *cp++ = 'S';
if ((rt->rt_flags & RTF_DYNAMIC)) *cp++ = 'D';
*cp = '\0';
(*pr)("%-8s ", addr); // Flags
if_indextoname(rt->rt_ifp->if_index, addr, 64);
(*pr)("%-8s ", addr);
(*pr)("\n");
}
return 0;
}
void
show_network_tables(pr_fun *pr)
{
int i, error;
struct radix_node_head *rnh;
struct ifnet *ifp;
cyg_scheduler_lock();
(*pr)("Routing tables\n");
(*pr)("Destination Gateway Mask Flags Interface\n");
for (i = 1; i <= AF_MAX; i++) {
if ((rnh = rt_tables[i]) != NULL) {
error = rnh->rnh_walktree(rnh, _dumpentry, pr);
}
}
(*pr)("Interface statistics\n");
for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
_show_ifp(ifp, pr);
}
cyg_scheduler_unlock();
}
#endif // CYGPKG_NET_DRIVER_FRAMEWORK
// EOF support.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -