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

📄 message_net.c

📁 嵌入式操作系统内核
💻 C
字号:
/* -*- Mode: C; tab-width:2 -*- *//* ex: set ts=2 shiftwidth=2 softtabstop=2 cindent: *//* * Copyright (c) 2003 The Regents of the University of California. * 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. All advertising materials mentioning features or use of this *    software must display the following acknowledgement: *       This product includes software developed by Networked & *       Embedded Systems Lab at UCLA * 4. Neither the name of the University nor that of the Laboratory *    may be used to endorse or promote products derived from this *    software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS * OR CONTRIBUTORS 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. * * $Id: message_net.c,v 1.36 2006/12/17 00:51:01 simonhan Exp $  *//** * @brief Message handling routines for network * @author Simon Han (simonhan@cs.ucla.edu) * @brief General Message Dispatcher (Handles diverse links) * @author Ram Kumar {ram@ee.ucla.edu} */#include <message_queue.h>#include <monitor.h>#include <sos_info.h>#include <message_types.h>#include <malloc.h>#include <message.h>#include <sos_sched.h>#include <hardware.h>#include <sos_logging.h>#if defined (SOS_UART_CHANNEL)#include <sos_uart.h>#include <sos_uart_mgr.h>#endif#if defined (SOS_I2C_CHANNEL)#include <sos_i2c.h>#include <sos_i2c_mgr.h>#endif//-------------------------------------------------------------------------------// STATIC FUNCTION DECLARATIONS//-------------------------------------------------------------------------------static int8_t sos_msg_dispatch(Message* m);static inline void msg_change_endian(Message* e);static void sos_msg_find_right_link(Message *m);//-------------------------------------------------------------------------------// FUNCTION IMPLEMENTATIONS//-------------------------------------------------------------------------------// Fix the endian-ness of the message headerstatic inline void msg_change_endian(Message* e){  e->daddr = ehtons(e->daddr);  e->saddr = ehtons(e->saddr);}// Create a deep copy of the message#if defined(SOS_UART_CHANNEL) || defined(SOS_I2C_CHANNEL) || defined(SOS_SPI_CHANNEL)static Message* msg_duplicate(Message* m){  Message* mcopy;	uint8_t* d;  mcopy = msg_create();  if (NULL == mcopy) return NULL;  d = (uint8_t*)ker_malloc(m->len, KER_SCHED_PID);  if ((NULL == d) && (0 != m->len)){    msg_dispose(mcopy);    return NULL;  }	memcpy(mcopy, m, sizeof(Message));	mcopy->data = d;	mcopy->flag |= SOS_MSG_RELEASE;  memcpy(mcopy->data, m->data, m->len);  return mcopy;}#endif// NULL Link - Simply free the messagestatic void null_link_msg_alloc(Message* m){  msg_dispose(m);}//-------------------------------------------------------------------------------// POST//-------------------------------------------------------------------------------// Copies message header and sends out the messageint8_t post(Message *e){  Message *m = msg_create();  if(m == NULL){ 	if(flag_msg_release(e->flag)) {	  ker_free(e->data);	}	return -ENOMEM;  }  // deep copy the header  *m = *e;    // Dispatch Message  return sos_msg_dispatch(m);}//-------------------------------------------------------------------------------// POST LINK//-------------------------------------------------------------------------------// Post a message over any link as specified by the flagint8_t post_link(sos_pid_t did, sos_pid_t sid, 		uint8_t type, uint8_t len, 		void *data, uint16_t flag, 		uint16_t daddr){  // Create a message  Message *m = msg_create();  if (NULL == m){    if (flag_msg_release(flag)){      ker_free(data);    }    return -ENOMEM;  }  // Fill out message header  m->daddr = daddr;  m->did = did;  m->type = type;  m->saddr = node_address;  m->sid = sid;  m->len = len;  m->data = (uint8_t*)data;  m->flag = flag;  // Dispatch Message  return sos_msg_dispatch(m);}//-----------------------------------------------------------------------------// SOS Find Right link//-----------------------------------------------------------------------------static void sos_msg_find_right_link(Message *m){		bool link_found = false;				// try to figure out the right link#ifdef SOS_UART_CHANNEL		if (check_uart_address(m->daddr) == SOS_OK) {			m->flag |= SOS_MSG_UART_IO;				link_found = true;		} else {			m->flag &= ~SOS_MSG_UART_IO;			}#else		m->flag &= ~SOS_MSG_UART_IO;	#endif		#ifdef SOS_I2C_CHANNEL		if (check_i2c_address(m->daddr) == SOS_OK) {			m->flag |= SOS_MSG_I2C_IO;				link_found = true;		} else {			m->flag &= ~SOS_MSG_I2C_IO;			}#else		m->flag &= ~SOS_MSG_I2C_IO;	#endif		if(link_found == false) {			m->flag |= SOS_MSG_RADIO_IO;			} else {			m->flag &= ~SOS_MSG_RADIO_IO;			}}//--------------------------------------------------------------------------------// SOS Message Dispatcher//--------------------------------------------------------------------------------static int8_t sos_msg_dispatch(Message* m){#if defined(SOS_RADIO_CHANNEL) || defined(SOS_UART_CHANNEL) || defined(SOS_I2C_CHANNEL) || defined(SOS_SPI_CHANNEL)	Message* mcopy[NUM_IO_LINKS] = {NULL};	uint8_t msg_count = 0;#endif  // Local Dispatch  if (node_address == m->daddr){    sched_msg_alloc(m);		ker_log( SOS_LOG_POST_NET, m->sid, m->daddr );    return SOS_OK;  }#if !defined(SOS_UART_CHANNEL) && !defined(SOS_I2C_CHANNEL) && !defined(SOS_RADIO_CHANNEL) && !defined(SOS_SPI_CHANNEL)	null_link_msg_alloc(m);	return -EINVAL;#endif	if (flag_msg_link_auto(m->flag) && m->daddr != BCAST_ADDRESS) {		sos_msg_find_right_link(m);	}	if ((m->flag & SOS_MSG_ALL_LINK_IO) == 0) {		null_link_msg_alloc(m);		return SOS_OK;	}	// Pre-allocate the message copies to allow for	// an atomic NOMEM failure#ifdef SOS_RADIO_CHANNEL	if (flag_msg_from_radio(m->flag)){		mcopy[SOS_RADIO_LINK_ID] = m;		msg_count ++;	}#endif	#ifdef SOS_UART_CHANNEL	if( flag_msg_from_uart(m->flag) ) {		if (msg_count == 0){			mcopy[SOS_UART_LINK_ID] = m;		} else {			mcopy[SOS_UART_LINK_ID] = msg_duplicate(m);			if (NULL == mcopy[SOS_UART_LINK_ID]) goto dispatch_cleanup;			mcopy[SOS_UART_LINK_ID]->flag &= ~SOS_MSG_RELIABLE;		}		msg_count++;	}#endif#ifdef SOS_I2C_CHANNEL	if (flag_msg_from_i2c(m->flag)) {		if (msg_count == 0){			mcopy[SOS_I2C_LINK_ID] = m;		} else {			mcopy[SOS_I2C_LINK_ID] = msg_duplicate(m);			if (NULL == mcopy[SOS_I2C_LINK_ID]) goto dispatch_cleanup;			mcopy[SOS_I2C_LINK_ID]->flag &= ~SOS_MSG_RELIABLE;		}		msg_count++;	}#endif#ifdef SOS_SPI_CHANNEL                                        	if (flag_msg_from_spi(m->flag)) {      		if (msg_count == 0){			mcopy[SOS_SPI_LINK_ID] = m;		} else {			mcopy[SOS_SPI_LINK_ID] = msg_duplicate(m);			if (NULL == mcopy[SOS_SPI_LINK_ID]) goto dispatch_cleanup;			mcopy[SOS_SPI_LINK_ID]->flag &= ~SOS_MSG_RELIABLE;		}		msg_count++;	}#endif	// Deliver to monitor only once	monitor_deliver_outgoing_msg_to_monitor(m);  // Radio Dispatch#ifdef SOS_RADIO_CHANNEL	if (NULL != mcopy[SOS_RADIO_LINK_ID]){		msg_change_endian(mcopy[SOS_RADIO_LINK_ID]);		SOS_RADIO_LINK_DISPATCH(mcopy[SOS_RADIO_LINK_ID]);		ker_log( SOS_LOG_POST_NET, mcopy[SOS_RADIO_LINK_ID]->sid, mcopy[SOS_RADIO_LINK_ID]->daddr );	}#endif  // UART Dispatch#ifdef SOS_UART_CHANNEL	if (NULL != mcopy[SOS_UART_LINK_ID]){		msg_change_endian(mcopy[SOS_UART_LINK_ID]);		SOS_UART_LINK_DISPATCH(mcopy[SOS_UART_LINK_ID]);	}#endif  // I2C Dispatch #ifdef SOS_I2C_CHANNEL	if (NULL != mcopy[SOS_I2C_LINK_ID]){		msg_change_endian(mcopy[SOS_I2C_LINK_ID]);		SOS_I2C_LINK_DISPATCH(mcopy[SOS_I2C_LINK_ID]);	}#endif	// SPI Dispatch#ifdef SOS_SPI_CHANNEL	if (NULL != mcopy[SOS_SPI_LINK_ID]){		msg_change_endian(mcopy[SOS_SPI_LINK_ID]);		SOS_SPI_LINK_DISPATCH(mcopy[SOS_SPI_LINK_ID]);	}#endif	return SOS_OK;#if defined(SOS_UART_CHANNEL) || defined(SOS_I2C_CHANNEL) || defined(SOS_SPI_CHANNEL)dispatch_cleanup:	{		uint8_t i;		for (i = 0 ; i < NUM_IO_LINKS; i++){			if (NULL != mcopy[i]){				msg_dispose(mcopy[i]);			}		}		DEBUG("----------------Cleaning up-----------\n");	}	return -ENOMEM;#endif}//============================================================================// sys APIs//============================================================================int8_t ker_sys_post_link(sos_pid_t dst_mod_id, uint8_t type,		uint8_t size, void *data, uint16_t flag, uint16_t dst_node_addr){	sos_pid_t my_id = ker_get_current_pid();		if( post_link(dst_mod_id, my_id, type, size, data, flag, dst_node_addr) != SOS_OK) {		return ker_mod_panic(my_id);	}	return SOS_OK;}

⌨️ 快捷键说明

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