Category: Software Design

It describe the software design note.

H.264 codec Note

•       Elements of a video Sequence o    Frames o    Slices o    MBs (macroblocks) •       Frame Types o    I-, P-, B-frames o    GOP (group of picture), specifies the order in which intra– and inter-frames are arranged. o    NAL (Network Abstraction Layer) v  SPS (Sequence parameter set) v  PPS (Picture parameter  set) v  IDR (Instantaneous Decoder Refresh),
Read More »

使用 qemu 调试 linux kernel

  在 Ubuntu 中build kernel 参考如下: [Ref] https://wiki.ubuntu.com/KernelTeam/GitKernelBuild    可以直接在宿主机调试kernel, 但是当发生崩溃之后,工作环境又要重新配置。   所以考虑用 qemu,因为它有个option: -kernel, 可以直接引导kernel。比 VirtualBox 等虚拟机更快速更方便。 尝试使用 qemu 直接启动主机上的kernel  $ sudo qemu-system-x86_64 -kernel /boot/vmlinuz-`uname -r` 这会提示缺少文件系统 可以使用 debootstrap 构建一个rootfs  IMG=qemu-image.img DIR=mount-point.dir qemu-img create $IMG 1g mkfs.ext2 $IMG mkdir $DIR sudo mount -o loop $IMG $DIR sudo debootstrap --arch amd64 jessie $DIR sudo umount $DIR
Read More »

git 相关

gitosis 搭建: git 本身是一个分布式的版本管理系统,但如果要设置一个中心库方便很多开发者同步,或者像SVN 一样使用它,就需要搭建git on the server – gitosis。 详情参考: https://git-scm.com/book/en/v1/Git-on-the-Server-Gitosis ubuntu:~$ sudo apt-get install git-core openssh-server openssh-client ubuntu:~$ sudo apt-get install python-setuptools ubuntu:~$ git config --global user.name "myname" ubuntu:~$ git config --global user.email "******@gmail.com" ubuntu:~$ git clone https://github.com/res0nat0r/gitosis.git ubuntu:/tmp$ cd gitosis/ ubuntu:/tmp/gitosis$ sudo python setup.py install ubuntu:/tmp/gitosis$ sudo useradd -m git ubuntu:/tmp/gitosis$ sudo passwd
Read More »

petalinux use guide summarize

petalinux 是针对 Xilinx FPGA-based SOC designs 的 embedded linux system development kit 。 包含了: Yocto Extensible SDK Minimal downloads XSCT and tool chains PetaLinux CLI tools   详情参考 PetaLinux Tools Reference Guide。 版本: v2018.2 June 6, 2018    不支持 ubuntu1804, 手贱装了ubuntu1804, 结果 build 的时候出现 Bitbake 运行不起来,google 一遍发现这版本petalinux  还是暂时不支持 ubuntu1804 ,遂重新装回1604. 总结: petalinux 安装, 略。 BSP
Read More »

c/c++编译相关技巧总结帖

链接时忽略文件中未用到的函数或者对象。这在移植代码过程中很有用, 我们就不需要去删除或者注释掉那些大量没用到的对象或者不需要去链接的对象。 For GCC, this is accomplished in two stages: First compile the data but tell the compiler to separate the code into separate sections within the translation unit. This will be done for functions, classes, and external variables by using the following two compiler flags: -fdata-sections -ffunction-sections Link the translation units together using the
Read More »

linux bash shell 像cmd.exe 一样的滚动补齐功能

有些情况下,比如我们遇到文件名含有一些字符不容易输入时就很着急了,这时候就需要让linux shell像windows cmd.exe 一样自动补全部的文件名,且可自动按顺序一个个滚动切换。方法如下: 在用户目录创建 ~/.inputrc (若不存在则自己创建) 文件里添加一行: 。 登出再登陆用户就可以了。 For more details see the READLINE section in man bash .

ubuntu 上部署OpenVPN服务

