- 博客(352)
- 资源 (8)
- 收藏
- 关注
原创 算法学习之排序算法(三)(选择排序法)
选择排序工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。选择排序是和冒泡排序差不多的一种排序。和冒泡排序交换相连数据不一样的是,选择排序只有在确定了最小的数据之后,。
2015-08-13 21:55:38 894
原创 算法学习之排序算法(二)(直接插入排序法)
1、插入法排序原理直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。
2015-08-12 21:34:58 941
原创 算法学习之排序算法(一)(冒泡法)
冒泡排序的内容并不复杂。假设有n个数据需要排序,那么我们需要确定n个从大到小的数据,每一次都挑选第n大的数据是多少,并且放大相应的位置。直到所有的数据都排列整齐了,那么我们的排序就结束了。 1、冒泡代码void bubble_sort(int array[], int length){ int inner = 0, outer = 0; int median = 0; if
2015-08-12 21:25:46 1070
原创 void* 指针有什么用
void*其实可以理解为一个context,利用它可以很好的实现C语言面向对象编程。我觉得使用void*,不是为了看起来合适,而是一个约定,使用C/C++编程的人员看到void*,习惯性的就会认为——这是个私有数据,只有定义的一方才有权解释;这也是我们在回调函数中传递void*作为userdata的基础共识。void*指针其实可以用作泛型,你想象一下你在C中要交换两个变量,如果
2015-08-11 22:02:12 3990
原创 Linux 网卡驱动学习(六)(应用层、tcp 层、ip 层、设备层和驱动层作用解析)
本文将介绍网络连接建立的过程、收发包流程,以及其中应用层、tcp层、ip层、设备层和驱动层各层发挥的作用。
2015-08-11 21:56:10 4071
转载 error while loading shared libraries: xxx.so.x"错误的原因和解决办法
一般我们在Linux下执行某些外部程序的时候可能会提示找不到共享库的错误, 比如:tmux: error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory原因一般有两个, 一个是操作系统里确实没有包含该共享库(lib*.so.*文件)
2015-08-10 21:29:04 2062
原创 Linux 网卡驱动学习(五)(收发包具体过程)
函数接口设备初始化函数网络设备驱动在 Linux 内核中是以内核模块的形式存在的,对应于模块的初始化,需要提供一个初始化函数来初始化网络设备的硬件寄存器、配置 DMA 以及初始化相关内核变量等。设备初始化函数在内核模块被加载时调用,它的函数形式如下: static int __init xx_init (void) { …… } module_init(xx_
2015-08-08 22:05:15 8944
原创 代码从记事本拷贝到 source insight 工程出现中文乱码解决办法
1、代码从记事本拷贝到source insight 工程,此时出现乱码,解决办法,将输入法切换到中午输入法即可。2、source insight 阅读VC++源码,注释为乱码解决方案1、options->preferences->Syntax Formatting->Styles; 2、在Style Name 选择 Comment,再对其Font Name 选择Pick,然后再选择“新宋体”。3、
2015-08-08 18:37:25 3625
原创 DPDK 的 uio 以及 PMD 机制的实现
本文主要分析uio和PMD的实现main函数中首先调用了rte_eal_init初始化eal环境,其中主要是hugepage的初始化;ret = rte_eal_init(argc, argv);if (ret 0) rte_exit(EXIT_FAILURE, "Invalid EAL arguments\n");接着创建了mbuf po
2015-08-04 21:52:22 15081
转载 DPDK 中断机制 eal_intr_handle_interrupts
DPDK通过在线程中使用epoll模型,监听UIO设备的事件,来模拟操作系统的中断处理。 一、中断初始化在rte_eal_intr_init()函数中初始化中断。具体如下:1、首先初始化intr_sources链表。所有UIO设备的中断都挂在这个链表上,中断处理线程通过遍历这个链表,来执行设备的中断。2、创建intr_pipe管道,用于epoll模型的消息通
2015-08-04 21:38:45 2143
转载 DPDK 内存管理(三)(rte_malloc 内存管理)
rte_malloc()为程序运行过程中分配内存,模拟从堆中动态分配内存空间。1 void *2 rte_malloc(const char *type, size_t size, unsigned align)3 {4 return rte_malloc_socket(type, size, align, SOCKET_ID_ANY);5 }rte_mallo
2015-08-04 21:33:00 4484 1
转载 DPDK 内存管理(二)(rte_mempool 内存管理)
DPDK以两种方式对外提供内存管理方法,一个是rte_mempool,主要用于网卡数据包的收发;一个是rte_malloc,主要为应用程序提供内存使用接口。本文讨论rte_mempool。rte_mempool由函数rte_mempool_create()负责创建,从rte_config.mem_config->free_memseg[]中取出合适大小的内存,放到rte_config.mem_co
2015-08-04 21:31:38 6654
转载 DPDK 内存管理(一)(内存初始化)
1 前言 DPDK通过使用hugetlbfs,减少CPU TLB表的Miss次数,提高性能。2 初始化DPDK的内存初始化工作,主要是将hugetlbfs的配置的大内存页,根据其映射的物理地址是否连续、属于哪个Socket等,有效的组织起来,为后续管理提供便利。2.1 eal_hugepage_info_init()eal_hugepage_info_ini
2015-08-04 21:30:15 5991
转载 DPDK 收发包处理流程(二)(网卡初始化)
三、PCI驱动注册调用rte_eal_init()--->rte_eal_dev_init()函数,遍历dev_driver_list链表,执行网卡驱动对应的init的回调函数,注册PCI驱动。/* Once the vdevs are initalized, start calling all the pdev drivers */ TAILQ_FOREA
2015-08-04 21:25:11 11429 1
转载 DPDK 收发包处理流程(一)(网卡驱动注册)
本文基于DPDK-1.8.0分析。网卡驱动模型一般包含三层,即,PCI总线设备、网卡设备以及网卡设备的私有数据结构,即将设备的共性一层层的抽象,PCI总线设备包含网卡设备,网卡设备又包含其私有数据结构。在DPDK中,首先会注册设备驱动,然后查找当前系统有哪些PCI设备,并通过PCI_ID为PCI设备找到对应的驱动,最后调用驱动初始化设备。一、网卡驱动注册以e1000网卡驱动
2015-08-04 21:23:15 5838
原创 GNU C - 一个别致的 HelloWorld 程序 (__attribute__机制)
对[ __attribute__ ] 很感兴趣,下面来看一个不一样的HelloWorld程序:12345678910111213141516171819#include #include
2015-08-03 21:31:52 1016
原创 __attribute__((constructor))
gcc为函数提供了几种类型的属性,其中包含:构造函数(constructors)和析构函数(destructors)。 程序员应当使用类似下面的方式来指定这些属性:__attribute__((constructor)) // 在main函数被调用之前调用__attribute__((destructor)) // 在main函数被调用之后调#include<stdio.h> __attrib
2015-08-03 21:31:06 6068
原创 dlopen 方式调用 Linux 的动态链接库
在dlopen()函数以指定模式打开指定的动态链接库文件,并返回一个句柄给 dlsym()的调用进程。使用 dlclose()来卸载打开的库。/*功能:打开一个动态链接库,并返回动态链接库的句柄包含头文件:#include 函数定义:*/void * dlopen( const char * pathname, int mode);/*函数描述:mode是打开方式,其值有多
2015-08-02 09:49:22 2972
原创 Linux 下动态链接库 *.so(生成、调用)
【摘要】动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,这里做个笔记。1、动态库的编译下面通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。//so_test.h:#include "stdio
2015-08-02 09:34:12 3148
原创 Linux 网卡驱动学习(四)(缓存描述符 Buffer Description)
Linux 网卡驱动学习(缓存描述符 Buffer Description)。BD 描述符包含了报文很多信息,比如长度,报文的缓存地址等等。
2015-07-30 22:12:45 4624
原创 Linux 网卡驱动学习(三)(net_device 等数据结构)
【摘要】前文对网络驱动例子进行一个简单的梳理总结,本文贴出 net_device 的数据结构以及一些驱动中常用的数据结构。1、网络设备驱动结构下图摘自http://blog.chinaunix.net/uid-20672257-id-3147768.html1)、网络协议接口层向网络层协议提供提供统一的数据包收发接口,不论上层协议为ARP还是IP,都通过dev_queue_xmit
2015-07-30 22:01:08 9937
原创 Linux 网卡驱动学习(二)(网络驱动接口小结)
【摘要】前文我们分析了一个虚拟硬件的网络驱动例子,从中我们看到了网络设备的一些接口,其实网络设备驱动和块设备驱动的功能比较类似,都是发送和接收数据包(数据请求)。当然它们实际是有很多不同的。1、引言首先块设备在/dev目录下有设备节点,而网络设备没有这样的设备入口。read,write等常规的文件接口在网络设备下也没有意义。 最大的区别在于:块设备只响应内核的数据请求;而网络设备驱动要异步地接收来
2015-07-29 20:01:37 8378 3
原创 Linux 网卡驱动学习(一)(分析一个虚拟硬件的网络驱动例子)
Linux 网卡驱动学习(分析一个虚拟硬件的网络驱动例子),网络设备驱动层是连接网络堆栈协议层和网络硬件的中间层。
2015-07-29 19:32:21 6540
原创 u32、u16、u8 数据类型
#define U32 unsigned int #define U16 unsigned short #define S32 int #define S16 short int #define U8 unsigned char #define S8 charunsigned char = u8 unsigned short int = u16 unsigned long int
2015-07-29 19:10:09 50753
原创 格式化说明符以及修饰符(整理)
【摘要】最近用到一些格式化输出符,调试老提示类型不对,故整理一下,方便查看。1、 转换说明符转换说明符 意 义%c把输入解释成一个字符%d把输入解释成一个有符号十进制整数%e,%f,%g,%a把输入解释成一个浮点数(%a 是C99标准)%E,%F,%G
2015-07-29 19:06:13 1931
原创 x86(32位)分页管理的机制
页的尺寸是4KB,虚拟地址的前20位用于指定一个物理页,后12位用于访问页内偏移。 页表项的结构: 层次化的设计想法: 因为4GB的虚拟内存共有1M=220=1048576个4K大小的页面。 我们将这些页面分成210=1024份,即从页表1到页表1024,由页目录表管理; 每一份(每一页表)有210=1024个页,由每一个页表管理,页在页表中是随机的,哪个页位于哪个页表中是没有规律的;
2015-07-28 21:18:05 1579
原创 Compare And Swap(CAS)实现无锁多生产者
struct node{struct node *next;int data;}struct node *queue;//队列头多个消费者(多线程)都需要向这个queue插入数据 为了说明问题的复杂性,先看看只有一个消费者时的情况,插入队列的操作非常简单: Step1) new_head->next = queue->head; Step2) queue->head = n
2015-07-27 21:59:22 3966
原创 dma_alloc_coherent (建立一致性 DMA 映射函数)
A: 内存的虚拟起始地址,在内核要用此地址来操作所分配的内存B: struct device指针,可以平台初始化里指定,主要是dma_mask之类,可参考framebufferC: 实际分配大小,传入dma_map_size即可D: 返回的内存物理地址,dma就可以用。所以,A和D是一一对应的,只不过,A是虚拟地址,而D是物理地址。对任意一个操作都将改变缓冲区内容。当然要注意操作环境。
2015-07-25 19:24:31 18853 1
原创 open(“/dev/mem “,O_RDWR | O_SYNC)
【摘要】open(“/dev/mem”,O_RDWR|O_SYNC) 中/dev/mem是物理内存的全映像,可以用来访问物理内存。然后mmap,接着就可以用mmap的地址来访问物理内存,这实际上就是实现用户空间驱动的一种方法。 http://blog.csdn.net/wlp600/article/details/6893636#
2015-07-25 19:14:04 12226 2
原创 并发无锁队列学习(单生产者单消费者模型)
【摘要】本文介绍单生产者单消费者模型的队列。根据写入队列的内容是定长还是变长,分为单生产者单消费者定长队列和单生产者单消费者变长队列两种。单生产者单消费者模型的队列操作过程是不需要进行加锁的。生产者通过写索引控制入队操作,消费者通过读索引控制出队列操作。二者相互之间对索引是独享,不存在竞争关系。
2015-07-24 19:45:10 4993 1
转载 并发无锁队列学习(数据结构)
提到并行计算通常都会想到加锁,事实却并非如此,大多数并发是不需要加锁的。比如在不同电脑上运行的代码编辑器,两者并发运行不需要加锁。在一台电脑上同时运行的媒体播放放器和代码编辑器,两者并发运行不需要加锁(当然系统调用和进程调度是要加锁的)。在同一个进程中运行多个线程,如果各自处理独立的事情也不需要加锁(当然系统调用、进程调度和内存分配是要加锁的)。在以上这些情况里,各个并发实体之间没有共享数据,所以虽
2015-07-24 19:35:12 2533
原创 并发无锁队列学习(概念介绍)
【摘要】队列在计算机中非常重要的一种数据结构,尤其在操作系统中。队列典型的特征是先进先出(FIFO),符合流水线业务流程。在进程间通信、网络通信之间经常采用队列做缓存,缓解数据处理压力。结合自己在工作中遇到的队列问题,总结一下对不同场景下的队列实现。根据操作队列的场景分为:单生产者——单消费者、多生产者——单消费者、单生产者——多消费者、多生产者——多消费者四大模型。其实后面三种的队列,可以归纳为一种多对多。根据队列
2015-07-24 19:23:56 7145
原创 ioremap 函数映射操作已知的物理地址(寄存器、端口、IO)
ioremap 函数来映射到内核地址空间,然后修改虚拟地址空间达到控制寄存器的状态。我用如下方法操作一个地址为0x56000020的端口
2015-07-23 22:10:59 4669
原创 内核态空间地址直接映射到用户态空间访问
【摘要】Linux中的内核空间到用户空间的地址映射让用户层应用可以直接访问内核地址,这就是mmap方法。应用程序通过内存映射可以直接访问设备的I/O存储区或DMA缓冲。内存映射使用户空间的一段地址关联到设备内存上,程序在映射的地址范围内进行读取或者写入,实际上就是对设备的访问。
2015-07-23 21:31:27 8806 1
原创 嵌入式 Linux 对内存的直接读写(devmem)
【摘要】这个工具的原理也比较简单,就是应用程序通过mmap函数实现对/dev/mem驱动中mmap方法的使用,映射了设备的内存到用户空间,实现对这些物理地址的读写操作。
2015-07-23 21:03:36 25160 2
原创 自己总结的 Makefile 小模板
all:commtestCFLAGS=-fPIC -g -WallARIA_INCLUDE=-I/usr/local/Aria/includeARIA_LINK=-L/usr/local/Aria/lib -lAria -lpthread -ldl -lrt%: %.cpp $(CXX) $(CFLAGS) $(ARIA_INCLUDE) $< -o $@ $(ARIA_LINK).
2015-07-20 21:21:32 623
原创 逻辑地址、虚拟地址、物理地址以及内存管理
本文涉及的硬件平台是X86。物理地址、虚拟地址、逻辑地址、线性地址之间的关系进行了细致分析。其实,内存资源在驱动设计中的地位是至关重要的,我们要对设备进行操作,首先要获取到设备的地址。在UIO用户态驱动设计中,用户直接操作设备,我们就应该明白操作到底是什么地址,明白地址之间映射的关系,才能更好的理解这个设备。
2015-07-19 17:27:32 2714
转载 Linux内存寻址之一:内存地址分类以及MMU介绍(转)
对于程序员来说,可以简单的把内存地址理解为一种访问存储单元的内容的一种方式。而对于80x86系列微处理器来说,我们需要区分三种地址: 1)逻辑地址 这种地址通常使用在机器语言里用于指定操作数或机器指令的地址。该类地址在著名的80x86分段体系架构中得到了很好体现,因此DOS程序员和windows程序员都不得不把他们的程序分成一段一段的(如代码段、数据段、堆栈段等等)。每一个逻
2015-07-19 16:59:21 870
原创 DMA (Direct Memory Access,直接内存存取)
对DMA内存的使用有3种方式:1,一致DMA映射通过dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag)来直接得到一块用于dma的内存,同时得到这一段内存的虚拟地址和总线地址,分别用于CPU和device的访问。 通过这种方式得到的dma内存,开发者不用担心cache的问题,但
2015-07-18 18:40:26 3343
原创 Linux 设备驱动之 DTS 描述的资源
在linux使用platform_driver_register() 注册 platform_driver 时, 需要在 platform_driver 的probe() 里面知道设备的中断号, 内存地址等资源。这些资源的描述信息存放在 resource 数据结构中, 相同的资源存放在一个树形树形数据结构中, 通过父节点, 兄弟节点, 子节点相连。 比如中断资源, IO端口资源, IO内存资源,
2015-07-16 22:27:36 6378
GP接口函数描述和入参解析
2022-05-04
Linux 设备模型之kobject
2015-06-08
字符设备LED驱动程序
2015-04-14
Windows下基于socket多线程并发通信的实现
2015-04-07
采温显示存储报警模块
2013-04-02
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人