亮相,为工业应用场景中Arm®
Cortex®-A架构微处理器嵌入式处理能力的充分发挥提供了强大助力。
发表于 04-22 10:49
•461次阅读
聚焦纯国产高边开关的核心价值,深入解析WS9008AE的性能优势与应用场景,筑牢产品供应链自主安全防线。
发表于 04-09 09:22
•596次阅读
要求严苛、多主体协同难度大等独特性,各类关键保护技术在落地应用中面临诸多瓶颈,严重制约了微电网效能的充分发挥,了解微电网管理系统平台咨询服务:1.3.7-5.0.0.4-6.2.0.0。本文将聚焦工业园区应用场景,系统拆解微电网
发表于 03-06 11:22
•1691次阅读
Linux内核内存分配
Linux系统使用了一种称为“虚拟内存”的机制。虚拟内存机制使得每个内存地址都是虚拟的,这意味着它们不会直接指向RAM中的任何地址。这样我们访问内存中的存储单元时,都会进行地址转换以匹配相应的物理内存
在Linux系统中,内核中的每个进程都表示为一个task_struct结构体实例,该结构体实例表征并描述了这个进程。在进程开始运行之前,系统会为其分配一个内存映射表,该表存放在struct mm_struct类型的变量中。在内核中,全局变量current时钟指向当前进程,current->mm字段指向当前的进程内存映射表,struct mm_struct结构定义参见include/linux/mm_types.h
地址转换和MMU
MMU不仅可以将虚拟地址转换为物理地址,还可以保护内存免受未经授权的访问。给定一个进程,需要从此进程访问的任何页都必须位于一个VMA中,且必须位于进程的页表中
由于最近访问的数据存放在缓存中,因此最近转换的地址也存放在缓存中。数据缓存加快了数据访问过程,TLB则加快了虚拟地址的转换过程。TLB是内容可寻址内存,其中键是虚拟地址,值是物理地址,其运作过程如下图所示
内存分配机制
下图展示了Linux系统中不同的内存分配器。最低级别的分配器是页分配器,它以页为单位分配内存,然后是Slab分配器,它建立在页分配器的基础上,从中获取页并将它们拆分为较小的内存实体,kmalloc分配器依赖于Slab分配器
实现DMA支持
DMA是计算机系统的一种特性,它允许设备在没有CPU干预的情况下访问主系统内存,使CPU嫩巩固专注于其他任务。它的使用示例包括网络流量加速、音频数据或视频帧抓取等,它的使用并不限于特定领域。负责管理DMA事务的外围设备是DMA控制器,它存在于大多数现代处理器和微控制器中。
DMA的工作方式如下:当驱动程序需要传输数据块时,便使用源地址、目标地址和要复制的总字节数设置DMA控制器,然后DMA控制器自动将数据地址从源地址传输到目标地址,而不会占用CPU周期。当剩余字节数为0时,数据块传输结束并通知驱动程序。
DMA引擎API
DMA控制器接口由两部分组成:控制器和通道。控制器执行内存传输,通道则是客户端驱动程序向控制器提交作业的方式
DMA控制器在Linux内核中别抽象为dma_device结构体实例,其定义如下
struct dma_device {
struct kref ref;
unsigned int chancnt;
unsigned int privatecnt;
struct list_head channels;
struct list_head global_node;
struct dma_filter filter;
dma_cap_mask_tcap_mask;
enum dma_desc_metadata_mode desc_metadata_modes;
unsigned short max_xor;
unsigned short max_pq;
enum dmaengine_alignment copy_align;
enum dmaengine_alignment xor_align;
enum dmaengine_alignment pq_align;
enum dmaengine_alignment fill_align;
#define DMA_HAS_PQ_CONTINUE (1 << 15)
int dev_id;
struct device *dev;
struct module *owner;
struct ida chan_ida;
u32 src_addr_widths;
u32 dst_addr_widths;
u32 directions;
u32 min_burst;
u32 max_burst;
u32 max_sg_burst;
bool descriptor_reuse;
enum dma_residue_granularity residue_granularity;
int (*device_alloc_chan_resources)(struct dma_chan *chan);
int (*device_router_config)(struct dma_chan *chan);
void (*device_free_chan_resources)(struct dma_chan *chan);
struct dma_async_tx_descriptor *(*device_prep_dma_memcpy)(
struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
size_t len, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_xor)(
struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src,
unsigned int src_cnt, size_t len, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_xor_val)(
struct dma_chan *chan, dma_addr_t *src,unsigned int src_cnt,
size_t len, enum sum_check_flags *result, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_pq)(
struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src,
unsigned int src_cnt, const unsigned char *scf,
size_t len, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_pq_val)(
struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src,
unsigned int src_cnt, const unsigned char *scf, size_t len,
enum sum_check_flags *pqres, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_memset)(
struct dma_chan *chan, dma_addr_t dest, int value, size_t len,
unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_memset_sg)(
struct dma_chan *chan, struct scatterlist *sg,
unsigned int nents, int value, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)(
struct dma_chan *chan, unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_slave_sg)(
struct dma_chan *chan, struct scatterlist *sgl,
unsigned int sg_len, enum dma_transfer_direction direction,
unsigned long flags, void *context);
struct dma_async_tx_descriptor *(*device_prep_dma_cyclic)(
struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
size_t period_len, enum dma_transfer_direction direction,
unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
struct dma_chan *chan, struct dma_interleaved_template *xt,
unsigned long flags);
struct dma_async_tx_descriptor *(*device_prep_dma_imm_data)(
struct dma_chan *chan, dma_addr_t dst, u64 data,
unsigned long flags);
void (*device_caps)(struct dma_chan *chan,
struct dma_slave_caps *caps);
int (*device_config)(struct dma_chan *chan,
struct dma_slave_config *config);
int (*device_pause)(struct dma_chan *chan);
int (*device_resume)(struct dma_chan *chan);
int (*device_terminate_all)(struct dma_chan *chan);
void (*device_synchronize)(struct dma_chan *chan);
enum dma_status (*device_tx_status)(struct dma_chan *chan,
dma_cookie_t cookie,
struct dma_tx_state *txstate);
void (*device_issue_pending)(struct dma_chan *chan);
void (*device_release)(struct dma_device *dev);
/* debugfs support */
void (*dbg_summary_show)(struct seq_file *s, struct dma_device *dev);
struct dentry *dbg_dev_root;
};
DMA通道的结构体定义如下
struct dma_chan {
int dev_id;/* this channel is allocated if >= 0, */
/* free otherwise */
void __iomem *io;
const char *dev_str;
int irq;
void *irq_dev;
unsigned int fifo_addr;
unsigned int mode;
};
请求DMA通道
dma_request_channel()函数用于请求一个通道
struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
dma_filter_fn filter_fn,
void *filter_param);
配置DMA通道
DMA引擎框架使用struct dma_slave_config数据结构进行配置,该数据结构表示DMA通道的运行时配置,这样客户端就可以指定诸如DMA方向、DMA地址、总线宽度和DMA突发成都等外设的参数,struct dma_slave_config数据结构定义如下
struct dma_slave_config {
enum dma_transfer_direction direction;
phys_addr_t src_addr;
phys_addr_t dst_addr;
enum dma_slave_buswidth src_addr_width;
enum dma_slave_buswidth dst_addr_width;
u32 src_maxburst;
u32 dst_maxburst;
u32 src_port_window_size;
u32 dst_port_window_size;
bool device_fc;
void *peripheral_config;
size_t peripheral_size;
};
通过dmaengine_slave_config()函数将这种配置作用于底层硬件上
static inline int dmaengine_slave_config(struct dma_chan *chan,
struct dma_slave_config *config)
{
if (chan->device->device_config)
return chan->device->device_config(chan, config);
return -ENOSYS;
}
配置DMA传输
这一步用于确认DMA传输的方式,要进行一次DMA传输,就需要用到与DMA通道对应的控制器中的一些函数,这些函数名为device_prep_dma_*,例如对于内存到内存的传输,使用device_prep_dma_memcpy()
struct dma_async_tx_descriptor *tx;
struct dma_chan *chan = acdev->dma_chan;
dma_cookie_t cookie;
unsigned long flags = DMA_PREP_INTERRUPT;
int ret = 0;
tx = chan->device->device_prep_dma_memcpy(chan, dest, src, len, flags);
if (!tx) {
dev_err(acdev->host->dev, \"device_prep_dma_memcpy failed\\\\n\");
return -EAGAIN;
}
提交DMA传输
为了把事务放到驱动程序的事务待处理队列中,可以使用dmaengine_submit()函数
static inline dma_cookie_t dmaengine_submit(struct dma_async_tx_descriptor *desc)
{
return desc->tx_submit(desc);
}
发出待处理的DMA请求并等待回调通知
启动传输是DMA传输设置的最后一步,可以通过在通道上调用dma_async_issue_pending()来激活通道待处理队列中的传输。
static inline void dma_async_issue_pending(struct dma_chan *chan)
{
chan->device->device_issue_pending(chan);
}
发表于 02-04 22:30
Neway电机方案在电机控制的应用场景Neway电机方案在电机控制领域的应用场景广泛且效果显著,其核心优势在步进电机、伺服电机控制及CNC机床主轴驱动等场景中得到了
发表于 01-04 10:10
在汽车电子系统中,如何充分发挥 GTM IP的功能,以满足复杂的系统级应用场景,是用户实现高效控制与精确响应的关键。本文将聚焦几个典型且核心的应用实例,探讨GTM IP在车载系统中的具体实现方式与优势。
发表于 12-30 17:36
•867次阅读
(ADAS);
嵌入式平台的 AI 与机器学习加速器;
工业物联网与自动化系统(开放标准架构的优势能充分发挥)。
对咱们开发者来说,这波合作最大的好处就是能拿到集成式解决方案,不仅能缩短开发周期,还能
发表于 12-18 12:01
GIS设备地图管理平台是基于地理信息系统(GIS)技术构建的,用于对设备相关的地理空间数据进行采集、存储、管理、分析和可视化展示的综合信息平台
发表于 11-18 11:31
•681次阅读
目前芯源的低功耗MCU比较火爆,就是CW32L0系列都有哪些应用场景?有哪些优势?
发表于 11-14 06:03
近日,经纬恒润与长春富维海拉车灯有限公司(以下简称“富维海拉”)顺利完成战略合作协议签约。未来,双方将充分发挥各自在车载智能灯光领域的互补优势和资源,共同推动创新灯光解决方案在智能汽车领域
发表于 07-15 17:08
•732次阅读
。古河云科技将详细探讨安全监测预警平台在不同领域的典型应用场景。 城市安全领域 1. 城市生命线工程监测 在城市燃气、供水、供热、排水等生命线工程中,监测预警平台发挥着关键作用: -
发表于 07-11 15:00
•801次阅读
的优势,如高效、彻底、节能、环保等。本文将重点介绍非标超声波清洗设备的最大优势以及如何充分发挥其特点。一、高效清洗非标超声波清洗设备通过高频声波的作用,能够在短时
发表于 07-08 16:58
•749次阅读
在电子测量领域,频率计是用于测量信号频率的关键仪器。而多通道频率计模块作为一种先进的频率测量组件,正凭借其独特的优势在众多领域发挥着日益重要的作用。那么频率计它的优势在哪,又有哪些场景
发表于 06-12 16:16
,使得其响应速度较慢,无法充分发挥NVMe SSD的速度优势。若想要在嵌入式系统中充分发挥NVMe协议的高速读写性能,一方面可以通过优化软件执行流程,来提高传输
发表于 06-02 23:28
在工业自动化进程中,工控机作为核心设备,其性能、功能需与应用场景精准适配,才能充分发挥效能,保障生产流程的高效与稳定。由于工业场景丰富多样,从精密制造车间到户外能源设施,从高速运转生产
发表于 05-14 15:56
•925次阅读
评论