缘起: 最近家里的长城宽带通往海外的线路堵得厉害(感觉长城宽带就是GFW的实验场),用ss翻墙都难连上服务器,apple store也难连上。于是不得不在国内阿里云的服务器上搭一个VPN。不仅可以解决长城宽带的问题,平时手机在外面连接不安全的wifi时也不用担心信息会泄漏了。另外VPN还可以将分布在各处的内网主机组成局域网,VPN服务就相当于是在中间的虚拟路由器。 参考了以上几个链接的博客总结一下安装过程。 http://www.linuxidc.com/Linux/2014-08/105925p2.htm http://www.linuxidc.com/Linux/2012-01/51702.htm https://help.ubuntu.com/lts/serverguide/openvpn.html http://blog.csdn.net/joyous/article/details/8034132 OpenVPN 是在TCP/UDP 端口上建立一个安全IP网络通道,支持SSL/TLS 对数据加密、授权等。简单点理解就是在传输层上建立一个虚拟线路,作IP包的交换,相当于一个虚拟网卡。原文是这么说的: * OpenVPN — An application to securely tunnel IP networks * over a single TCP/UDP port, with support for SSL/TLS-based * session authentication and key exchange, * packet encryption, packet authentication, and * packet compression. 一、安装OpenVPN dnsmasq 在用来在vpn路由器功能里面充当域名服务器的作用。有的版本openvpn包含了 easy-rsa ,不用再安装easy-rsa。如果没有再自行安装easy-rsa,它包含生成密钥用的脚本文件。 注:更新本地仓库:apt-get update 安装完查看openvpn相关安装包位置的命令:
Read More »

Lwip 内存管理

Lwip 用它自己的动态内存分配方式替代了标准C的malloc(); 它可以使用MEM_POOL的方式分配内存,即开辟几个不同尺寸的缓冲池,给数据分配合适的缓冲区来存放,就类似于使用数组的方式,可能会比较浪费空间,但是可以有效避免内存碎片产生, 这在第二部分讲。两种方式分别在mem.c memp.c里面实现,下面先总结一般的内存堆分配方式。 (一) 内存堆动态分配方式 首先是内存对齐,这里用到的MCU是按4字节对齐的。这一语句功能是将addr 调整成最靠近addr的且能被4整除的值,其实就是(addr+3)&(~(u32)(0x03)),+3之后有余数的自然就进位了然后再舍掉余数。其实也可以用 addr = (addr&0x03)?(addr+1):addr; 这样应该也可以,更容易理解一些,但是没有上面的简便。 这里申请了一个内存堆ram_heap, 大小包括整个MEM_SIZE + 两个STRUCT_MEM的大小 + 4, 假设申请了MEM_SIZE 为8k。 内存初始化。ram 指向了ram_heap开头, 并且在开头初始化了一个struct mem。 ram_end 指向了MEM_SIZE之后的第一个STRUCT_MEM, 这里不知道是不是bug,我觉得应该指向&ram[MEM_SIZE_ALIGNED+SIZEOF_STRUCT_MEM]; 没时间了,以后再慢慢研究。 lfree最开始也指向了开头。 ->next 等这些参数都是相对地址,相对ram的,方便之后用数组的方式访问。 内存分配函数。首先对齐size,并且size不能太小或者太大,太小容易产生过多的碎片导致后期内存不足。 然后搜索heap,找到适合的块。lfree指向未分配的内存位置,刚开始它是在开头。 ptr=lfree-ram 即是lfree相对ram的位置,即已经用掉的内存大小。 ptr mem 先指向lfree所指的位置,当这块内存未被使用并且剩下的内存大于size时,…略复杂,待续… (二) 内存池的动态分配 内存池顾名思义就是一个个划分好的池子,不像内存堆一样东西乱堆。 pbuf是协议栈里最常用的数据类型,它有多种类型的存储方式,如下: 我们从pbuf入手研究一下MEM_POOL内存池的编写方式。 pbuf_alloc(PBUF_POOL)调用的是: p = (struct pbuf *)memp_malloc(MEMP_PBUF_POOL); 我们来看看MEMP_PBUF_POOL是如何声明的: memp_std.h里定义了各种类型POOL. memp.c 定义了 几个数组来保存每个pool的元素大小和数量。定义一个memp_memory[]内存块保存所有的pool。
Read More »

