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

📄 deluge_app.c

📁 MANTIS是由科罗拉多大学开发的传感器网络嵌入式操作系统。 这是mantis的0.9.5版本的源码。
💻 C
📖 第 1 页 / 共 3 页
字号:
//  This file is part of MANTIS OS, Operating System//  See http://mantis.cs.colorado.edu/////  Copyright (C) 2003,2004,2005 University of Colorado, Boulder////  This program is free software; you can redistribute it and/or//  modify it under the terms of the mos license (see file LICENSE)#include "mos.h"#ifdef ARCH_AVR#include "msched.h"#include "com.h"#include "node_id.h"#include "clock.h"#include "deluge_impl.h"#include "printf.h"#include "led.h"#include "boot.h"#include "net.h"#include "sem.h"#include "crc.h"#include "atmel-flash.h"#include "simple_fs.h"#include <stdlib.h>#include "deluge_msgs.h"#include "aqueduct_shell.h"/* Protocol state variables: */static comBuf spkt;					// comBuf for sendingextern uint8_t deluge_portmap[DELUGE_INSTANCE_COUNT];extern deluge_entry table[DELUGE_INSTANCE_COUNT];#ifdef DELUGE_KEEP_STATSextern uint16_t packet_counts[DELUGE_STATS_COUNT][4];extern uint8_t deluge_recordstats;#endif/* Private functions: */#ifdef DELUGE_SYMMETRIC_LINKSstatic void checkNeighbor(deluge_app* app, uint16_t neighbor){	int8_t i;	//uint8_t mask = 1;	for (i=0; i<DELUGE_NEIGHBOR_COUNT; i++)	{		if (neighbor==app->neighbors[i]) {			return;		}		//mask <<= 1;	}	i = app->nextNeighbor;	app->neighbors[i] = neighbor;	//mask = 1 << i;	app->nextNeighbor = (i + 1) % DELUGE_NEIGHBOR_COUNT;	// Our neighbor list changed, this could affect routing	//app->detectedInconsistency = 1;	//app->symdtbs[i] = 255;}	static int8_t checkSymmetry(deluge_app* app, deluge_foot_summary* summary){	uint16_t id = mos_node_id_get();	uint8_t j;	for (j=0; j<DELUGE_NEIGHBOR_COUNT; j++)	{		if (id==summary->neighbors[j]) {			/*if (summary->version == app->dcb.version &&				(summary->highPage > app->dcb.highPage ||				(app->index != 0 && summary->highPage == app->dcb.highPage)))			{				app->symdtbs[i] = summary->dtb;			}*/			//app->symmetric |= mask;			return 1;		}	}	//app->symmetric &= ~mask;	// We're not in their list, send a summary	//app->detectedInconsistency = 1;	return 0;}static void clearSymmetry(deluge_app* app, uint16_t node){	uint8_t i;	//uint8_t mask = 1;	for (i=0; i<DELUGE_NEIGHBOR_COUNT; i++)	{		if (node==app->neighbors[i]) {			app->neighbors[i] = 0xFFFF;			//app->symdtbs[i] = 255;			//app->symmetry &= ~mask;			// Our neighbor list changed, this could affect routing			//app->detectedInconsistency = 1;		}		//mask <<= 1;	}}#elsestatic inline void checkNeighbor(deluge_app* app, uint16_t neighbor) {}#endif#if DELUGE_CACHE_PAGES > 1static int8_t cachedPageIndex(deluge_app* app, int8_t page){	int8_t i;	for (i=0; i</*DELUGE_CACHE_PAGES*/app->cacheSize; i++)		if (app->cache_map[i] == page)			return i;	return -1;}static void saveIncomingCachePage(deluge_app* app, int8_t page){	app->cache_map[app->incomingCachePage] = page;	app->incomingCachePage = (app->incomingCachePage + 1) % /*DELUGE_CACHE_PAGES*/app->cacheSize;}#endifstatic void setTimeout(deluge_app* app, uint32_t ticks, uint8_t reason){	table[app->index].nextState = reason;	mos_alarm_ticks(&table[app->index].alarm, ticks);}static inline void setRequestTimeout(deluge_app* app, uint8_t timeoutState){	#ifdef DELUGE_DTB_REQUEST_TIMEOUT	uint32_t reqT = random() % DELUGE_T_R;	if (app->dtb > 1) {		//printf("#nPacketsRequested: %C\n", app->nPacketsRequested);		reqT += app->dtb * (app->nPacketsRequested + DELUGE_OMEGA) * DELUGE_T_TX;	} else		reqT += DELUGE_OMEGA * DELUGE_T_TX;	#else	uint32_t reqT = DELUGE_OMEGA * DELUGE_T_TX + random() % DELUGE_T_R;	#endif	// this timeout will be reset as long as we keep getting data packets	setTimeout(app, reqT, timeoutState);}static void clearTimeout(deluge_app* app){	mos_remove_alarm(&table[app->index].alarm);}void stateTransition(deluge_app* app, uint8_t newState){	mos_remove_alarm(&table[app->index].alarm);	table[app->index].nextState = newState;	table[app->index].copyState = 1;	deluge_wakeup(&table[app->index]);}void deluge_saveState(deluge_app* app){	dev_ioctl(DEV_AVR_EEPROM, DEV_LOCK);	dev_ioctl (DEV_AVR_EEPROM, DEV_SEEK, DELUGE_CONTROL_BLOCK_ADDR + app->index*DELUGE_CONTROL_BLOCK_SIZE);	dev_write (DEV_AVR_EEPROM, (uint8_t *)&app->dcb, DELUGE_CONTROL_BLOCK_SIZE);	dev_ioctl(DEV_AVR_EEPROM, DEV_UNLOCK);}static void loadState(deluge_app* app){	dev_ioctl(DEV_AVR_EEPROM, DEV_LOCK);	dev_ioctl (DEV_AVR_EEPROM, DEV_SEEK, DELUGE_CONTROL_BLOCK_ADDR + app->index*DELUGE_CONTROL_BLOCK_SIZE);	dev_read (DEV_AVR_EEPROM, (uint8_t *)&app->dcb, DELUGE_CONTROL_BLOCK_SIZE);	dev_ioctl(DEV_AVR_EEPROM, DEV_UNLOCK);}static void saveBootCB(deluge_app* app, boot_control_block_t* cb){	dev_ioctl(DEV_AVR_EEPROM, DEV_LOCK);	dev_ioctl (DEV_AVR_EEPROM, DEV_SEEK, CONTROL_BLOCK_ADDR);	dev_write (DEV_AVR_EEPROM, (uint8_t *)cb, sizeof (boot_control_block_t));	dev_ioctl(DEV_AVR_EEPROM, DEV_UNLOCK);}static void loadBootCB(deluge_app* app, boot_control_block_t* cb){	dev_ioctl(DEV_AVR_EEPROM, DEV_LOCK);	dev_ioctl (DEV_AVR_EEPROM, DEV_SEEK, CONTROL_BLOCK_ADDR);	dev_read (DEV_AVR_EEPROM, (uint8_t *)cb, sizeof (boot_control_block_t));	dev_ioctl(DEV_AVR_EEPROM, DEV_UNLOCK);}static void moveToNextPage(deluge_app* app){	uint8_t index = app->dcb.incomingPage / 8;	uint8_t mask = 1 << (app->dcb.incomingPage % 8);		// clear bit for page we just finished	app->dcb.pagesNeeded[index] &= ~mask;		// find the next needed page	do {		app->dcb.incomingPage++;		mask = mask << 1;		if (mask == 0) {			mask = 1;			index++;		}		if (app->dcb.pagesNeeded[index] & mask) break;	}	while (app->dcb.incomingPage < app->dcb.goalPage);	app->dcb.highPage = app->dcb.incomingPage;}static void findBadPages(deluge_app* app){	uint8_t page = 0;	uint8_t index = 0;	uint8_t mask = 1;	uint16_t crc;		dev_ioctl(DEV_AVR_EEPROM, DEV_LOCK);	dev_ioctl (DEV_AVR_EEPROM, DEV_SEEK, DELUGE_PAGE_CRC_ADDR);	for (; page<app->dcb.goalPage; page++)	{		dev_read (DEV_AVR_EEPROM, (uint8_t *)&crc, 2);		if (crc != mos_file_crc(app->image_file, DELUGE_ADDR(page, 0), (uint32_t)DELUGE_PAGE_SIZE)) {			app->dcb.pagesNeeded[index] |= mask;			if (app->dcb.incomingPage == app->dcb.goalPage)				app->dcb.incomingPage = page;		}		mask = mask << 1;		if (mask == 0) {			mask = 1;			index++;		}	}	dev_ioctl(DEV_AVR_EEPROM, DEV_UNLOCK);		if (app->dcb.incomingPage == app->dcb.goalPage)		// The program CRC failed, but we didn't find a page that failed.		// This is extremely improbable, but just in case, we start all over:		app->dcb.incomingPage = 0;	app->dcb.highPage = app->dcb.incomingPage;}typedef void (*reboot_func)(void);void reboot(){	// Jump to bootloader	#ifdef DELUGE_PRINT_EVENT	printf_P(sReboot);	printf_P(sDisplayTime);		// display time	#endif	mos_disable_ints ();	SPCR &= (1 << SPE);	reboot_func rfunc = (reboot_func)0x1E000;	rfunc();}void runReprogram(deluge_app* app){	boot_control_block_t bcb;	loadBootCB(app, &bcb);	bcb.start_addr = app->image_file->start;	bcb.byte_count = app->image_file->length;	bcb.reprogram = 1;	saveBootCB(app, &bcb);		/*#ifdef DELUGE_KEEP_STATS	deluge_saveStats();	#endif*/		reboot();}static void doMaintain1(deluge_app* app){	//clearTimeout(app);	// beginning of round	if (app->detectedInconsistency) {		// Rule M.2		table[app->index].roundT = DELUGE_T_L;	} else {		// Rule M.3		if (table[app->index].roundT < DELUGE_T_H)			table[app->index].roundT *= 2;		if (table[app->index].roundT > DELUGE_T_H)			table[app->index].roundT = DELUGE_T_H;	}	mos_mutex_lock(&app->delugeLock);	app->nSummaries = 0;	app->nProfiles = 0;	app->detectedInconsistency = 0;	if (app->heardRequest) app->heardRequest--;	if (app->heardData) app->heardData--;	mos_mutex_unlock(&app->delugeLock);	//app->state = DELUGE_STATE_MAINTAIN2;	// wait until it's time to send our summary	app->sumT = (table[app->index].roundT>>1) + random() % (table[app->index].roundT>>1);	setTimeout(app, app->sumT, DELUGE_STATE_MAINTAIN2);}static void doMaintain2(deluge_app* app){	// Send a summary or a profile	if (app->heardObsolete) {		app->heardObsolete = 0;		if (app->nProfiles < DELUGE_K) {			// Rule M.4			deluge_foot_profile* profile = (deluge_foot_profile*)spkt.data;			mos_mutex_lock(&app->delugeLock);			profile->crc = app->dcb.programcrc;			profile->codeSize = app->dcb.codeSize;			profile->version = app->dcb.version;			profile->goalPage = app->dcb.goalPage;			mos_mutex_unlock(&app->delugeLock);						profile->id = mos_node_id_get();			profile->type = DELUGE_PACKET_PROFILE;			spkt.size = sizeof(deluge_foot_profile);						net_send(&spkt, DELUGE_PROTO_ID, deluge_portmap[app->index], deluge_portmap[app->index]);		}	} else if (/*(app->index == 0 && */app->nSummaries < DELUGE_K/*) ||		(app->index != 0 && app->nSummaries < DELUGE_FORWARD_K)*/)	{		// Rule M.1		deluge_foot_summary* summary = (deluge_foot_summary*)spkt.data;		mos_mutex_lock(&app->delugeLock);		#ifdef DELUGE_SYMMETRIC_LINKS		uint8_t i;		for (i = 0; i<DELUGE_NEIGHBOR_COUNT; i++)			summary->neighbors[i] = app->neighbors[i];		#endif		summary->version = app->dcb.version;		summary->highPage = app->dcb.highPage;		#ifdef DELUGE_NO_FORWARD		summary->dtb = 0;		#else		if (app->index == 0) {			summary->dtb = 0;		} else {			summary->dtb = app->dtb;		}		#endif		mos_mutex_unlock(&app->delugeLock);		summary->id = mos_node_id_get();		summary->type = DELUGE_PACKET_SUMMARY;		spkt.size = sizeof(deluge_foot_summary);								net_send(&spkt, DELUGE_PROTO_ID, deluge_portmap[app->index], deluge_portmap[app->index]);	}		// wait till the round is over	setTimeout(app, table[app->index].roundT - app->sumT, DELUGE_STATE_MAINTAIN);}static void doRx(deluge_app* app){	if (app->nRequests < DELUGE_LAMBDA) {		// Rule R.1		deluge_foot_request* request = (deluge_foot_request*)spkt.data;		mos_mutex_lock(&app->delugeLock);		request->to = app->updaterNode;		request->packets[0] = app->incomingPackets[0];		request->packets[1] = app->incomingPackets[1];		request->packets[2] = app->incomingPackets[2];		request->version = app->dcb.version;		request->page = app->dcb.incomingPage;		request->rateChange = app->nRequests-1;		mos_mutex_unlock(&app->delugeLock);		request->id = mos_node_id_get();		request->type = DELUGE_PACKET_REQUEST;		spkt.size = sizeof(deluge_foot_request);							net_send(&spkt, DELUGE_PROTO_ID, deluge_portmap[app->index], deluge_portmap[app->index]);		app->nRequests++;	} else {		// TODO: check reception rate		// Rule R.2		app->nRequests = 0;		// Assume parent node is dead; assign the highest possible DTB; 		// we'll take any node with a lower DTB		app->dtb = 0xFF;		/*#ifdef DELUGE_LINK_QUALITY		app->dtb_votes[app->updater_index] = 0;		#endif*/		#ifdef DELUGE_SYMMETRIC_LINKS		clearSymmetry(app, app->updaterNode);		/*if (nextSymmetric(app) != 255) {			app->nRequests = 0;			stateTransition(app, DELUGE_STATE_RX);			return;		}*/		#endif		stateTransition(app, DELUGE_STATE_MAINTAIN);		return;	}	// wait a while before requesting again	setRequestTimeout(app, DELUGE_STATE_RX);}static void doTx(deluge_app* app){	deluge_foot_data* foot = (deluge_foot_data*)&spkt.data[DELUGE_PACKET_SIZE];	mos_mutex_lock(&app->delugeLock);	foot->version = app->dcb.version;	#if DELUGE_CACHE_PAGES > 1	int8_t page = (app->index == 0)? app->outgoingPage : app->outgoingCachePage;	#else	int8_t page = app->outgoingPage;	#endif	foot->page = app->outgoingPage;	foot->id = mos_node_id_get();	foot->type = DELUGE_PACKET_DATA;			uint32_t crc_len = (app->outgoingPage == app->dcb.goalPage-1)?		app->dcb.codeSize % (uint32_t)DELUGE_PAGE_SIZE :		(uint32_t)DELUGE_PAGE_SIZE;	uint16_t crc = mos_file_crc(app->image_file, DELUGE_ADDR(page, 0), crc_len);		uint16_t txpackets[3] = { app->outgoingPackets[0], app->outgoingPackets[1], app->outgoingPackets[2] };	mos_mutex_unlock(&app->delugeLock);			while (app->state == DELUGE_STATE_TX && (txpackets[0] != 0 || txpackets[1] != 0 || txpackets[2] != 0))	{		uint8_t i, ih;		uint16_t txmask = 1;		uint8_t txidx = 0;		uint32_t txaddr = DELUGE_ADDR(page, 0);		for (i=0; i<DELUGE_PACKETS_PER_PAGE; i++)

⌨️ 快捷键说明

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