⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtems_glue.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
	t->arg = arg;	/*	 * Start the task	 */	sc = rtems_task_start (tid, taskEntry, (rtems_task_argument)t);	if (sc != RTEMS_SUCCESSFUL)		rtems_panic ("Can't start network daemon `%s': `%s'\n", name, rtems_status_text (sc));	/*	 * Let our caller know the i.d. of the new task	 */	return tid;}rtems_status_code rtems_bsdnet_event_receive (  rtems_event_set  event_in,  rtems_option     option_set,  rtems_interval   ticks,  rtems_event_set *event_out){	rtems_status_code sc;	rtems_bsdnet_semaphore_release ();	sc = rtems_event_receive (event_in, option_set, ticks, event_out);	rtems_bsdnet_semaphore_obtain ();	return sc;}/* * Return time since startup */voidmicrotime (struct timeval *t){	rtems_interval now;	rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);	t->tv_sec = now / rtems_bsdnet_ticks_per_second;	t->tv_usec = (now % rtems_bsdnet_ticks_per_second) * rtems_bsdnet_microseconds_per_tick;}unsigned longrtems_bsdnet_seconds_since_boot (void){	rtems_interval now;	rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);	return now / rtems_bsdnet_ticks_per_second;}/* * Fake random number generator */unsigned longrtems_bsdnet_random (void){	rtems_interval now;	rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);	return (now * 99991);}/* * Callout list processing */voidtimeout(void (*ftn)(void *), void *arg, int ticks){	register struct callout *new, *p, *t;	if (ticks <= 0)		ticks = 1;	/* Fill in the next free callout structure. */	if (callfree == NULL) {		callfree = malloc (sizeof *callfree);		if (callfree == NULL)			rtems_panic ("No memory for timeout table entry");		callfree->c_next = NULL;	}	new = callfree;	callfree = new->c_next;	new->c_arg = arg;	new->c_func = ftn;	/*	 * The time for each event is stored as a difference from the time	 * of the previous event on the queue.  Walk the queue, correcting	 * the ticks argument for queue entries passed.  Correct the ticks	 * value for the queue entry immediately after the insertion point	 * as well.  Watch out for negative c_time values; these represent	 * overdue events.	 */	for (p = &calltodo;	    (t = p->c_next) != NULL && ticks > t->c_time; p = t)		if (t->c_time > 0)			ticks -= t->c_time;	new->c_time = ticks;	if (t != NULL)		t->c_time -= ticks;	/* Insert the new entry into the queue. */	p->c_next = new;	new->c_next = t;}/* * Ticks till specified time * XXX: This version worries only about seconds, but that's good * enough for the way the network code uses this routine. */inthzto(struct timeval *tv){	long diff = tv->tv_sec - rtems_bsdnet_seconds_since_boot();	if (diff <= 0)		return 1;	return diff * rtems_bsdnet_ticks_per_second;}/* * Kernel debugging */int rtems_bsdnet_log_priority;voidrtems_bsdnet_log (int priority, const char *fmt, ...){	va_list args;		if (priority & rtems_bsdnet_log_priority) {		va_start (args, fmt);		vprintf (fmt, args);		va_end (args);	}}/* * IP header checksum routine for processors which don't have an inline version */u_intin_cksum_hdr (const void *ip){	rtems_unsigned32 sum;	const rtems_unsigned16 *sp;	int i;	sum = 0;	sp = (rtems_unsigned16 *)ip;	for (i = 0 ; i < 10 ; i++)		sum += *sp++;	while (sum > 0xFFFF)		sum = (sum & 0xffff) + (sum >> 16);	return ~sum & 0xFFFF;}/* * Manipulate routing tables */int rtems_bsdnet_rtrequest (    int req,    struct sockaddr *dst,    struct sockaddr *gateway,    struct sockaddr *netmask,    int flags,    struct rtentry **net_nrt){	int error;	rtems_bsdnet_semaphore_obtain ();	error = rtrequest (req, dst, gateway, netmask, flags, net_nrt);	rtems_bsdnet_semaphore_release ();	if (error) {		errno = error;		return -1;	}	return 0;}static intrtems_bsdnet_setup (void){	struct rtems_bsdnet_ifconfig *ifp;	short flags;	struct sockaddr_in address;	struct sockaddr_in netmask;	struct sockaddr_in broadcast;	struct sockaddr_in gateway;	int i;	extern char *strdup (const char *cp);	/*	 * Set local parameters	 */	if (rtems_bsdnet_config.hostname)		sethostname (rtems_bsdnet_config.hostname,					strlen (rtems_bsdnet_config.hostname));	if (rtems_bsdnet_config.domainname)		rtems_bsdnet_domain_name =					strdup (rtems_bsdnet_config.domainname);	if (rtems_bsdnet_config.log_host)		rtems_bsdnet_log_host_address.s_addr =				inet_addr (rtems_bsdnet_config.log_host);	for (i = 0 ; i < sizeof rtems_bsdnet_config.name_server /			sizeof rtems_bsdnet_config.name_server[0] ; i++) {		if (!rtems_bsdnet_config.name_server[i])			break;		rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count++].s_addr			= inet_addr (rtems_bsdnet_config.name_server[i]);	}	for (i = 0 ; i < sizeof rtems_bsdnet_config.ntp_server /			sizeof rtems_bsdnet_config.ntp_server[0] ; i++) {		if (!rtems_bsdnet_config.ntp_server[i])			break;		rtems_bsdnet_ntpserver[rtems_bsdnet_ntpserver_count++].s_addr			= inet_addr (rtems_bsdnet_config.ntp_server[i]);	}	/*	 * Configure interfaces	 */	for (ifp = rtems_bsdnet_config.ifconfig ; ifp ; ifp = ifp->next) {		if (ifp->ip_address == NULL)			continue;		/*		 * Bring interface up		 */		flags = IFF_UP;		if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFFLAGS, &flags) < 0) {			printf ("Can't bring %s up: %s\n", ifp->name, strerror (errno));			continue;		}		/*		 * Set interface netmask		 */		memset (&netmask, '\0', sizeof netmask);		netmask.sin_len = sizeof netmask;		netmask.sin_family = AF_INET;		netmask.sin_addr.s_addr = inet_addr (ifp->ip_netmask);		if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFNETMASK, &netmask) < 0) {			printf ("Can't set %s netmask: %s\n", ifp->name, strerror (errno));			continue;		}		/*		 * Set interface address		 */		memset (&address, '\0', sizeof address);		address.sin_len = sizeof address;		address.sin_family = AF_INET;		address.sin_addr.s_addr = inet_addr (ifp->ip_address);		if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFADDR, &address) < 0) {			printf ("Can't set %s address: %s\n", ifp->name, strerror (errno));			continue;		}		/*		 * Set interface broadcast address if the interface has the 		 * broadcast flag set.		 */		if (rtems_bsdnet_ifconfig (ifp->name, SIOCGIFFLAGS, &flags) < 0) {			printf ("Can't read %s flags: %s\n", ifp->name, strerror (errno));			continue;		}		if (flags & IFF_BROADCAST) {			memset (&broadcast, '\0', sizeof broadcast);			broadcast.sin_len = sizeof broadcast;			broadcast.sin_family = AF_INET;			broadcast.sin_addr.s_addr = 					address.sin_addr.s_addr | ~netmask.sin_addr.s_addr;			if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFBRDADDR, &broadcast) < 0) {				struct in_addr	in_addr;				char			buf[20];				in_addr.s_addr = broadcast.sin_addr.s_addr;				if (!inet_ntop(AF_INET, &in_addr, buf, sizeof(buf)))						strcpy(buf,"?.?.?.?");				printf ("Can't set %s broadcast address %s: %s\n",					ifp->name, buf, strerror (errno));			}		}	}	/*	 * Set default route	 */	if (rtems_bsdnet_config.gateway) {		address.sin_addr.s_addr = INADDR_ANY;		netmask.sin_addr.s_addr = INADDR_ANY;		memset (&gateway, '\0', sizeof gateway);		gateway.sin_len = sizeof gateway;		gateway.sin_family = AF_INET;		gateway.sin_addr.s_addr = inet_addr (rtems_bsdnet_config.gateway);		if (rtems_bsdnet_rtrequest (				RTM_ADD, 				(struct sockaddr *)&address,				(struct sockaddr *)&gateway,				(struct sockaddr *)&netmask,				(RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL) < 0) {			printf ("Can't set default route: %s\n", strerror (errno));			return -1;		}	}	return 0;}/* * Initialize the network */intrtems_bsdnet_initialize_network (void){	struct rtems_bsdnet_ifconfig *ifp;	/*	 * Start network tasks.	 * Initialize BSD network data structures.	 */	if (rtems_bsdnet_initialize () < 0)		return -1;	/*	 * Attach interfaces	 */	for (ifp = rtems_bsdnet_config.ifconfig ; ifp ; ifp = ifp->next) {		rtems_bsdnet_attach (ifp);	}	/*	 * Bring up the network	 */	if (rtems_bsdnet_setup () < 0)		return -1;	if (rtems_bsdnet_config.bootp)		(*rtems_bsdnet_config.bootp)();	return 0;}/* * Attach a network interface. */void rtems_bsdnet_attach (struct rtems_bsdnet_ifconfig *ifp){	if (ifp) {		rtems_bsdnet_semaphore_obtain ();		(ifp->attach)(ifp, 1);		rtems_bsdnet_semaphore_release ();	}}/* * Detach a network interface. */void rtems_bsdnet_detach (struct rtems_bsdnet_ifconfig *ifp){	if (ifp) {		rtems_bsdnet_semaphore_obtain ();		(ifp->attach)(ifp, 0);		rtems_bsdnet_semaphore_release ();	}}/* * Interface Configuration. */int rtems_bsdnet_ifconfig (const char *ifname, unsigned32 cmd, void *param){	int s, r = 0;	struct ifreq ifreq;	/*	 * Configure interfaces	 */	s = socket (AF_INET, SOCK_DGRAM, 0);	if (s < 0)		return -1;	strncpy (ifreq.ifr_name, ifname, IFNAMSIZ);	rtems_bsdnet_semaphore_obtain ();	switch (cmd) {		case SIOCSIFADDR:		case SIOCSIFNETMASK:			memcpy (&ifreq.ifr_addr, param, sizeof (struct sockaddr));			r = ioctl (s, cmd, &ifreq);			break;		case OSIOCGIFADDR:		case SIOCGIFADDR:		case OSIOCGIFNETMASK:		case SIOCGIFNETMASK:			if ((r = ioctl (s, cmd, &ifreq)) < 0)				break;			memcpy (param, &ifreq.ifr_addr, sizeof (struct sockaddr));			break;		case SIOCGIFFLAGS:		case SIOCSIFFLAGS:			if ((r = ioctl (s, SIOCGIFFLAGS, &ifreq)) < 0)				break;			if (cmd == SIOCGIFFLAGS) {				*((short*) param) = ifreq.ifr_flags;				break;			}			ifreq.ifr_flags |= *((short*) param);			if ( (*((short*) param) & IFF_UP ) == 0 ) {			    /* set the interface down */			    ifreq.ifr_flags &= ~(IFF_UP);			}			r = ioctl (s, SIOCSIFFLAGS, &ifreq);			break;		case SIOCSIFDSTADDR:			memcpy (&ifreq.ifr_dstaddr, param, sizeof (struct sockaddr));			r = ioctl (s, cmd, &ifreq);			break;		case OSIOCGIFDSTADDR:		case SIOCGIFDSTADDR:			if ((r = ioctl (s, cmd, &ifreq)) < 0)				break;			memcpy (param, &ifreq.ifr_dstaddr, sizeof (struct sockaddr));			break;		case SIOCSIFBRDADDR:			memcpy (&ifreq.ifr_broadaddr, param, sizeof (struct sockaddr));			r = ioctl (s, cmd, &ifreq);			break;		case OSIOCGIFBRDADDR:		case SIOCGIFBRDADDR:			if ((r = ioctl (s, cmd, &ifreq)) < 0)				break;			memcpy (param, &ifreq.ifr_broadaddr, sizeof (struct sockaddr));			break;		case SIOCSIFMETRIC:			ifreq.ifr_metric = *((int*) param);			r = ioctl (s, cmd, &ifreq);			break;		case SIOCGIFMETRIC:			if ((r = ioctl (s, cmd, &ifreq)) < 0)				break;			*((int*) param) = ifreq.ifr_metric;			break;		case SIOCSIFMTU:			ifreq.ifr_mtu = *((int*) param);			r = ioctl (s, cmd, &ifreq);			break;		case SIOCGIFMTU:			if ((r = ioctl (s, cmd, &ifreq)) < 0)				break;			*((int*) param) = ifreq.ifr_mtu;			break;		case SIOCSIFPHYS:			ifreq.ifr_phys = *((int*) param);			r = ioctl (s, cmd, &ifreq);			break;		case SIOCGIFPHYS:			if ((r = ioctl (s, cmd, &ifreq)) < 0)				break;			*((int*) param) = ifreq.ifr_phys;			break;		case SIOCSIFMEDIA:			ifreq.ifr_media = *((int*) param);			r = ioctl (s, cmd, &ifreq);			break;		case SIOCGIFMEDIA:			if ((r = ioctl (s, cmd, &ifreq)) < 0)				break;			*((int*) param) = ifreq.ifr_media;			break;						case SIOCAIFADDR:		case SIOCDIFADDR:			r = ioctl(s, cmd, (struct freq *) param);			break;		default:			errno = EOPNOTSUPP;			r = -1;			break;	}	rtems_bsdnet_semaphore_release ();	close (s);	return r;}/* * Parse a network driver name into a name and a unit number */intrtems_bsdnet_parse_driver_name (const struct rtems_bsdnet_ifconfig *config, char **namep){	const char *cp = config->name;	char c;	int unitNumber = 0;	if (cp == NULL) {		printf ("No network driver name.\n");		return -1;	}	while ((c = *cp++) != '\0') {		if ((c >= '0') && (c <= '9')) {			int len = cp - config->name;			if ((len < 2) || (len > 50))				break;			for (;;) {				unitNumber = (unitNumber * 10) + (c - '0');				c = *cp++;				if (c == '\0') {					char *unitName = malloc (len);					if (unitName == NULL) {						printf ("No memory.\n");						return -1;					}					strncpy (unitName, config->name, len - 1);					unitName[len-1] = '\0';					*namep = unitName;					return unitNumber;				}				if ((c < '0') || (c > '9'))					break;			}			break;		}	}	printf ("Bad network driver name `%s'.\n", config->name);	return -1;}/* * Handle requests for more network memory * XXX: Another possibility would be to use a semaphore here with *      a release in the mbuf free macro.  I have chosen this `polling' *      approach because: *      1) It is simpler. *      2) It adds no complexity to the free macro. *      3) Running out of mbufs should be a rare *         condition -- predeployment testing of *         an application should indicate the *         required mbuf pool size. * XXX: Should there be a panic if a task is stuck in the loop for *      more than a minute or so? */intm_mballoc (int nmb, int nowait){	if (nowait)		return 0;	m_reclaim ();	if (mmbfree == NULL) {		int try = 0;		int print_limit = 30 * rtems_bsdnet_ticks_per_second;		mbstat.m_wait++;		for (;;) {			rtems_bsdnet_semaphore_release ();			rtems_task_wake_after (1);			rtems_bsdnet_semaphore_obtain ();			if (mmbfree)				break;			if (++try >= print_limit) {				printf ("Still waiting for mbuf.\n");				try = 0;			}		}	}	else {		mbstat.m_drops++;	}	return 1;}intm_clalloc(ncl, nowait){	if (nowait)		return 0;	m_reclaim ();	if (mclfree == NULL) {		int try = 0;		int print_limit = 30 * rtems_bsdnet_ticks_per_second;		mbstat.m_wait++;		for (;;) {			rtems_bsdnet_semaphore_release ();			rtems_task_wake_after (1);			rtems_bsdnet_semaphore_obtain ();			if (mclfree)				break;			if (++try >= print_limit) {				printf ("Still waiting for mbuf cluster.\n");				try = 0;			}		}	}	else {		mbstat.m_drops++;	}	return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -