dmatest.c

AXI DMA总结、内核axidmatest.c测试程序分析、SG mode AXI DMA 概述: XILINX提供的AXI DMA支持Scatter/Gather mode和Direct Register mode 数据位宽支持32,64,128,256,512,1024bits,stream数据位宽支持8,16,32,64,128,256,512,1024bits,这里数据位宽表示DDR到上图中DataMover的数据位宽,stream数据位宽表示的DataMover到设备的数据位宽,表示一次可以传输多少位的数据。最高支持64bit地址。 AXI DMA在Scatte 阅读详情

这个代码位于/driver/dma/dmatest.c, 可以编译成模块 dmatest.ko

1. late_initcall(dmatest_init) ---这个init还是第一次见。

static int __init dmatest_init(void)
{
	dma_cap_mask_t mask;
	struct dma_chan *chan;
	int err = 0;

	dma_cap_zero(mask);        //清除mask
	dma_cap_set(DMA_MEMCPY, mask);                  //设置 DMA_MEMCPY 掩码
	for (;;) {
		chan = dma_request_channel(mask, filter, NULL);   //请求获得 dma channel
		if (chan) {
			err = dmatest_add_channel(chan);               //添加 dma test channel
			if (err) {
				dma_release_channel(chan);               //释放 dma channel
				break; /* add_channel failed, punt */
			}
		} else
			break; /* no more channels available */
		if (max_channels && nr_channels >= max_channels)               //限定最大 channel数
			break; /* we have all we need */
	}

	return err;
}
/* when compiled-in wait for drivers to load first */
late_initcall(dmatest_init);

dma_cap_mask_t

/**
 * dma_cap_mask_t - capabilities bitmap modeled after cpumask_t.
 * See linux/cpumask.h
 */
typedef struct { DECLARE_BITMAP(bits, DMA_TX_TYPE_END); } dma_cap_mask_t;
dma_cap_zero

#define dma_cap_zero(mask) __dma_cap_zero(&(mask))
static inline void __dma_cap_zero(dma_cap_mask_t *dstp)
{
	bitmap_zero(dstp->bits, DMA_TX_TYPE_END);
}
dma_cap_set

#define dma_cap_set(tx, mask) __dma_cap_set((tx), &(mask))
static inline void
__dma_cap_set(enum dma_transaction_type tx_type, dma_cap_mask_t *dstp)
{
	set_bit(tx_type, dstp->bits);
}
2. dma_request_channel() --- 请求获取dma channel

#define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y)
/**
 * dma_request_channel - try to allocate an exclusive channel
 * @mask: capabilities that the channel must satisfy
 * @fn: optional callback to disposition available channels
 * @fn_param: opaque parameter to pass to dma_filter_fn
 */
struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param)
{
	struct dma_device *device, *_d;
	struct dma_chan *chan = NULL;
	int err;

	/* Find a channel */
	mutex_lock(&dma_list_mutex);
	list_for_each_entry_safe(device, _d, &dma_device_list, global_node) {
		chan = private_candidate(mask, device, fn, fn_param);
		if (chan) {
			/* Found a suitable channel, try to grab, prep, and
			 * return it.  We first set DMA_PRIVATE to disable
			 * balance_ref_count as this channel will not be
			 * published in the general-purpose allocator
			 */
			dma_cap_set(DMA_PRIVATE, device->cap_mask);
			device->privatecnt++;
			err = dma_chan_get(chan);

			if (err == -ENODEV) {
				pr_debug("%s: %s module removed\n", __func__,
					 dma_chan_name(chan));
				list_del_rcu(&device->global_node);
			} else if (err)
				pr_err("dmaengine: failed to get %s: (%d)\n",
				       dma_chan_name(chan), err);
			else
				break;
			if (--device->privatecnt == 0)
				dma_cap_clear(DMA_PRIVATE, device->cap_mask);
			chan->private = NULL;
			chan = NULL;
		}
	}
	mutex_unlock(&dma_list_mutex);

	pr_debug("%s: %s (%s)\n", __func__, chan ? "success" : "fail",
		 chan ? dma_chan_name(chan) : NULL);

	return chan;
}
EXPORT_SYMBOL_GPL(__dma_request_channel);
3. dmatest_add_channel ---添加 dma test channel

static int dmatest_add_channel(struct dma_chan *chan)
{
	struct dmatest_chan	*dtc;
	struct dma_device	*dma_dev = chan->device;
	unsigned int		thread_count = 0;
	unsigned int		cnt;

	dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
	if (!dtc) {
		pr_warning("dmatest: No memory for %s\n", dma_chan_name(chan));
		return -ENOMEM;
	}

	dtc->chan = chan;
	INIT_LIST_HEAD(&dtc->threads);

	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
		cnt = dmatest_add_threads(dtc, DMA_MEMCPY);
		thread_count += cnt > 0 ? cnt : 0;
	}
	if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
		cnt = dmatest_add_threads(dtc, DMA_XOR);
		thread_count += cnt > 0 ? cnt : 0;
	}
	if (dma_has_cap(DMA_PQ, dma_dev->cap_mask)) {
		cnt = dmatest_add_threads(dtc, DMA_PQ);
		thread_count += cnt > 0 ?: 0;
	}

	pr_info("dmatest: Started %u threads using %s\n",
		thread_count, dma_chan_name(chan));

	list_add_tail(&dtc->node, &dmatest_channels);
	nr_channels++;

	return 0;
}
4. dmatest_add_threads

static int dmatest_add_threads(struct dmatest_chan *dtc, enum dma_transaction_type type)
{
	struct dmatest_thread *thread;
	struct dma_chan *chan = dtc->chan;
	char *op;
	unsigned int i;

	if (type == DMA_MEMCPY)
		op = "copy";
	else if (type == DMA_XOR)
		op = "xor";
	else if (type == DMA_PQ)
		op = "pq";
	else
		return -EINVAL;

	for (i = 0; i < threads_per_chan; i++) {
		thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL);
		if (!thread) {
			pr_warning("dmatest: No memory for %s-%s%u\n",
				   dma_chan_name(chan), op, i);

			break;
		}
		thread->chan = dtc->chan;
		thread->type = type;
		smp_wmb();
		thread->task = kthread_run(dmatest_func, thread, "%s-%s%u",           //创建新线程,运行dmatest_func 程序。
				dma_chan_name(chan), op, i);
		if (IS_ERR(thread->task)) {
			pr_warning("dmatest: Failed to run thread %s-%s%u\n",
					dma_chan_name(chan), op, i);
			kfree(thread);
			break;
		}

		/* srcbuf and dstbuf are allocated by the thread itself */

		list_add_tail(&thread->node, &dtc->threads);
	}

	return i;
}
5. dmatest_func 这是新创建进程所运行的程序
/*
 * This function repeatedly tests DMA transfers of various lengths and
 * offsets for a given operation type until it is told to exit by
 * kthread_stop(). There may be multiple threads running this function
 * in parallel for a single channel, and there may be multiple channels
 * being tested in parallel.
 *
 * Before each test, the source and destination buffer is initialized
 * with a known pattern. This pattern is different depending on
 * whether it's in an area which is supposed to be copied or
 * overwritten, and different in the source and destination buffers.
 * So if the DMA engine doesn't copy exactly what we tell it to copy,
 * we'll notice.
 */
static int dmatest_func(void *data)
{
	struct dmatest_thread	*thread = data;
	struct dma_chan		*chan;
	const char		*thread_name;
	unsigned int		src_off, dst_off, len;
	unsigned int		error_count;
	unsigned int		failed_tests = 0;
	unsigned int		total_tests = 0;
	dma_cookie_t		cookie;
	enum dma_status		status;
	enum dma_ctrl_flags 	flags;
	u8			pq_coefs[pq_sources + 1];
	int			ret;
	int			src_cnt;
	int			dst_cnt;
	int			i;

	thread_name = current->comm;

	ret = -ENOMEM;

	smp_rmb();
	chan = thread->chan;
	if (thread->type == DMA_MEMCPY)
		src_cnt = dst_cnt = 1;
	else if (thread->type == DMA_XOR) {
		src_cnt = xor_sources | 1; /* force odd to ensure dst = src */
		dst_cnt = 1;
	} else if (thread->type == DMA_PQ) {
		src_cnt = pq_sources | 1; /* force odd to ensure dst = src */
		dst_cnt = 2;
		for (i = 0; i < src_cnt; i++)
			pq_coefs[i] = 1;
	} else
		goto err_srcs;

	thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL);
	if (!thread->srcs)
		goto err_srcs;
	for (i = 0; i < src_cnt; i++) {
		thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL);
		if (!thread->srcs[i])
			goto err_srcbuf;
	}
	thread->srcs[i] = NULL;

	thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL);
	if (!thread->dsts)
		goto err_dsts;
	for (i = 0; i < dst_cnt; i++) {
		thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL);
		if (!thread->dsts[i])
			goto err_dstbuf;
	}
	thread->dsts[i] = NULL;

	set_user_nice(current, 10);

	flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT;

	while (!kthread_should_stop()
	       && !(iterations && total_tests >= iterations)) {
		struct dma_device *dev = chan->device;
		struct dma_async_tx_descriptor *tx = NULL;
		dma_addr_t dma_srcs[src_cnt];
		dma_addr_t dma_dsts[dst_cnt];
		struct completion cmp;
		unsigned long tmo = msecs_to_jiffies(3000);
		u8 align = 0;

		total_tests++;

		/* honor alignment restrictions */
		if (thread->type == DMA_MEMCPY)
			align = dev->copy_align;
		else if (thread->type == DMA_XOR)
			align = dev->xor_align;
		else if (thread->type == DMA_PQ)
			align = dev->pq_align;

		if (1 << align > test_buf_size) {
			pr_err("%u-byte buffer too small for %d-byte alignment\n",
			       test_buf_size, 1 << align);
			break;
		}

		len = dmatest_random() % test_buf_size + 1;
		len = (len >> align) << align;
		if (!len)
			len = 1 << align;
		src_off = dmatest_random() % (test_buf_size - len + 1);
		dst_off = dmatest_random() % (test_buf_size - len + 1);

		src_off = (src_off >> align) << align;
		dst_off = (dst_off >> align) << align;

		dmatest_init_srcs(thread->srcs, src_off, len);
		dmatest_init_dsts(thread->dsts, dst_off, len);

		for (i = 0; i < src_cnt; i++) {
			u8 *buf = thread->srcs[i] + src_off;

			dma_srcs[i] = dma_map_single(dev->dev, buf, len,
						     DMA_TO_DEVICE);
		}
		/* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
		for (i = 0; i < dst_cnt; i++) {
			dma_dsts[i] = dma_map_single(dev->dev, thread->dsts[i],
						     test_buf_size,
						     DMA_BIDIRECTIONAL);
		}


		if (thread->type == DMA_MEMCPY)
			tx = dev->device_prep_dma_memcpy(chan,
							 dma_dsts[0] + dst_off,
							 dma_srcs[0], len,
							 flags);
		else if (thread->type == DMA_XOR)
			tx = dev->device_prep_dma_xor(chan,
						      dma_dsts[0] + dst_off,
						      dma_srcs, src_cnt,
						      len, flags);
		else if (thread->type == DMA_PQ) {
			dma_addr_t dma_pq[dst_cnt];

			for (i = 0; i < dst_cnt; i++)
				dma_pq[i] = dma_dsts[i] + dst_off;
			tx = dev->device_prep_dma_pq(chan, dma_pq, dma_srcs,
						     src_cnt, pq_coefs,
						     len, flags);
		}

		if (!tx) {
			for (i = 0; i < src_cnt; i++)
				dma_unmap_single(dev->dev, dma_srcs[i], len,
						 DMA_TO_DEVICE);
			for (i = 0; i < dst_cnt; i++)
				dma_unmap_single(dev->dev, dma_dsts[i],
						 test_buf_size,
						 DMA_BIDIRECTIONAL);
			pr_warning("%s: #%u: prep error with src_off=0x%x "
					"dst_off=0x%x len=0x%x\n",
					thread_name, total_tests - 1,
					src_off, dst_off, len);
			msleep(100);
			failed_tests++;
			continue;
		}

		init_completion(&cmp);
		tx->callback = dmatest_callback;
		tx->callback_param = &cmp;
		cookie = tx->tx_submit(tx);

		if (dma_submit_error(cookie)) {
			pr_warning("%s: #%u: submit error %d with src_off=0x%x "
					"dst_off=0x%x len=0x%x\n",
					thread_name, total_tests - 1, cookie,
					src_off, dst_off, len);
			msleep(100);
			failed_tests++;
			continue;
		}
		dma_async_issue_pending(chan);

		tmo = wait_for_completion_timeout(&cmp, tmo);
		status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);

		if (tmo == 0) {
			pr_warning("%s: #%u: test timed out\n",
				   thread_name, total_tests - 1);
			failed_tests++;
			continue;
		} else if (status != DMA_SUCCESS) {
			pr_warning("%s: #%u: got completion callback,"
				   " but status is \'%s\'\n",
				   thread_name, total_tests - 1,
				   status == DMA_ERROR ? "error" : "in progress");
			failed_tests++;
			continue;
		}

		/* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
		for (i = 0; i < dst_cnt; i++)
			dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size,
					 DMA_BIDIRECTIONAL);

		error_count = 0;

		pr_debug("%s: verifying source buffer...\n", thread_name);
		error_count += dmatest_verify(thread->srcs, 0, src_off,
				0, PATTERN_SRC, true);
		error_count += dmatest_verify(thread->srcs, src_off,
				src_off + len, src_off,
				PATTERN_SRC | PATTERN_COPY, true);
		error_count += dmatest_verify(thread->srcs, src_off + len,
				test_buf_size, src_off + len,
				PATTERN_SRC, true);

		pr_debug("%s: verifying dest buffer...\n",
				thread->task->comm);
		error_count += dmatest_verify(thread->dsts, 0, dst_off,
				0, PATTERN_DST, false);
		error_count += dmatest_verify(thread->dsts, dst_off,
				dst_off + len, src_off,
				PATTERN_SRC | PATTERN_COPY, false);
		error_count += dmatest_verify(thread->dsts, dst_off + len,
				test_buf_size, dst_off + len,
				PATTERN_DST, false);

		if (error_count) {
			pr_warning("%s: #%u: %u errors with "
				"src_off=0x%x dst_off=0x%x len=0x%x\n",
				thread_name, total_tests - 1, error_count,
				src_off, dst_off, len);
			failed_tests++;
		} else {
			pr_debug("%s: #%u: No errors with "
				"src_off=0x%x dst_off=0x%x len=0x%x\n",
				thread_name, total_tests - 1,
				src_off, dst_off, len);
		}
	}

	ret = 0;
	for (i = 0; thread->dsts[i]; i++)
		kfree(thread->dsts[i]);
err_dstbuf:
	kfree(thread->dsts);
err_dsts:
	for (i = 0; thread->srcs[i]; i++)
		kfree(thread->srcs[i]);
err_srcbuf:
	kfree(thread->srcs);
err_srcs:
	pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
			thread_name, total_tests, failed_tests, ret);

	if (iterations > 0)
		while (!kthread_should_stop()) {
			DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wait_dmatest_exit);
			interruptible_sleep_on(&wait_dmatest_exit);
		}

	return ret;
}
6. dmatest_exit():

static void __exit dmatest_exit(void)
{
	struct dmatest_chan *dtc, *_dtc;
	struct dma_chan *chan;

	list_for_each_entry_safe(dtc, _dtc, &dmatest_channels, node) {
		list_del(&dtc->node);
		chan = dtc->chan;
		dmatest_cleanup_channel(dtc);
		pr_debug("dmatest: dropped channel %s\n",
			 dma_chan_name(chan));
		dma_release_channel(chan);
	}
}
module_exit(dmatest_exit);
dmatest_cleanup_channel

static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
{
	struct dmatest_thread	*thread;
	struct dmatest_thread	*_thread;
	int			ret;

	list_for_each_entry_safe(thread, _thread, &dtc->threads, node) {
		ret = kthread_stop(thread->task);
		pr_debug("dmatest: thread %s exited with status %d\n",
				thread->task->comm, ret);
		list_del(&thread->node);
		kfree(thread);
	}
	kfree(dtc);
}

Linux内核DMA子系统 - DMA测试实例1 【DMA机理】Linux内核DMA子系统 - DMA测试实例1。 阅读详情

相关推荐

ZedBoard的AXI DMA收发独立双线程linux应用程序

ZedBoard的AXI DMA收发独立双线程linux应用程序!有别于之前官方或者其它提供的单次发单次收。该代码包含速度测试,实测传输速率可以达到274MB/s。

Linux驱动开发基础之DMA

本文对于DMA在Linux驱动中的相关运用进行了简单的介绍,并且也提到了一些DMA的相关概念以函数。对于DMA的传输过程进行了详细的介绍,并通过相关的代码进行了实现。下文所使用的硬件设备是基于ARM Cortex-A9处理器的Exynos-tiny4412开发板所实现的,所使用的内核版本为Linux-3.5提示:以下是本篇文章正文内容,下面案例可供参考。

ZZZZZ1113的博客 4866

SDI-12协议与STM32 进行uart通信

其中DIR_OUT_SDI是一个IO引脚,控制UART_TX_SDI是否使能,U10是三态门IC,即拉低DIR_OUT_SDI使能stm32输出,拉高DIR_OUT_SDI失能输出,串口配置8位数据位,偶校验,1位停止位,1200波特率。示波器测试得到传感器的应答信号如下:第一个是唤醒信号,拉高电平13毫秒,之后保持20毫秒低电平,第二个数据帧是激活信号,即ascii码: "0!",第三个是传感器的应答信号:"0\r\n"

weixin_42186805的博客 4401

Linux内核4.14版本——DMA Engine框架分析(4)_dmatest.c分析

dmatest.c分析

yangguoyu8023的博客 1435

AUTOSAR R20-11标准下载!

这是公众号的第2篇推文,粉丝数49 Document Search Classic Platform Adaptive Platform Foundation 文档截图 以为会在明天的发布会之后才上线,没想到官网现在就悄悄放出来了。 中国由于网络问题,下载速度比较慢或者会中断。 “阅读原文”提供多种下载方式,可以在线浏览,可以集中下载也可单个文档下载。 如有增减我也会及时在公众号里通知大家,不过我觉得不会变动了。 整理不宜,好东西要分...

Adaptive_AUTOSAR的博客 1890

从ABS到EBS再到AEBS:商用车制动安全系统的“三代同堂”与技术演进史

本文详细解析了商用车制动安全系统从ABS到EBS再到AEBS的技术演进历程。通过对比三代系统的性能差异和应用效果,揭示了电子控制单元(ECU)在提升制动精度和安全性的核心作用,并展望了智能制动技术的未来发展趋势。

weixin_42651748的博客 329

Zynq Axidma linux下驱动axidmatest.c 驱动分析

本文的部分内容可能来源于网络,该内容归原作者所有,如果侵犯到您的权益,请及时通知我,我将立即删除,原创内容copyleft归tingkman@163.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。欢迎加入zynq-arm-linux提高交流群:788265722。

✨小太阳丶微凉✨的博客 1342

电子货架标签应用浅析(ESL)

​【 关注与分享,是对原创最大的鼓励 】 年底了,会断续介绍几个主要的BLE的应用及市场情况,这篇文章介绍的是电子货架标签, ESL (Electronic Shelf Label)。 文章将从应用简介,市场规模,产业链,头部玩家及系统框架进行介绍。只对技术感兴趣的可以直接拉到底。 ESL简介 ESL,是一种显示产品,其主要是替代传统的纸质标签,应用于大型商超,...

iotthings的博客 4691

dmatest.c 内核模块参数详解:10个 sysfs 接口与性能调优指南

本文详细解析了Linux内核中dmatest模块的10个关键sysfs接口参数,包括iterations、timeout、buf_size等,并提供了性能调优的实战指南。通过合理配置这些参数,开发者可以优化DMA传输性能,提升吞吐量(IOPS)和降低延迟,适用于视频处理、音频处理等多种场景。

weixin_34174322的博客 432

手机VPN的连接方法分享

6、返回到VPN页面,可以看到刚刚新添加的VPN,点击开启VPN后面的开关。5、在打开的添加VPN的页面中输入VPN的信息后点击右上角的“保存”按钮。7、待VPN开关开启后,可以看到添加的VPN正在连接的提示信息了。2、在打开的小米手机设置页面中点击“更多连接方式”的菜单项。3、然后在打开的更多连接方式页面中点击VPN的菜单项。4、在打开的VPN设置页面中点击“添加VPN”的按钮。1、首先在手机屏幕左右的滑动,找到手机的设置图标。

惠惠软件 3万+

构建基于知识图谱的金融风险关联网络可视化系统

知识图谱是一种用于表示实体及其关系的图形结构,能够将分散的数据组织成易于理解和查询的形式。语义性:通过实体和关系的描述,赋予数据语义。结构化:以图的形式组织数据,便于计算机处理。动态性:支持实时更新,能够反映数据的最新状态。风险关联网络是指将金融风险事件、实体及其关系以图形形式表示的网络。关联性:能够展示风险事件之间的相互影响。动态性:能够实时反映风险变化。可视化:便于金融从业者直观理解风险分布。可视化系统是指通过图形界面展示数据或信息的系统。提供直观的数据显示。帮助用户快速理解复杂数据。

AI天才研究院 1057

dmatest.c 源码解析:3个关键数据结构与 DMA 测试线程生命周期

本文深入解析了Linux内核中dmatest.c模块的3个关键数据结构(dmatest_params、dmatest_info、dmatest_thread)及其交互关系,详细剖析了DMA测试线程的完整生命周期。通过分析核心代码实现,揭示了DMA测试的参数配置、线程管理、数据传输验证等关键机制,为开发者理解Linux DMA子系统提供了实践参考。

weixin_30918633的博客 427

dolphinscheduler服务注册中心源码解析(一)服务注册与发现整体设计

下一篇文章我们开始讲解dolphinscheduler基于Zookeeper实现注册中心的源码解析。

最爱嫣夜来 375

Linux 内核 dmatest.c 模块实战:配置 3 个参数实现 DMA 通道功能与性能验证

本文详细介绍了Linux内核dmatest模块的实战应用,通过配置3个关键参数实现DMA通道功能与性能验证。文章涵盖模块加载、参数配置、测试结果分析及性能优化建议,帮助开发者高效验证DMA控制器功能,提升系统数据传输效率。

weixin_42530458的博客 330

手把手教你学Simulink——基于经典滤波器设计的场景:低通滤波器(LPF)的设计与频率响应仿真

滤波器是信号处理领域中非常重要的组件,用于去除不需要的频率成分或者提取有用的频率信息。低通滤波器(Low-Pass Filter, LPF)允许低于某个特定截止频率的信号通过,同时衰减高于该截止频率的信号。在本教程中,我们将学习如何使用设计一个简单的模拟低通滤波器,并对其频率响应进行仿真分析。本文介绍了如何使用设计一个简单的模拟低通滤波器,并通过仿真展示了其应用效果。通过这样的实践,您不仅能够加深对滤波器工作原理的理解,还能掌握利用Simulink进行滤波器设计与仿真的基本技能。

MHD0815的博客 5720

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Linux DMA Engine framework(5)-DMATest

使用dmatest modele 1.How to build the test module   The menuconfig contains an option that could be found by following path: Device Drivers -> DMA Engine support -> DMA Test client   In the co...

weixin_41028621的博客 1111

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

dmatest 代码分析

dmatest 代码分析 dmatest是内核的一个测试dma模块的代码,代码位置位于内核的./drivers/dma/dmatest.c,关于dmatest模块的使用可以参考内核提供的文档./Documentation/dmaengine/dmatest.txt,这里只简单地介绍一下。 编译加载模块 配置支持位置: Device Drivers -> DMA Engine support -> DMA Test client 或者直接修改配置文件CONFIG_DMATEST=m,编译成模块。

weixin_38878510的博客 5099

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

dmaengine,dmatest, DW_DMAC driver

linux下有现成的dw_dmac驱动,但是需要自己创建设备文件,分配IRQ和mem resources, 所以需要对配置进行测试 linux dma engine framework提供了dmatest.c测试文件,用于测试,但是怎么使用这个文件呢? 首先一定要将该文件编译为ko文件,在测试时,insmod+参数 就可以启动这个函数  module 中使用参数主要有几个函数 : modu

yazhouren的专栏 5438

Linux DMA驱动框架

DMA(Direct Memory Access),直接内存访问,这里的直接是和需要CPU参与的内存访问相对的概念,在我们写程序的时候经常会遇到这样的场景: 将数据从一片内存搬运到另一片内存 持续不断从IO设备读取数据到内存 将大量数据不断写入IO设备 这样的活儿CPU当然能干,不过其他的事情就只能推后再处理,毕竟CPU最擅长的还是串行的逻辑,如果能有一个外设,我们告诉它数据存储的地址和长度,再告诉它从哪里搬运到哪里,它就能任劳任怨的去干,最好干完了能再通知CPU一声,那岂..

gnr_123的专栏 1150

DMA的使用(基于树莓派5)

本文基于树莓派5(BCM2712)平台进行DMA学习实验。实验环境为Debian 13 trixie系统,内核版本6.12.75+rpt-rpi-2712。实验分为两部分:1)验证内核dmatest模块的DMA memcpy功能;2)自定义DMA内核模块与CPU memcpy性能对比。实验结果表明,该平台的DMA引擎吞吐约为30MB/s,远低于CPU的13GB/s,但DMA优势在于解放CPU资源。通过分析发现,树莓派5的legacy DMA控制器(dma0/dma1)硬件性能有限,而PCIe侧的dma2(D

fanged的专栏 1487

NXP Layerscape平台Linux内核定制与eDMA/CAAM DMA驱动开发实战

在嵌入式Linux开发中,内核定制与驱动开发是连接硬件与操作系统的核心技术。其原理在于通过配置系统(如Kbuild)和设备树(Device Tree)描述,将特定硬件功能编译进内核或模块。这项技术的核心价值在于能够针对特定硬件平台(如NXP Layerscape系列ARM处理器)进行深度优化,实现性能提升、功耗降低与功能裁剪。在应用场景上,它广泛用于工业控制、网络设备、汽车电子等领域,需要高效处理外设数据搬运与硬件加密加速。本文聚焦于**eDMA(增强型直接内存访问)** 与**CAAM DMA(加密加速模

chiyingliao3565的博客 325

dma client test

在driver/dma/dmatest.c 可以测试dma client. config DMATEST     tristate "DMA Test client"     depends on DMA_ENGINE     select DMA_ENGINE_RAID     help       Simple DMA test client. Say N unless you'r

jason的笔记 3849

NXP Layerscape Linux内核构建与驱动开发实战指南

Linux内核是嵌入式系统的核心,它管理硬件资源并提供系统服务。其工作原理是通过可加载模块和设备树(Device Tree)来支持多样化的硬件平台。掌握内核配置与构建技术,对于优化系统性能、裁剪功能以及开发硬件驱动至关重要,能显著提升嵌入式产品的稳定性和效率。在基于Arm架构的嵌入式开发中,特别是使用NXP Layerscape系列处理器时,开发者常需面对内核源码管理、交叉编译以及关键驱动(如eDMA和CAAM DMA)的集成与调试。本文以NXP Layerscape Linux Distribution

cri5768的博客 410

Linux链表操作

在研究linux内核自带的dmatest.c驱动程序过程中发现有部分的链接操作,非常迷惑,故在此记录下来一些查阅资料后的心得体会。 0 内核链表的特点        普通的链表操作,通常包含数据域和指针域2个内容 如下所示。 typedef struct node {      ElemType data;       //数据域      struct node

FireBird的专栏 3298

DMA基本概念及linux2440下DMA驱动程序编写与测试

转自:http://blog.techbulo.com/tech/artical/1462.html 1、基本概念 DMA即Direct Memory Access(直接存储器存取),那么为什么要引入这么个东东呢?它的作用又是什么呢?我们通过一个例子来说明: 比 如当我们要往内存里面拷贝一块很大的数据时,由于CPU同一时间只能做一件事情,这样在一段很长的时间里就不能再处理其它

8113
上一篇: DMA 相关的一些结构体
下一篇: od --- 查看文件二进制原型
lamdoc
博客等级 码龄18年 155粉丝 655原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值