musb_core.c 解析

本文详细探讨musb_core.c文件,它是USB通用接口musb模块的核心部分,涉及USB、musb、DMA及平台模块等多个组件。musb_init()函数初始化过程包括musb_driver结构体的musb_driver_name和fifo_mode设置。

musb_core.c 是usb_general.c 调用进musb模块的核心函数,

里面有usb,musb,dma,platform模块等内容。

1. musb_init():

/* make us init after usbcore and i2c (transceivers, regulators, etc)
 * and before usb gadget and host-side drivers start to register
 */
fs_initcall(musb_init);

static int __init musb_init(void)
{
#ifdef CONFIG_USB_MUSB_HDRC_HCD
	if (usb_disabled())
		return 0;
#endif

	pr_info("%s: version " MUSB_VERSION ", "
#ifdef CONFIG_MUSB_PIO_ONLY               //这些宏由内核配置选项中来
		"pio"
#elif defined(CONFIG_USB_TI_CPPI_DMA)
		"cppi-dma"
#elif defined(CONFIG_USB_INVENTRA_DMA)
		"musb-dma"
#elif defined(CONFIG_USB_TUSB_OMAP_DMA)
		"tusb-omap-dma"
#elif defined(CONFIG_USB_CARTESIO_DMA)
		"pl080-dma"
#else
		"?dma?"
#endif
		", "
#ifdef CONFIG_USB_MUSB_OTG
		"otg (peripheral+host)"
#elif defined(CONFIG_USB_GADGET_MUSB_HDRC)
		"peripheral"
#elif defined(CONFIG_USB_MUSB_HDRC_HCD)
		"host"
#endif
		", debug=%d\n",
		musb_driver_name, musb_debug);
	return platform_driver_probe(&musb_driver, musb_probe);  //这里调用了platform 平台函数,注册进platform类型队列中。
}

musb_driver:

static struct platform_driver musb_driver = {
	.driver = {
		.name		= (char *)musb_driver_name, 
		.bus		= &platform_bus_type,   //platform bus类型
		.owner		= THIS_MODULE,
		.pm		= MUSB_DEV_PM_OPS,    //PM OPS, suspend+resume
	},
	.remove		= __exit_p(musb_remove),  
	.shutdown	= musb_shutdown,
};

1.1 musb_driver_name 定义:

#define MUSB_DRIVER_NAME "musb_hdrc"
const char musb_driver_name[] = MUSB_DRIVER_NAME;
1.2 MUSB_DEV_PM_OPS 定义:

#define MUSB_DEV_PM_OPS (&musb_dev_pm_ops)
#else
#define	MUSB_DEV_PM_OPS	NULL
#endif
static const struct dev_pm_ops musb_dev_pm_ops = {
	.suspend	= musb_suspend,
	.resume         = musb_resume_noirq,
};
static int musb_suspend(struct device *dev)

static int musb_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	unsigned long	flags;
	struct musb	*musb = dev_to_musb(&pdev->dev);

	if (!musb->clock)
		return 0;

	spin_lock_irqsave(&musb->lock, flags);

	if (is_peripheral_active(musb)) {
		/* FIXME force disconnect unless we know USB will wake
		 * the system up quickly enough to respond ...
		 */
	} else if (is_host_active(musb)) {
		/* we know all the children are suspended; sometimes
		 * they will even be wakeup-enabled.
		 */
	}

	musb_save_context(musb);

	if (musb->set_clock)
		musb->set_clock(musb->clock, 0);
	else
		clk_disable(musb->clock);
	spin_unlock_irqrestore(&musb->lock, flags);
	return 0;
}
static int musb_resume_noirq(struct device *dev):

static int musb_resume_noirq(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct musb	*musb = dev_to_musb(&pdev->dev);
#ifdef MUSB_RESTORE_REG
	int status;
#endif
	if (!musb->clock)
		return 0;

	if (musb->set_clock)
		musb->set_clock(musb->clock, 1);
	else
		clk_enable(musb->clock);

	musb_restore_context(musb);

#ifdef MUSB_RESTORE_REG
	status = musb_core_init(musb->is_multipoint
				? MUSB_CONTROLLER_MHDRC
				: MUSB_CONTROLLER_HDRC, musb);
	if (status < 0)
		return status;

	/* we need to apply the DEV_CTRL SESSION bit to initialize the VBUS.
	 * This should be generally called through root hub POWERON feature,
	 * but it is needed also  here if autosuspend is disabled.
         */
	musb_start(musb);

	/* wait for the connect interrupt */
	mdelay(200);
#endif
	return 0;
}
1.4  static int __exit musb_remove(struct platform_device *pdev)
static int __exit musb_remove(struct platform_device *pdev)
{
	struct musb	*musb = dev_to_musb(&pdev->dev);
	void __iomem	*ctrl_base = musb->ctrl_base;

	/* this gets called on rmmod.
	 *  - Host mode: host may still be active
	 *  - Peripheral mode: peripheral is deactivated (or never-activated)
	 *  - OTG mode: both roles are deactivated (or never-activated)
	 */
	musb_shutdown(pdev);
#ifdef CONFIG_USB_MUSB_HDRC_HCD
	if (musb->board_mode == MUSB_HOST)
		usb_remove_hcd(musb_to_hcd(musb));
#endif
	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);
	musb_platform_exit(musb);
	musb_writeb(musb->mregs, MUSB_DEVCTL, 0);

	musb_free(musb);
	iounmap(ctrl_base);
	device_init_wakeup(&pdev->dev, 0);
#ifndef CONFIG_MUSB_PIO_ONLY
	pdev->dev.dma_mask = orig_dma_mask;
#endif
	return 0;
}
1.5 static void musb_shutdown(struct platform_device *pdev)
static void musb_shutdown(struct platform_device *pdev)
{
	struct musb	*musb = dev_to_musb(&pdev->dev);
	unsigned long	flags;

	spin_lock_irqsave(&musb->lock, flags);
	musb_platform_disable(musb);
	musb_generic_disable(musb);
	if (musb->clock)
		clk_put(musb->clock);
	spin_unlock_irqrestore(&musb->lock, flags);

	/* FIXME power down */
}
2.  musb_cleanup():

static void __exit musb_cleanup(void)
{
	platform_driver_unregister(&musb_driver);
}
module_exit(musb_cleanup);
3. static int __init musb_probe(struct platform_device *pdev)
static int __init musb_probe(struct platform_device *pdev)
{
	struct device	*dev = &pdev->dev;
	int		irq = platform_get_irq(pdev, 0);
	int		status;
	struct resource	*iomem;
	void __iomem	*base;

	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);  //获取 platform 资源
	if (!iomem || irq == 0)
		return -ENODEV;

	base = ioremap(iomem->start, resource_size(iomem));    //映射内存
	if (!base) {
		dev_err(dev, "ioremap failed\n");
		return -ENOMEM;
	}