methods of handling multiple connections as lwip

这里分享一些一个服务handle多client连接的经验。 (1) 多线程/进程方法 每accept并创建一个新连接之后,就create一个task来处理这个连接的事务。linux使用fork()来创建分支线程。freertos 不支持fork方法,只能创建新的线程来管理连接。此方法内存开销较大。 (2) non-blocking socket 和 select 此方法由单线程处理并发事务,即最原始的轮询方式。在系统不支持fork()的情况下经常用到。首先,accpet/recv函数都必须的non-blocking的,需立即返回,否则其它任务就得不到轮询。这种模式在跑单片机裸机程序时经常是这样的,另外在labview里面也经常是这样的轮询的方式。这个例程可以在lwip 1.4.1 contrib下app demo:chargen 里可以学习到。这种方式会占用很多cpu资源,这样的任务优先级要放低,并设置一定的轮询间隔(类比在labview里,while循环通常会插入一个等待时间)。否则 freertos 中低优先级任务就得不到运行,同优先级的任务也只能分时间片轮流运行。 这里简单总结下 select方法。 协议栈内核在每次有accept 或 recv事件到达后都会调用 event_callback(); 增加一个事件记录。在上层接收后都会减掉一个记录。select 函数通过查询socket的对应event来置位fd_set对应的比特位。本质就类似查询一个计数信号量。 (3) 使用 raw api, 基于事件触发(基于回调)方式。 此方式适合编写只进行简单处理的应用,每次接收到包就会调用相应的回调函数。多连接是由协议栈的active_pcb_lists直接管理,每个连接都创建属于自己的state argument。如果需要运算量比较大占用时间较长的服务则不适合此方式,会影响的协议栈对其它服务的响应速度。 后记,从事务的角度来看,一个tcp连接代表一个session,一句udp 请求也代表一个session。一个session从接收到返回就是一条事务线。若不能一气呵成,则就必须用一条线程去管理它,或者说维护一个工作现场,等待它的后台任务完成再回来应答这个事务。一条线程就对应一个事务现场,多任务操作系统就是在不同的工作现场的中交替工作,模拟多个人工作的情况,每一个工作现场都保存的对应工作事务的进展情况和所有需要用到的工具。 或者还有一种做法,就是一件事做完一部分后丢给后台,让它处理完之后调用我给它的办法帮我把剩下的事处理完,节省了任务之间信息传递和任务切换带来的开销。 其实一个session对应一个任务确实有点浪费,我想一般handle几百上千万个连接的服务应该不会这样做的,每个连接只需将它当前的状态变量连同数据包传给每个部门来做就可以了,毕竟每个连接的状态的数据量不是很多,没必要开辟一个专门的任务去Handle.

Lwip 里的信号量、邮箱、线程

这里简单分析总结一下Lwip sys_arch.c 中的信号量、邮箱、进程相关的内容。系统用的是FreeRTOS。 这里创建了两个全局结构体数组来管理semaphores and mailboxes. 有个不明白的地方是,结构体里的buffer是用来作什么的? 这里的semaphore其实用的是长度为1的queue来实现。mbox是长度为size的queue,其中消息对象类型都是void *,由于freertos在把消息送入队列和提取出队列都是复制的方式(应该是类似ringbuf的操作,没深入研究),所以这里为了提高效率,把对象封装一个消息结构体,只传递指针。在作消息传递时要特别注意内存的分配和释放,以免造成内存泄漏。 这里还要总结的一点是,类似于这种xxx_new, xxx_alloc的函数,用来分配对向内存的函数,传递进去的是指针的地址,因为要将指针指向新分配的内存,所以传进去的为指针的地址。 如这样调用: Lwip 的Thread是用FreeRTOS的xTaskCreate()来实现的。这里有个问题, TI的sys_arch.c里的sys_thread_new的实现,又用mem_malloc()分配了栈内存,是不是多此一举了,因为xTaskCreate里会为这个任务分配栈内存。这里似乎没有任何用处。