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

📄 bw_monitor.c

📁 Sample code for use on smp 863x processor.
💻 C
字号:
#define ALLOW_OS_CODE 1#include "../rmdef/rmdef.h"#include "../rmcore/include/rmcore.h"#include "../rua/include/rua.h"#include "../rua/include/rua_property.h"#include "get_key.h"#include <stdio.h>#include <unistd.h>#define CONTROLLER_COUNT 2#define GRAPHIC_MODE_WIDTH 64#define ACTIVE_CHAR '#'#define UNACTIVE_CHAR '-'#define MAX_CHAR '@'#define MAX_BANDWIDTH 1200#define ORIGIN_TO_CHAR(_org) ((_org==bw_monitor_sample_origin_global)?'T':((_org==bw_monitor_sample_origin_selection)?'S':'?'))/** TYPE DEFINITIONS **/enum bw_monitor_ouput_mode{	bw_monitor_ouput_mode_bw,	bw_monitor_ouput_mode_bar,	bw_monitor_ouput_mode_peak,	bw_monitor_ouput_mode_raw,};enum bw_monitor_sample_origin{	bw_monitor_sample_origin_global,	bw_monitor_sample_origin_selection,};struct channel_desc {	RMascii name[32];	RMuint8 value;};struct monitor_params {	struct SystemBlock_BWMonitorSelection_type selection;	struct SystemBlock_BWMonitorEnable_type enable;	RMbool dump_total;	RMbool dump_selected;};/** GLOBAL VARIABLES **/static enum bw_monitor_ouput_mode out_mode = bw_monitor_ouput_mode_bw;static RMascii bar[GRAPHIC_MODE_WIDTH + 1];static struct monitor_params config[CONTROLLER_COUNT];	/* one per controller *//* see at the end of this file for a script that generates this table */static const struct channel_desc channel_table[] = {      {name: "VOID", value:BWM_VOID},      {name: "ALL_BUSES_W", value:BWM_ALL_BUSES_W},      {name: "ALL_BUSES_R", value:BWM_ALL_BUSES_R},      {name: "MBUS_HOST0_R", value:BWM_MBUS_HOST0_R},      {name: "MBUS_HOST1_R", value:BWM_MBUS_HOST1_R},      {name: "MBUS_AUDIO0_R", value:BWM_MBUS_AUDIO0_R},      {name: "MBUS_AUDIO1_R", value:BWM_MBUS_AUDIO1_R},      {name: "MBUS_TRANSPORT_R", value:BWM_MBUS_TRANSPORT_R},      {name: "MBUS_VIDEO_MISC0_R", value:BWM_MBUS_VIDEO_MISC0_R},      {name: "MBUS_VIDEO_MISC1_R", value:BWM_MBUS_VIDEO_MISC1_R},      {name: "MBUS_VIDEO_DBLK0_R", value:BWM_MBUS_VIDEO_DBLK0_R},      {name: "MBUS_VIDEO_DBLK1_R", value:BWM_MBUS_VIDEO_DBLK1_R},      {name: "MBUS_VIDEO_STORE0_R", value:BWM_MBUS_VIDEO_STORE0_R},      {name: "MBUS_VIDEO_STORE1_R", value:BWM_MBUS_VIDEO_STORE1_R},      {name: "MBUS_ALL_R", value:BWM_MBUS_ALL_R},      {name: "MBUS_HOST0_W", value:BWM_MBUS_HOST0_W},      {name: "MBUS_HOST1_W", value:BWM_MBUS_HOST1_W},      {name: "MBUS_AUDIO0_W", value:BWM_MBUS_AUDIO0_W},      {name: "MBUS_AUDIO1_W", value:BWM_MBUS_AUDIO1_W},      {name: "MBUS_TRANSPORT_W", value:BWM_MBUS_TRANSPORT_W},      {name: "MBUS_VIDEO_MISC0_W", value:BWM_MBUS_VIDEO_MISC0_W},      {name: "MBUS_VIDEO_MISC1_W", value:BWM_MBUS_VIDEO_MISC1_W},      {name: "MBUS_VIDEO_DBLK0_W", value:BWM_MBUS_VIDEO_DBLK0_W},      {name: "MBUS_VIDEO_DBLK1_W", value:BWM_MBUS_VIDEO_DBLK1_W},      {name: "MBUS_VIDEO_STORE0_W", value:BWM_MBUS_VIDEO_STORE0_W},      {name: "MBUS_VIDEO_STORE1_W", value:BWM_MBUS_VIDEO_STORE1_W},      {name: "MBUS_ALL_W", value:BWM_MBUS_ALL_W},      {name: "VBUS_MV_L_R", value:BWM_VBUS_MV_L_R},      {name: "VBUS_MV_C_R", value:BWM_VBUS_MV_C_R},      {name: "VBUS_VCR_L_R", value:BWM_VBUS_VCR_L_R},      {name: "VBUS_VCR_C_R", value:BWM_VBUS_VCR_C_R},      {name: "VBUS_VP_R", value:BWM_VBUS_VP_R},      {name: "VBUS_HDSD_R", value:BWM_VBUS_HDSD_R},      {name: "VBUS_GFX_L_R", value:BWM_VBUS_GFX_L_R},      {name: "VBUS_GFX_C_R", value:BWM_VBUS_GFX_C_R},      {name: "VBUS_OSD_R", value:BWM_VBUS_OSD_R},      {name: "VBUS_SPU_R", value:BWM_VBUS_SPU_R},      {name: "VBUS_GACC_Y_R", value:BWM_VBUS_GACC_Y_R},      {name: "VBUS_GACC_X_R", value:BWM_VBUS_GACC_X_R},      {name: "VBUS_ALL_R", value:BWM_VBUS_ALL_R},      {name: "VBUS_GRAPH_IN_W", value:BWM_VBUS_GRAPH_IN_W},      {name: "VBUS_VIDEO_IN_W", value:BWM_VBUS_VIDEO_IN_W},      {name: "VBUS_GACC_W", value:BWM_VBUS_GACC_W},      {name: "VBUS_HDSD_W", value:BWM_VBUS_HDSD_W},      {name: "VBUS_ALL_W", value:BWM_VBUS_ALL_W},      {name: "GBUS_R", value:BWM_GBUS_R},      {name: "GBUS_W", value:BWM_GBUS_W},};/** STATIC FUNCTIONS **/static void print_usage(RMascii * progname){	RMuint32 i;	fprintf(stderr,		"Usage: %s [-o output_mode] [-dram N [c0 [c1 [c2 [c3]]]]  [-nt]]...\n\n"		"Prints a dynamic real-time view of the system's memory bandwidth load\n\n"		"-dram N enables monitoring of DRAM controller N (0..1)\n\n"		"-nt disables reporting the total bandwidth for controller specified by\n"		"the last -dram option\n\n"		"-o <bar|bw|raw|peak>: Selects the output mode. Default is\"bw\"\n"		"\tbar: prints a bar representing the bandwidth usage relative to the estimated limit\n"		"\tbw: prints the consumed bandwidth in kB/sec\n"		"\traw: prints the number of the accessed bytes and the measurement interval in usecs\n"		"\tpeak: prints the maximum instantaneous bandwidth measured so far\n\n"		"c0, c1, c2, c3 are the channel names of the channels to monitor on the\n"		"controller specified by tha last -dram option\n"		"When no channel names are specified, only the global bandwidth is output\n\n"		"Available channelid are:\n", progname);	for (i = 0; i < sizeof(channel_table) / sizeof(struct channel_desc); i++) {		fprintf(stderr, "\t%s\n", channel_table[i].name);	}}static RMstatus parse_cmdline(RMuint32 argc, RMascii ** argv){	RMuint32 dram_id = CONTROLLER_COUNT, arg = 1, i;	RMuint32 parsing_channels = 4;	if(argc < 2){		fprintf(stderr, "Too few options!\n%s -help for usage description\n",			argv[0]);		return RM_ERROR;	}	for (dram_id = 0; dram_id < CONTROLLER_COUNT; dram_id++) {		config[dram_id].enable.DRAMControllerId = dram_id;		config[dram_id].enable.Enable = FALSE;		config[dram_id].selection.DRAMControllerId = dram_id;		config[dram_id].selection.AddressHi = 0x0;		config[dram_id].selection.AddressLo = 0x0;		config[dram_id].selection.ConfigId = 0x0;		config[dram_id].selection.ChannelA = BWM_VOID;		config[dram_id].selection.ChannelB = BWM_VOID;		config[dram_id].selection.ChannelC = BWM_VOID;		config[dram_id].selection.ChannelD = BWM_VOID;		config[dram_id].dump_total = TRUE;		config[dram_id].dump_selected = FALSE;	}	while (arg < argc) {		if (RMCompareAscii(argv[arg], "-help")) {			print_usage(argv[0]);			return RM_ERROR;		}		else if (RMCompareAscii(argv[arg], "-o")) {			if (arg + 1 < argc) {				if(RMCompareAscii(argv[arg+1], "bw"))					out_mode = bw_monitor_ouput_mode_bw;				else if(RMCompareAscii(argv[arg+1], "bar"))					out_mode = bw_monitor_ouput_mode_bar;				else if(RMCompareAscii(argv[arg+1], "raw"))					out_mode = bw_monitor_ouput_mode_raw;				else if(RMCompareAscii(argv[arg+1], "peak"))					out_mode = bw_monitor_ouput_mode_peak;				else{					fprintf(stderr, "Invalid output mode \"%s\"!\n",argv[arg+1]);					return RM_ERROR;				}			}			else {				fprintf(stderr, "-o takes an argument\n");				return RM_ERROR;			}			arg += 2;		}		else if (RMCompareAscii(argv[arg], "-dram")) {			if (arg + 1 < argc) {				RMasciiToUInt32(argv[arg + 1], &(dram_id)); /* WARNING: there's no way to tell if the user passed a valid number */				if (dram_id > (CONTROLLER_COUNT - 1)) {					fprintf(stderr, "Invalid dram id %ld\n", dram_id);					return RM_ERROR;				}			}			else {				fprintf(stderr, "-dram takes a numeric parameter\n");				return RM_ERROR;			}			config[dram_id].enable.Enable = TRUE;			parsing_channels = 4;			arg += 2;		}		else if (RMCompareAscii(argv[arg], "-nt")) {			if (dram_id < CONTROLLER_COUNT) {				config[dram_id].dump_total = FALSE;			}			else {				for (dram_id = 0; dram_id < CONTROLLER_COUNT; dram_id++) {					config[dram_id].dump_total = FALSE;				}			}			arg++;		}		else if ((argv[arg][0] != '-') && (parsing_channels)) {			for (i = 0; i < sizeof(channel_table) / sizeof(struct channel_desc); i++) {				if (RMCompareAscii(argv[arg], channel_table[i].name)) {					break;				}			}			if (i == sizeof(channel_table) / sizeof(struct channel_desc)) {				fprintf(stderr, "I don't know about channelid \"%s\"!\n%s -help for a list of valid channel ids\n",					argv[arg], argv[0]);				return RM_ERROR;			}			config[dram_id].dump_selected = TRUE;			switch (parsing_channels) {			case 4:				config[dram_id].selection.ChannelA = channel_table[i].value;				break;			case 3:				config[dram_id].selection.ChannelB = channel_table[i].value;				break;			case 2:				config[dram_id].selection.ChannelC = channel_table[i].value;				break;			case 1:				config[dram_id].selection.ChannelD = channel_table[i].value;				break;			}			parsing_channels--;			arg++;		}		else{			fprintf(stderr, "Sorry, I don't understand \"%s\"!\n%s -help for a list of valid options\n", argv[arg], argv[0]);			return RM_ERROR;		}	}	return RM_OK;}static void print_sample(RMuint32 bytes, RMuint32 interval, RMuint32 dram_id, enum bw_monitor_sample_origin origin){	RMbool new_max = FALSE;	RMuint32 i;	RMuint32 instant_bw = 0 , max_id = 0, bar_active;	static RMuint32 max_bw[CONTROLLER_COUNT*2] = {0,};	if(out_mode != bw_monitor_ouput_mode_raw){		if (interval >> 2 == 0)	/* this should not happen */			return;		instant_bw = (bytes << 4) / (interval >> 2);		instant_bw *= 15625;	/* (1000000/(16*4)) */		max_id = 2*dram_id + ((origin == bw_monitor_sample_origin_global)?0:1);		if(instant_bw > max_bw[max_id]){			new_max = TRUE;			max_bw[max_id] = instant_bw;		}	}				switch(out_mode){	case bw_monitor_ouput_mode_bw:		fprintf(stdout, "%c_dram%ld %09ldkbps (%04ldMBps)\n", ORIGIN_TO_CHAR(origin), dram_id, instant_bw >> 10, instant_bw >> 20);		break;	case bw_monitor_ouput_mode_bar:		bar_active = instant_bw / ((1024 * 1024 * MAX_BANDWIDTH) / GRAPHIC_MODE_WIDTH);		for (i = 0; i < GRAPHIC_MODE_WIDTH; i++) {			if (i < bar_active) {				bar[i] = ACTIVE_CHAR;			}			else {				bar[i] = UNACTIVE_CHAR;			}		}		bar[i] = '\0';		fprintf(stdout, "[%c%ld]%s (%04ldMBps)\n", ORIGIN_TO_CHAR(origin), dram_id, bar, instant_bw >> 20);		break;	case bw_monitor_ouput_mode_peak:		if(new_max){			fprintf(stdout, "%c_dram%ld %09ldkbps (%04ldMBps)\n", ORIGIN_TO_CHAR(origin), dram_id, max_bw[max_id]>>10, max_bw[max_id] >> 20);		}		break;	case bw_monitor_ouput_mode_raw:		fprintf(stdout, "%c:%ld:%010ld:%010ld\n", ORIGIN_TO_CHAR(origin), dram_id, bytes, interval);		break;			}}int main(int argc, char **argv){	struct RUA *pRUA = NULL;	RMstatus err;	RMuint32 dram_id;	struct EMhwlibBWMonitorSample entry;	err = parse_cmdline(argc, argv);	if (RMFAILED(err)) {		return -1;	}	err = RUACreateInstance(&pRUA, 0);	if (RMFAILED(err)) {		fprintf(stderr, "Error creating RUA instance! %d\n", err);		return -1;	}	for (dram_id = 0; dram_id < CONTROLLER_COUNT; dram_id++) {		while (RUASetProperty(pRUA, SystemBlock,				      RMSystemBlockPropertyID_BWMonitorSelection, &(config[dram_id].selection),				      sizeof(config[dram_id].selection), 0) == RM_PENDING) {		}		while (RUASetProperty(pRUA, SystemBlock,				      RMSystemBlockPropertyID_BWMonitorEnable, &(config[dram_id].enable),				      sizeof(config[dram_id].enable), 0) == RM_PENDING) {		}	}	RMTermInit(TRUE);	RMSignalInit(NULL, NULL);	while (TRUE) {		if (RMKeyAvailable()) {			if(RMGetKey() == 'q')				break;		}		while (RUAGetProperty(pRUA, SystemBlock, RMSystemBlockPropertyID_BWMonitorSample, &entry, sizeof(entry)) == RM_OK) {			if (config[entry.DRAMControllerId].dump_total) {				print_sample(entry.TotalTransfers, entry.Interval, entry.DRAMControllerId, bw_monitor_sample_origin_global);			}			if (config[entry.DRAMControllerId].dump_selected) {				print_sample(entry.SelectedTransfers, entry.Interval, entry.DRAMControllerId, bw_monitor_sample_origin_selection);			}		}		usleep(500000);	}		RMTermExit();		for (dram_id = 0; dram_id < CONTROLLER_COUNT; dram_id++) {		config[dram_id].enable.Enable = FALSE;		while (RUASetProperty(pRUA, SystemBlock,				      RMSystemBlockPropertyID_BWMonitorEnable, &(config[dram_id].enable),				      sizeof(config[dram_id].enable), 0) == RM_PENDING);	}	/* flush the sample fifo */	while (RUAGetProperty(pRUA, SystemBlock, RMSystemBlockPropertyID_BWMonitorSample, &entry, sizeof(entry)) == RM_OK);	err = RUADestroyInstance(pRUA);	if (RMFAILED(err)) {		fprintf(stderr, "Cannot destroy RUA instance %d\n", err);		return -1;	}	return 0;}/* script to generate the channel table structure *//* echo \{; for channel_label in $(cat emhwlib_globaltypes.h | grep BWM_ | cut -d ' ' -f 2) ;do echo \{name:\"${channel_label:4}\", value:${channel_label} \}, ;done;echo \}; */

⌨️ 快捷键说明

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