#ifndef CONFIG_MUSB_PIO_ONLY
	/* clobbered by use_dma=n */
	orig_dma_mask = dev->dma_mask;         //如果内核配置了CONFIG_MUSB_PIO_ONLY,则屏蔽DMA
#endif
	status = musb_init_controller(dev, irq, base);   //这个才是主要的函数
	if (status < 0)
		iounmap(base);

	return status;
}
4. static int __init
musb_init_controller(struct
代码架构描述,详细,每行每部分 # coding=utf-8 import copy import datetime import os import sys import re import math import shutil import logging import shlex from core.fpsgo_test_auditor import FpsgoTestAuditor from core.frameload_auditor import FrameLoadAuditor from core.frame_boost_auditor import FrameBoostAuditor from core.uifirst_auditor import UiFirstAuditor from core.gpu_auditor import GpuAuditor if 'win' in sys.platform: sys.path.insert(0, "third_party_win") #print("third_party_win") else: #print("third_party_linux") sys.path.insert(0, "third_party_linux") #sys.setrecursionlimit(2000) import importer.importall as importall from importer.process_data_importer import ProcessDataImporter from importer.trace_event_importer import TraceEventImporter from linux_perf.ftrace_importer import FTraceImporter from core.auditorall import Auditorall from android.android_auditor import AndroidAuditor from core.vsync_auditor import VSyncAuditor from core.cpu_freq_auditor import CpuFreqAuditor from core.cpu_idle_auditor import CpuIdleAuditor from core.cpu_load_auditor import CPULoadAuditor from core.cpu_power_auditor import CPUPowerAuditor from core.irq_auditor import IrqAuditor from core.slice_auditor import SliceAuditor from core.thread_state_auditor import ThreadStateAuditor from core.thread_dependency_auditor import ThreadDependencyAuditor from core.queueBuffer_auditor import QueueBufferAuditor from core.syscall_auditor import SyscallAuditor from core.block_auditor import BlockAuditor from core.mmc_auditor import MmcAuditor from core.ufs_auditor import UfsAuditor from core.uag_auditor import UagAuditor from core.mtk_pm_qos_auditor import MtkpmqosAuditor from core.chrome_cpu_load_auditor import ChromeCpuLoadAuditor from core.StacktraceAuditor import StacktraceAuditor from core.mtk_sched_auditor import MtkSchedAuditor from core.vmscan_auditor import VmScanAuditor from core.mmstat_auditor import MmstatAuditor from core.kmem_auditor import KmemAuditor from core.android_fs_auditor import AndroidfsAuditor from core.filemap_auditor import FileMapAuditor from core.f2fs_auditor import F2fsAuditor from core.mmap_lock_auditor import Mmap_lockAuditor from core.signal_auditor import SignalAuditor from core.regmap_auditor import RegmapAuditor from core.rwmmio_auditor import RwmmioAuditor from core.orms_auditor import OrmsAuditor from core.perflock_auditor import PerflockAuditor from core.urcc_auditor import UrccAuditor from core.dcvs_auditor import DcvsAuditor from core.dma_buf_alloc_auditor import Dma_buf_alloc_Auditor from core.thermal_auditor import ThermalAuditor from core.musb_auditor import MusbAuditor from core.mali_auditor import MaliAuditor from model.content import Content from model.model import Model from base.traceHTMLParser import traceHTMLParser from base.output_excel import OutputExcel import pandas as pd from base.excel_style import ExcelStyle from model.helper.app_frame import AppFrame from model.helper.composer_frame import ComposerFrame from model.helper.fence_process import FenceProcess import optparse import gc DEBUG = False class Controller(object): #@profile def __init__(self, filename, device, option, argv_str): logging.info("init") self.filename = filename if option.frameTest == True: option.wakingEnable = True self.model = Model(option, argv_str) self.traces = [] self.importerall = importall.Importall() self.auditorall = Auditorall() self.fenceprocess = None self.appframe = None self.composerframe = None self.composerframeStatisticsTuple = None self.cpufreqOutput = None self.starttime = option.starttime self.replaceTitle = option.replaceTitle self.device = device self.perfetto = False self.atrace = False self.get_power_into_ret = False if os.path.splitext(filename)[1] == '.txt' and option.power_info_get != None: self.get_power_info(option.power_info_get ) self.get_power_into_ret = True return if os.path.splitext(filename)[1] == '.perfetto-trace' or os.path.splitext(filename)[1] == '.perfetto': self.perfetto = True self.replaceTitle = True self.model.replaceTitle = True ext = os.path.splitext(filename)[1] logging.info("perfetto trace") name = self.filename.rstrip('perfetto-trace').rstrip('.') if 'win' in sys.platform: cmd = "traceconv systrace " + self.filename + " " + name +'.html' else: cmd = "./traceconv systrace " + self.filename + " " + name +'.html' logging.info(cmd) os.system(cmd) logging.info("traceconv_end") self.filename = name + '.html' self.updatetsfile = name + "_updateTs" + ".html" elif os.path.splitext(filename)[1] == '.pftrace': self.perfetto = True self.replaceTitle = True self.model.replaceTitle = True ext = os.path.splitext(filename)[1] logging.info("pftrace") name = self.filename.rstrip('pftrace').rstrip('.') if 'win' in sys.platform: cmd = "traceconv systrace " + self.filename + " " + name +'.html' else: cmd = "./traceconv systrace " + self.filename + " " + name +'.html' logging.info(cmd) os.system(cmd) logging.info("traceconv_end") self.filename = name + '.html' self.updatetsfile = name + "_updateTs" + ".html" elif os.path.splitext(filename)[1] == '.out': ext = os.path.splitext(filename)[1] logging.info("atrace") name = self.filename.rstrip('out').rstrip('.') cmd = "python chromium-trace/systrace.py --from-file=" + self.filename logging.info(cmd) os.system(cmd) self.filename = name + '.html' self.updatetsfile = name + "_updateTs" + ".html" elif os.path.splitext(filename)[1] == '.atrace': ext = os.path.splitext(filename)[1] logging.info("atrace") name = self.filename.rstrip('atrace').rstrip('.') cmd = "python chromium-trace/systrace.py --from-file=" + self.filename logging.info(cmd) os.system(cmd) self.filename = name + '.html' self.updatetsfile = name + "_updateTs" + ".html" else: self.updatetsfile = self.getfilename(filename) + "_updateTs" + ".html" Content.startContent(self.device) self.titleEnd = \ '''<!-- BEGIN TRACE --> <script class="trace-data" type="application/text">\n''' def getfilename(self, filename): ret = filename.rstrip('html').rstrip('.') return ret def setappframeTuple(self, appframeTuple): if appframeTuple != None: self.model.appframe = appframeTuple[0] self.model.appframetitle = appframeTuple[1] self.model.appbadframe = appframeTuple[2] self.model.appwarningframe = appframeTuple[3] else: self.model.appframe = None self.model.appframetitle = None self.model.appbadframe = None self.model.appwarningframe = None def setcompserframeTuple(self, composerframeTuple): if composerframeTuple != None: self.model.composerframe = composerframeTuple[0] self.model.composerframetitle = composerframeTuple[1] self.model.composerFrameMissed = composerframeTuple[2] else: self.model.composerframe = None self.model.composerframetitle = None self.model.composerFrameMissed = None def setAppStatisticsTuple(self, appframeStatisticsTuple): if appframeStatisticsTuple != None and appframeStatisticsTuple.__len__() != 0: self.model.appStatistics = appframeStatisticsTuple[0] self.model.appStatisticstitle = appframeStatisticsTuple[1] else: self.model.appStatistics = None self.model.appStatisticstitle = None def setComposerStatisticsTuple(self, composerStatisticsTuple): if composerStatisticsTuple != None and composerStatisticsTuple.__len__() != 0: self.model.composerStatistics = composerStatisticsTuple[0] self.model.composerStatisticstitle = composerStatisticsTuple[1] else: self.model.composerStatistics = None self.model.composerStatisticstitle = None #@profile def out(self): self.outputexcel = OutputExcel(self.model, self.getfilename(self.filename), self.model.starttime, self.model.endtime) self.setappframeTuple(self.model.appframeTuple) self.setcompserframeTuple(self.model.compserframeTuple) self.setAppStatisticsTuple(self.model.appframeStatisticsTuple) self.setComposerStatisticsTuple(self.model.composerframeStatisticsTuple) ret = self.outputexcel.write() logging.info("===============================================================") try: logging.info("Total Duration: " + str(format(1, '.3%'))+ "(" + str(self.model.bounds.max - self.model.bounds.min) + "ms, " + str(0) + "~" + str(self.model.bounds.max - self.model.bounds.min) + ")") except Exception: logging.info("Total Duration: " + str(format(1, '.3%')) + "none") try: ignoredDurtion = (self.model.starttime + (self.model.bounds.max - self.model.bounds.min) - self.model.endtime)/(self.model.bounds.max -self.model.bounds.min) except Exception: logging.info("Ignored Duration: none") try: logging.info("Ignored Duration:" +str(format(ignoredDurtion, '.3%'))) except Exception: logging.info("none") try: if abs(self.model.bounds.max - self.model.bounds.min - self.model.endtime) <= 0.001: logging.info("Ignored Duration:" +str(format(ignoredDurtion, '.3%')) + "(" + str(self.model.starttime + (self.model.bounds.max - self.model.bounds.min) - self.model.endtime) + "ms, " + str(0) + "~" + str(self.model.starttime) + ")") else: logging.info("Ignored Duration:" +str(format(ignoredDurtion, '.3%')) + "(" + str(self.model.starttime + (self.model.bounds.max - self.model.bounds.min) - self.model.endtime) + "ms, " + str(0) + "~" + str(self.model.starttime) + "," + str(self.model.endtime) +"~" + str(self.model.bounds.max - self.model.bounds.min) + ")") except Exception: logging.info("Ignored Duration:" + "none") try: analyzedDurtion = self.model.getDuration()/(self.model.bounds.max -self.model.bounds.min) logging.info("Analyzed Duration:" +str(format(analyzedDurtion, '.3%')) + "(" + str(self.model.getDuration()) + "ms, " + str(self.model.starttime) + "~" + str(self.model.endtime) + ")") except Exception: logging.info("Analyzed Duration: none") if self.model.warning != None: logging.info(self.model.warning) logging.info("===============================================================") return ret def get_power_info(self, type): dynamic_power_coefficient_none = False logging.info("get_power_info") cpu_capacity_re = "/sys/devices/system/cpu/cpu(\d+),cpu_capacity=(\d+)" cpu_freq_re = "/sys/devices/system/cpu/cpu(\d+)/cpufreq,cpuinfo_max_freq=(\d+),cpuinfo_min_freq=(\d+)" power_coefficient_re = "/proc/device-tree/cpus/cpu@(\d+),capacity-dmips-mhz=(.*),dynamic-power-coefficient=(.*)" no_power_coefficient_re = "/proc/device-tree/cpus/cpu@(\d+),capacity-dmips-mhz=(.*)" if type == 1: #qcom #energy_model_re = "/sys/kernel/debug/energy_model/cpu(\d+)/ps:(\d+),cost=(\d+),power=(\d+),frequency=(\d+)" energy_model_re = "/sys/kernel/debug/energy_model/(?:cpu|pd)(\d+)/(?:ps|cs):(\d+),cost=(\d+),power=(\d+),frequency=(\d+)" elif type == 2: energy_model_re = "/sys/kernel/debug/pd(\d+)/cs:(\d+),cost=(\d+),power=(\d+),frequency=(\d+)" txtFile = open(self.filename, 'r') txtContent = txtFile.read() txtFile.close() txtContent = re.split('\n', txtContent) cpu_freq_info = {} cluser_first_cpuid = {} cpu_info = [] # # cpu_id, cpu_capacity,cpuinfo_max_freq,cpuinfo_min_freq,capacity_dmips_mhz,dynamic_power_coefficient,cpu_freq_info little_core_dynamic_power_coefficient = "little_core_dynamic-power-coefficient = " middle_core_dynamic_power_coefficient = "middle_core_dynamic-power-coefficient = " big_core_dynamic_power_coefficient = "big_core_dynamic-power-coefficient = " little_core_mips_per_mhz = "little_core_mips_per_mhz = " middle_core_mips_per_mhz = "middle_core_mips_per_mhz = " big_core_mips_per_mhz = "big_core_mips_per_mhz = " capacity_dmips_mhz_cpu_id = 0 for line in txtContent: event = re.match(cpu_capacity_re, line) if event != None: #print(event.group(0)) cpu_id = int(event.group(1)) cpu_capacity = int(event.group(2)) logging.info(cpu_id), logging.info(cpu_capacity) cpu_info.append([cpu_id, cpu_capacity]) event = re.match(cpu_freq_re, line) if event != None: #print(event.group(0)) cpu_id = int(event.group(1)) cpuinfo_max_freq = int(event.group(2)) cpuinfo_min_freq = int(event.group(3)) logging.info(cpu_id), logging.info(cpuinfo_max_freq), logging.info(cpuinfo_min_freq) cpu_info[cpu_id].append(cpuinfo_max_freq) cpu_info[cpu_id].append(cpuinfo_min_freq) event = re.match(power_coefficient_re, line) if event != None: # cpu_id = int(event.group(1), 16) # if cpu_id >= 16*16: # cpu_id = cpu_id/(16*16) capacity_dmips_mhz = int(event.group(2), 16) dynamic_power_coefficient = int(event.group(3), 16) # print("cpu_id="), # print(capacity_dmips_mhz_cpu_id), # print(capacity_dmips_mhz), # print(dynamic_power_coefficient) cpu_info[capacity_dmips_mhz_cpu_id].append(capacity_dmips_mhz) cpu_info[capacity_dmips_mhz_cpu_id].append(dynamic_power_coefficient) capacity_dmips_mhz_cpu_id += 1 else: event = re.match(no_power_coefficient_re, line) if event != None: dynamic_power_coefficient_none = True # cpu_id = int(event.group(1), 16) # if cpu_id >= 16*16: # cpu_id = cpu_id/(16*16) capacity_dmips_mhz = int(event.group(2), 16) dynamic_power_coefficient = None logging.info("cpu_id="), logging.info(capacity_dmips_mhz_cpu_id), logging.info(capacity_dmips_mhz), logging.info(dynamic_power_coefficient) cpu_info[capacity_dmips_mhz_cpu_id].append(capacity_dmips_mhz) cpu_info[capacity_dmips_mhz_cpu_id].append(dynamic_power_coefficient) capacity_dmips_mhz_cpu_id += 1 event = re.match(energy_model_re, line) if event != None: cpu_id = int(event.group(1)) freq = int(event.group(2)) cost = int(event.group(3)) power = int(event.group(4)) logging.info(cpu_id), logging.info(freq), logging.info(cost) logging.info(power) if cpu_freq_info.get(cpu_id) == None: cpu_freq_info[cpu_id] = [[cpu_id, freq, cost, power]] else: cpu_freq_info.get(cpu_id).append([cpu_id, freq, cost, power]) if cluser_first_cpuid.get(cpu_id) == None: cluser_first_cpuid[cpu_id] = cpu_id cpu_info[cpu_id].append(cpu_freq_info.get(cpu_id)) index = 0 if cluser_first_cpuid.__len__() >= 4: middle2_core_mips_per_mhz = "middle2_core_mips_per_mhz = " middle2_core_dynamic_power_coefficient = "middle2_core_dynamic-power-coefficient = " little_core_max_freq = "little_core_max_freq = " little_core_min_freq = "little_core_min_freq = " middle_core_max_freq = "middle_core_max_freq = " middle_core_min_freq = "middle_core_min_freq = " if cluser_first_cpuid.__len__() >= 4: middle2_core_max_freq = "middle2_core_max_freq = " middle2_core_min_freq = "middle2_core_min_freq = " big_core_max_freq = "big_core_max_freq = " big_core_min_freq = "big_core_min_freq = " little_core_cpufreq = "little_core_cpufreq = " middle_core_cpufreq = "middle_core_cpufreq = " if cluser_first_cpuid.__len__() >= 4: middle2_core_cpufreq = "middle2_core_cpufreq = " big_core_cpufreq = "big_core_cpufreq = " little_core_uv = "little_core_uv = " middle_core_uv = "middle_core_uv = " if cluser_first_cpuid.__len__() >= 4: middle2_core_uv = "middle2_core_uv = " big_core_uv = "big_core_uv = " if dynamic_power_coefficient_none == True: little_core_power = "little_core_power = " middle_core_power = "middle_core_power = " if cluser_first_cpuid.__len__() >= 4: middle2_core_power = "middle2_core_power = " big_core_power = "big_core_power = " for cpuid in range (0, cpu_info.__len__()): if cluser_first_cpuid.get(cpuid) != None: cpu_info[cpuid][6].sort(key=lambda x: x[1], reverse=False) cpu_capacity = cpu_info[cpuid][1] dynamic_power_coefficient = cpu_info[cpuid][5] logging.info("cpu_capacity="), logging.info(cpu_capacity) if cluser_first_cpuid.__len__() <= 3: if index == 0: little_core_max_freq += str(cpu_info[cpuid][2]) little_core_min_freq += str(cpu_info[cpuid][3]) little_core_dynamic_power_coefficient += str(dynamic_power_coefficient) little_core_mips_per_mhz += str(int(cpu_info[7][2] / float(cpu_info[cpuid][2]) * cpu_capacity)) elif index == 1 and cluser_first_cpuid.__len__() == 3: middle_core_max_freq += str(cpu_info[cpuid][2]) middle_core_min_freq += str(cpu_info[cpuid][3]) middle_core_dynamic_power_coefficient += str(dynamic_power_coefficient) middle_core_mips_per_mhz += str(int(cpu_info[7][2]/float(cpu_info[cpuid][2]) * cpu_capacity)) else: big_core_max_freq += str(cpu_info[cpuid][2]) big_core_min_freq += str(cpu_info[cpuid][3]) big_core_dynamic_power_coefficient += str(dynamic_power_coefficient) logging.info(int(cpu_info[7][2] / float(cpu_info[cpuid][2]) * cpu_capacity)) big_core_mips_per_mhz += str(int(cpu_info[7][2] / float(cpu_info[cpuid][2]) * cpu_capacity)) else: if index == 0: little_core_max_freq += str(cpu_info[cpuid][2]) little_core_min_freq += str(cpu_info[cpuid][3]) little_core_dynamic_power_coefficient += str(dynamic_power_coefficient) little_core_mips_per_mhz += str(int(cpu_info[7][2] / float(cpu_info[cpuid][2]) * cpu_capacity)) elif index == 1 and cluser_first_cpuid.__len__() == 4: middle_core_max_freq += str(cpu_info[cpuid][2]) middle_core_min_freq += str(cpu_info[cpuid][3]) middle_core_dynamic_power_coefficient += str(dynamic_power_coefficient) middle_core_mips_per_mhz += str(int(cpu_info[7][2]/float(cpu_info[cpuid][2]) * cpu_capacity)) elif index == 2 and cluser_first_cpuid.__len__() == 4: middle2_core_max_freq += str(cpu_info[cpuid][2]) middle2_core_min_freq += str(cpu_info[cpuid][3]) middle2_core_dynamic_power_coefficient += str(dynamic_power_coefficient) middle2_core_mips_per_mhz += str(int(cpu_info[7][2]/float(cpu_info[cpuid][2]) * cpu_capacity)) else: big_core_max_freq += str(cpu_info[cpuid][2]) big_core_min_freq += str(cpu_info[cpuid][3]) big_core_dynamic_power_coefficient += str(dynamic_power_coefficient) logging.info(int(cpu_info[7][2] / float(cpu_info[cpuid][2]) * cpu_capacity)) big_core_mips_per_mhz += str(int(cpu_info[7][2] / float(cpu_info[cpuid][2]) * cpu_capacity)) logging.info(cpu_info[cpuid][0:6]) for freqinfo in cpu_info[cpuid][6]: freq = freqinfo[1] power = freqinfo[3] power = power/1000.0 # SM7675,SM8650,SM8635 logging.info(power), logging.info(cpu_capacity), logging.info(freq) if dynamic_power_coefficient != None: uv = int(math.sqrt(float(power)*1000000/(dynamic_power_coefficient*freq))*1000*1000) else: uv = None if cluser_first_cpuid.__len__() <= 3: if index == 0: little_core_uv += str(uv) + "," little_core_cpufreq += str(freq) + "," if dynamic_power_coefficient_none == True: little_core_power += str(power) + "," elif index == 1 and cluser_first_cpuid.__len__() == 3: middle_core_uv += str(uv) + "," middle_core_cpufreq += str(freq) + "," if dynamic_power_coefficient_none == True: middle_core_power += str(power) + "," else: big_core_uv += str(uv) + "," big_core_cpufreq += str(freq) + "," if dynamic_power_coefficient_none == True: big_core_power += str(power) + "," else: if index == 0: little_core_uv += str(uv) + "," little_core_cpufreq += str(freq) + "," if dynamic_power_coefficient_none == True: little_core_power += str(power) + "," elif index == 1 and cluser_first_cpuid.__len__() == 4: middle_core_uv += str(uv) + "," middle_core_cpufreq += str(freq) + "," if dynamic_power_coefficient_none == True: middle_core_power += str(power) + "," elif index == 2 and cluser_first_cpuid.__len__() == 4: middle2_core_uv += str(uv) + "," middle2_core_cpufreq += str(freq) + "," if dynamic_power_coefficient_none == True: middle2_core_power += str(power) + "," elif index == 3: big_core_uv += str(uv) + "," big_core_cpufreq += str(freq) + "," if dynamic_power_coefficient_none == True: big_core_power += str(power) + "," index += 1 logging.info("index="), logging.info(index) #print(freqinfo) print(little_core_max_freq) print(little_core_min_freq) print(middle_core_max_freq) print(middle_core_min_freq) if cluser_first_cpuid.__len__() >= 4: print(middle2_core_max_freq) print(middle2_core_min_freq) print(big_core_max_freq) print(big_core_min_freq) print(little_core_mips_per_mhz) print(middle_core_mips_per_mhz) if cluser_first_cpuid.__len__() >= 4: print(middle2_core_mips_per_mhz) print(big_core_mips_per_mhz) print(little_core_dynamic_power_coefficient) print(middle_core_dynamic_power_coefficient) if cluser_first_cpuid.__len__() >= 4: print(middle2_core_dynamic_power_coefficient) print(big_core_dynamic_power_coefficient) print(little_core_uv[:-1]) print(middle_core_uv[:-1]) if cluser_first_cpuid.__len__() >= 4: print(middle2_core_uv[:-1]) print(big_core_uv[:-1]) print(little_core_cpufreq[:-1]) print(middle_core_cpufreq[:-1]) if cluser_first_cpuid.__len__() >= 4: print(middle2_core_cpufreq[:-1]) print(big_core_cpufreq[:-1]) if dynamic_power_coefficient_none == True: print(little_core_power) print(middle_core_power) if cluser_first_cpuid.__len__() >= 4: print(middle2_core_power) print(big_core_power) #@profile def run(self): logging.info("run") htmlFile = open(self.filename, 'r') content = htmlFile.read() htmlFile.close() parser = traceHTMLParser() parser.feed(content) parser.close() self.traces = parser.alldata del(content) del(parser) #gc.collect() logging.info("run1") if self.replaceTitle == True: logging.info("replace html title") trace_viewer_File = open('systrace_trace_viewer.html', 'r') traceviewertitle = trace_viewer_File.read() webcomponentsFile = open('webcomponents.min.js', 'r') webcomponents = webcomponentsFile.read() prefix_File = open('prefix.html', 'r') prefix = prefix_File.read() prefix2 = prefix.replace('{{SYSTRACE_TRACE_VIEWER_HTML}}', traceviewertitle) newStr = prefix2.replace('{{WEBCOMPONENTS_V0_POLYFILL_JS}}', webcomponents) del(webcomponents) del(prefix) newStr = newStr + self.titleEnd if self.traces.__len__() > 1 and self.traces[1][0:13] == "# tracer: nop": self.traces[0] = newStr webcomponentsFile.close() trace_viewer_File.close() prefix_File.close() self.importerall.register(ProcessDataImporter) self.importerall.register(FTraceImporter) self.importerall.register(TraceEventImporter) ftraceimporter = None for i in range(self.traces.__len__()): #print("ftraceimporter55"), #print(self.traces[i].__len__()), Importers = self.importerall.findImporter(self.traces[i]) #print(Importers) if DEBUG == True: logging.info("findImporter") logging.info(Importers) if Importers != None: importer = Importers(self.model, self.traces[i]) if importer.getname() == "FTraceImporter": ftraceimporter = importer self.model.ftraceimporter = ftraceimporter ftraceimporterindex = i importer.startImport() del(importer) if self.replaceTitle != True: del(self.traces) if self.model.ftraceimporter == None: logging.info("self.model.ftraceimporter="), logging.info(type(self.model.ftraceimporter).__name__) logging.info("Input file format error!") return None else: logging.info("self.model.ftraceimporter="), logging.info(type(self.model.ftraceimporter).__name__) self.model.autoCloseOpenSlices() self.model.createSubSlices() self.auditorall.register(AndroidAuditor) self.auditorall.register(VSyncAuditor) self.auditorall.register(CpuFreqAuditor) self.auditorall.register(CpuIdleAuditor) self.auditorall.register(CPULoadAuditor) self.auditorall.register(CPUPowerAuditor) self.auditorall.register(ThreadStateAuditor) self.auditorall.register(ThreadDependencyAuditor) if self.model.frameTest == True: self.auditorall.register(QueueBufferAuditor) self.auditorall.register(ChromeCpuLoadAuditor) self.auditorall.register(IrqAuditor) if self.model.blockEnable != None: self.auditorall.register(AndroidfsAuditor) self.auditorall.register(BlockAuditor) self.auditorall.register(MmcAuditor) self.auditorall.register(UfsAuditor) self.auditorall.register(UagAuditor) self.auditorall.register(SyscallAuditor) self.auditorall.register(StacktraceAuditor) self.auditorall.register(SliceAuditor) self.auditorall.register(FrameLoadAuditor) self.auditorall.register(GpuAuditor) self.auditorall.register(MtkpmqosAuditor) self.auditorall.register(MtkSchedAuditor) self.auditorall.register(VmScanAuditor) self.auditorall.register(MmstatAuditor) self.auditorall.register(KmemAuditor) self.auditorall.register(FileMapAuditor) self.auditorall.register(F2fsAuditor) self.auditorall.register(Mmap_lockAuditor) self.auditorall.register(SignalAuditor) self.auditorall.register(RegmapAuditor) self.auditorall.register(RwmmioAuditor) self.auditorall.register(OrmsAuditor) self.auditorall.register(PerflockAuditor) self.auditorall.register(UrccAuditor) self.auditorall.register(DcvsAuditor) self.auditorall.register(Dma_buf_alloc_Auditor) self.auditorall.register(ThermalAuditor) self.auditorall.register(MusbAuditor) self.auditorall.register(FpsgoTestAuditor) self.auditorall.register(FrameBoostAuditor) self.auditorall.register(UiFirstAuditor) self.auditorall.register(MaliAuditor) self.fenceprocess = FenceProcess(ftraceimporter) self.fenceprocess.start() Auditors = self.auditorall.getallauditor() for i in range(Auditors.__len__()): auditors = Auditors[i](self.model) if self.replaceTitle != True: logging.info(type(auditors).__name__) auditors.runAnnotate() if auditors.getAuditorName() == "AndroidAuditor": logging.info("AndroidAuditor") if self.replaceTitle == True: newHtmlfile = open(self.updatetsfile, 'w') if self.perfetto == True: if self.model.starttime == 0: logging.info("removeTime="), logging.info(ftraceimporter.cpusliceStartMax_perfetto - self.model.bounds.min) self.traces[ftraceimporterindex] = ftraceimporter.updaterTs(self.model.bounds.min, ftraceimporter.cpusliceStartMax_perfetto - self.model.bounds.min) else: self.traces[ftraceimporterindex] = ftraceimporter.updaterTs(self.model.bounds.min, self.model.starttime) else: self.traces[ftraceimporterindex] = ftraceimporter.updaterTs(self.model.bounds.min, self.model.starttime) for trace in self.traces: newHtmlfile.write(trace) newHtmlfile.close() del(self.traces) self.model.appframeTuple = auditors.getappframeTuple(self.fenceprocess) self.model.compserframeTuple = auditors.getComposerframeTuple(self.fenceprocess) self.model.appframeStatisticsTuple = auditors.getappframeStatisticsTuple() self.model.composerframeStatisticsTuple = auditors.getcomposerframeStatisticsTuple() if self.replaceTitle == True and self.perfetto == True: logging.info("update ts html file is %s" % self.updatetsfile) return "perfetto_replace" elif self.replaceTitle == True: logging.info("update ts html file is %s" %self.updatetsfile) return None else: return self.out() #@profile def main(argv): # print("argv="), # print(argv) #print(type(argv)) VersionNum = "V6.0" if type(argv) == type("str"): argv = argv.split(' ') argv_str = "" for ar in argv: argv_str += str(ar) + " " # print(argv_str) logging.basicConfig(level=logging.INFO, format='%(asctime)s.%(msecs)03d %(levelname)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') begin = datetime.datetime.now() usage = "Usage: analysismain.py systracefile [options]" parser = optparse.OptionParser(usage) parser.add_option("-d", "--device", type="int", dest="devicetype", help="8250:msm8250, 8350:msm8350, 8450:msm8450, 8650:msm8650, 6115:msm6115, 8635:msm8635" "6225:msm6225, 62252:msm6225pro, 6375:msm6375, 7325:msm7325, 7435:msm7435, 6450:msm6450," "7475:msm7475, 8475:msm8475, 84752:msm8475_lowfreq, 8550:msm8550, 7675:msm7675, 7635:msm7635," "6895:MT6895, 6877:MT6877, 6878:MT6878, 6853:MT6853, 6835:MT6835,68352:MT6835_24E," "6833:MT6833, 6769:MT6769, 6789:MT6789, 6886:MT6886" "6781:MT6781, 6785:MT6785, 6893:MT6893," "6891:MT6891,") parser.add_option("-t", "--threadpid", type="int", dest="watchingTid", help="watching thread tid") parser.add_option("-s", "--starttime", type="float", dest="starttime", help="start time(ms)") parser.add_option("-e", "--endtime", type="float", dest="endtime", help="end time(ms)") parser.add_option("-l", "--timeDuration", type="float", dest="time", help="duration(ms)") parser.add_option("-a", "--launching", type="int", dest="launching", help="1:launching time as starttime and endtime, " "2:launching time as starttime and endtime and launching app as watching thread") parser.add_option("-v", "--view", type="int", dest="view", help="1:uithread as watching thread," "2:renderthread as watchingtid," "3:surfaceflinger as watchingtid") parser.add_option("-g", "--tag", type="string", dest="tag", help="support tag") parser.add_option("-m", "--maxminfreq", type="int", dest="maxminfreq", help="systrace init freq, 1:maxfreq,2:minfreq") parser.add_option("-f", "--freqbounds", action="store_true", dest="freqbounds", help="the time when all cpu has cpufreq info as starttime") parser.add_option("-w", "--wakingEnable", action="store_true", dest="wakingEnable", help="use sched_waking to compute thread dependency") parser.add_option("-r", "--replaceTitle", action="store_true", dest="replaceTitle", help="replace systrace html title") parser.add_option("-k", "--threadload", type="string", dest="loadserialtid", help="thread load serial") parser.add_option("-i", "--runnableSerial", action="store_true", dest="runnableSerial", help="runnable Serial") parser.add_option("-q", "--irqload", action="store_true", dest="irqload", help="irq load") parser.add_option("-z", "--allThreadSlice", type="int", dest="allThreadSlice", help="all thread slice") parser.add_option("-p", "--frameTest", action="store_true", dest="frameTest", help="frame test") parser.add_option("-c", "--croppedVersion", action="store_true", dest="croppedVersion", help="Cropped version") parser.add_option("-n", "--runqEnable", action="store_true", dest="runqEnable", help="runqEnable") parser.add_option("-b", "--blockEnable", type="int", dest="blockEnable", help="blockEnable") parser.add_option("-u", "--mem", type="int", dest="memEnable", help="memEnable") parser.add_option("-j", "--inode_file", type="string", dest="inode_file", help="inode_file") parser.add_option("-x", "--power_info_get", type="int", dest="power_info_get", help="power_info_get") parser.add_option("-y", "--schedEnable", action="store_true", dest="schedEnable", help="schedEnable") parser.add_option("-o", "--onlycompate", action="store_true", dest="onlycompate", help="onlycompate") logging.info(VersionNum) options, args = parser.parse_args(argv[1:]) if options.starttime != None and options.time != None: options.endtime = options.starttime + options.time if options.endtime != None and options.time != None and options.starttime == None: options.starttime = options.endtime - options.time logging.info(options) if args.__len__() != 1: logging.info("param error!") sys.exit() device = 0 if options.devicetype == 8450: device = "msm8450" elif options.devicetype == 8250: device = "msm8250" elif options.devicetype == 8350: device = "msm8350" elif options.devicetype == 8550: device = "msm8550" elif options.devicetype == 8650: device = "msm8650" elif options.devicetype == 8635: device = "msm8635" elif options.devicetype == 7635: device = "msm7635" elif options.devicetype == 7675: device = "msm7675" elif options.devicetype == 7325: device = "msm7325" elif options.devicetype == 7435: device = "msm7435" elif options.devicetype == 6450: device = "msm6450" elif options.devicetype == 6115: device = "msm6115" elif options.devicetype == 6225: device = "msm6225" elif options.devicetype == 62252: device = "msm6225pro" elif options.devicetype == 6375: device = "msm6375" elif options.devicetype == 7475: device = "msm7475" elif options.devicetype == 8475: device = "msm8475" elif options.devicetype == 84752: device = "msm8475_lowfreq" elif options.devicetype == 6891: device = "MT6891" elif options.devicetype == 6893: device = "MT6893" elif options.devicetype == 6895: device = "MT6895" elif options.devicetype == 6769: device = "MT6769" elif options.devicetype == 6781: device = "MT6781" elif options.devicetype == 6785: device = "MT6785" elif options.devicetype == 6789: device = "MT6789" elif options.devicetype == 6833: device = "MT6833" elif options.devicetype == 6835: device = "MT6835" elif options.devicetype == 68352: device = "MT68352" elif options.devicetype == 6853: device = "MT6853" elif options.devicetype == 6877: device = "MT6877" elif options.devicetype == 6878: device = "MT6878" elif options.devicetype == 6886: device = "MT6886" elif options.devicetype == 9863: device = "SC9863" elif options.devicetype == 612: device = "SC612" else: if options.power_info_get == None: raise Exception("Device type is None!") if options.endtime != None and options.starttime != None and options.starttime >= options.endtime: raise Exception("Input param error, endtime need be bigger than starttime!") logging.info("is dir"), logging.info(os.path.isdir(args[0])) path = args[0] if os.path.isdir(path) == False: controller = Controller(args[0], device, options, argv_str) if controller.get_power_into_ret == True: return None ret = controller.run() end = datetime.datetime.now() logging.info("Elapsed Time=" + str(end - begin)) if ret == "perfetto_replace" and options.replaceTitle != True: if options.endtime != None and options.starttime != None and options.starttime >= options.endtime: raise Exception("Input param error, endtime need be bigger than starttime!") logging.info("new_test:"), logging.info(controller.updatetsfile) controller = Controller(controller.updatetsfile, device, options, argv_str) ret = controller.run() end = datetime.datetime.now() logging.info("Elapsed Time=" +str(end - begin)) if ret != None: logging.info("Test result in " +str(ret)) elif ret != None: logging.info("Test result in " + str(ret)) else: logging.info("ret = " + str(ret)) return ret else: if options.onlycompate != True: for dirpath, dirnames, filenames in os.walk(path): for filepath in filenames: ret = None #print (os.path.join(dirpath, filepath)) filepath_full = os.path.join(dirpath, filepath) if filepath_full.endswith(".html") or filepath_full.endswith(".perfetto-trace") or filepath_full.endswith(".perfetto"): logging.info(filepath_full) controller = Controller(filepath_full, device, options, argv_str) ret = controller.run() end = datetime.datetime.now() logging.info("Elapsed Time=" + str(end - begin)) if ret == "perfetto_replace" and options.replaceTitle != True: if options.endtime != None and options.starttime != None and options.starttime >= options.endtime: raise Exception("Input param error, endtime need be bigger than starttime!") logging.info("new_test:"), logging.info(controller.updatetsfile) controller = Controller(controller.updatetsfile, device, options, argv_str) ret = controller.run() end = datetime.datetime.now() logging.info("Elapsed Time=" +str(end - begin)) if ret != None: if options.croppedVersion != True: logging.info("Test result in " + str(ret)) elif ret != None: if options.croppedVersion != True: logging.info("Test result in " + str(ret)) else: logging.info("ret =" + str(ret)) #if os.path.isdir(path_out) == False: # os.mkdir(path_out) #if ret != None: # des = ret.replace(path, path + "_rtrace_out", 1) # logging.info("move from %s, to %s" %(ret, des)) # shutil.copy(ret, des) if path != None: compare(path) def compare(path): dfs = [] dfs_block_rq = [] dfs_cpuload = [] dfs_apps = [] dfs_launching = [] dfs_thread = [] dfs_process = [] filepath_list = [] for dirpath, dirnames, filenames in os.walk(path): for filepath in filenames: filepath_full = os.path.join(dirpath, filepath) if filepath_full.endswith(".xlsx") and not filepath_full.__contains__("~$") and "compare.xlsx" not in filepath_full: logging.info("filepath=" + str(filepath_full)) filepath_list.append(filepath_full) if filepath_list.__len__() > 0: filepath_list.sort(reverse=False) for filepath_full in filepath_list: try: df = pd.read_excel(filepath_full, sheet_name='D_IO', header=0) df_modify = copy.copy(df.head(1)) df_new = copy.copy(df_modify.iloc[:, [1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]]) df_new.rename(columns={'Tid': 'traceFile'}, inplace=True) df_new.iloc[0, 0] = filepath_full dfs.append(df_new) except: logging.info(filepath_full + " D_IO sheet not exit!") try: df_block_rq = pd.read_excel(filepath_full, sheet_name='block_rq', header=0) df_block_rq.iloc[0, 0] = filepath_full dfs_block_rq.append(df_block_rq) except: logging.info(filepath_full + " block_rq sheet not exit!") try: df_cpuload = pd.read_excel(filepath_full, sheet_name='cpuload', header=0) df_cpuload.iloc[0, 0] = filepath_full dfs_cpuload.append(df_cpuload) except: logging.info(filepath_full + " load sheet not exit!") try: df_apps = pd.read_excel(filepath_full, sheet_name='apps', header=0) df_apps.iloc[0, 0] = filepath_full dfs_apps.append(df_apps) except: logging.info(filepath_full + " apps sheet not exit!") try: df_launching = pd.read_excel(filepath_full, sheet_name='launching', header=0) df_launching.iloc[0, 0] = filepath_full dfs_launching.append(df_launching) except: logging.info(filepath_full + " launching sheet not exit!") try: df_thread = pd.read_excel(filepath_full, sheet_name='thread', header=0) df_thread = copy.copy(df_thread.head(10)) df_thread.iloc[0, 0] = filepath_full dfs_thread.append(df_thread) except: logging.info(filepath_full + " thread sheet not exit!") try: df_process = pd.read_excel(filepath_full, sheet_name='process', header=0) df_process = copy.copy(df_process.head(10)) df_process.iloc[0, 0] = filepath_full dfs_process.append(df_process) except: logging.info(filepath_full + " process sheet not exit!") if dfs.__len__() > 0: write = pd.ExcelWriter(path + "/compare.xlsx") wb = write.book #pd_look = pd.DataFrame(df, columns=df.columns) new_df = pd.concat(dfs, axis=0) pd_look = pd.DataFrame(new_df, columns=new_df.columns) pd_look.to_excel(write, sheet_name='D_IO') ExcelStyle.excel_length_process(pd_look, write, "D_IO") ExcelStyle.style_title_color_except(wb, 1, 1, "6496C8") if dfs_block_rq.__len__() > 0: new_df_block_rq = pd.concat(dfs_block_rq, axis=0) pd_look = pd.DataFrame(new_df_block_rq, columns=new_df_block_rq.columns) pd_look.to_excel(write, sheet_name='block_rq') ExcelStyle.excel_length_process(pd_look, write, "block_rq") ExcelStyle.style_title_color_except(wb, 1, 1, "6496C8") if dfs_cpuload.__len__() > 0: new_df_cpuload = pd.concat(dfs_cpuload, axis=0) pd_look = pd.DataFrame(new_df_cpuload, columns=new_df_cpuload.columns) pd_look.to_excel(write, sheet_name='cpuload') ExcelStyle.excel_length_process(pd_look, write, "cpuload") ExcelStyle.style_title_color_except(wb, 1, 1, "6496C8") if dfs_apps.__len__() > 0: new_df_apps = pd.concat(dfs_apps, axis=0) pd_look = pd.DataFrame(new_df_apps, columns=new_df_apps.columns) pd_look.to_excel(write, sheet_name='apps') ExcelStyle.excel_length_process(pd_look, write, "apps") ExcelStyle.style_title_color_except(wb, 1, 1, "6496C8") if dfs_launching.__len__() > 0: new_df_launching = pd.concat(dfs_launching, axis=0) pd_look = pd.DataFrame(new_df_launching, columns=new_df_launching.columns) pd_look.to_excel(write, sheet_name='launching') ExcelStyle.excel_length_process(pd_look, write, "launching") ExcelStyle.style_title_color_except(wb, 1, 1, "6496C8") if dfs_thread.__len__() > 0: new_df_thread = pd.concat(dfs_thread, axis=0) pd_look = pd.DataFrame(new_df_thread, columns=new_df_thread.columns) pd_look.to_excel(write, sheet_name='thread') ExcelStyle.excel_length_process(pd_look, write, "thread") ExcelStyle.style_title_color_except(wb, 1, 1, "6496C8") if dfs_process.__len__() > 0: new_df_process = pd.concat(dfs_process, axis=0) pd_look = pd.DataFrame(new_df_process, columns=new_df_process.columns) pd_look.to_excel(write, sheet_name='process') ExcelStyle.excel_length_process(pd_look, write, "process") ExcelStyle.style_title_color_except(wb, 1, 1, "6496C8") write.save() write.close() logging.info("output file is =" + path + "/compare.xlsx") if __name__ == "__main__": main(sys.argv)
最新发布
12-02
musb 中文翻译和英文文档.可以通过会话请求协议(SRP)发起USB流量,而双角色设备同时支持SRP和主机协商协议(HNP),并且可以根据需要担任主机或外设的角色。MUSBMHDRC还支持拆分事务,这反过来允许它支持使用带有USB 2.0集线器的全速度或低速设备。核心还包括支持在不使用时关闭便携式设备。 除了端点0之外,MUSBMHDRC是用户可配置的,可支持最多15个‘传输’端点和/或最多15个‘接收’端点。(对于IN事务和OUT事务使用这些端点取决于MUSBMHDRC是用作外设还是用作主机。当用作外设时,IN事务通过TX端点处理,OUT事务通过Rx端点处理。当用作主机时,IN事务通过Rx端点处理,OUT事务通过TX端点处理。)这些附加端点可以在软件中单独配置,以处理批量传输(这也允许它们处理中断传输)、同步传输或控制传输。此外,还可以动态地将端点分配给不同的目标设备函数——最大限度地同时支持设备的数量。 每个端点都需要一个FIFO与之关联。MUSBMHDRC有一个RAM接口,用于连接到用于所有端点FIFOs的同步单端口RAM的单个块。(RAM块本身需要由用户添加。) 端点0的FIFO需要为64字节深,并缓冲1个数据包。RAM接口可以根据其他端点FIFOs进行配置,它的大小可以从8到8192字节,可以缓冲1个或2个数据包。单独的FIFOs可以与每个端点相关联:或者,具有相同端点编号的TX端点和Rx端点可以配置为使用相同的FIFO,例如,如果它们永远不能同时活动,可以减少所需RAM块的大小。 MUSBMHDRC提供了一个32位同步CPU接口,设计用于连接AMBA AHB bus1。接口支持使用AHB总线运行在一个大范围的总线速度。AHB总线上的多层操作也被支持。通过添加合适的包装器/桥接器,MUSBMHDRC还可以很容易地连接到一系列其他标准总线。 还支持对端点FIFOs的DMA访问。 MUSBMHDRC提供了一个UTMI+ 3级兼容接口,用于连接到一个合适的USB高/全速收发器。包含了一个可选的ULPI链接包装器(在musbhdrc /docs目录中包含的musbhdrc_ulpi_an.pdf文档中描述),用于连接到与ULPI兼容的物理。另一种接口也提供,允许使用USB 1.1与核心全速PHY,但仅为全速和低速事务。(此接口见8.1节)。 MUSBMHDRC提供发送和接收USB数据包所需的所有编码、解码、检查和重新请求——仅当端点数据已被成功传输时才中断CPU。 当充当主机时,MUSBMHDRC另外维护一个帧计数器,并自动调度SOF、同步、中断和批量传输。它还包括对在点对点通信中使用的会话请求和主机协商协议的支持,其细节在USB 2.0规范的USB on - go补充中给出。MUSBMHDRC提供了一系列的测试模式——主要是USB 2.0规范中描述的高速运行的四种测试模式。它还包括选项,允许它被迫进入全速模式,高速模式或主机模式。最后一个可能在帮助调试硬件PHY问题时有用。 提供了图形用户界面脚本,用于根据用户的需求配置核心。要使用的脚本取决于所选的CPU接口。请注意:在撰写本文时,内核仅在Verilog中可用。 本规范应与USB运行规范一起阅读,该规范还提供了电源要求、电压水平、连接器等细节。.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值