0%

背景

12月11日下半年的软考成绩公布了,我这次三个科目(综合、案例、论文)都及格了,经过一年的备考,继上半年案例挂了之后,这次各科都及格了,终于二次上岸了,为这段学习经历画下了圆满的句号。

分享一下自己的备考的经验和感受吧。

阅读全文 »

前言

最近在写一个通用的测试工具用于认证,针对不同的产品差异不同,通过代码或者编译选项来区分产品太不灵活了。因此,有了使用配置文件来修改的想法。

现写一个当然不如找一个,在AI的时代,使用GPT来辅助编程越来越方便高效了。目前工作中,使用的最多的就是kimi了。大概搜索了一下,找到一个minIni的库。

这是一个小巧且便携的INI文件库,支持读写操作,特别适合嵌入式系统。minIni库是根据Apache许可证2.0版分发的,外加一个例外条款,以明确允许将该库静态链接到商业应用程序,对于我想写的小型的测试程序也很适合。

阅读全文 »

前言

不知道什么情况,最近支持的客户越来越多了。前人欠的债,后人帮忙还。

最近有个客户使用了公司的产品,通过strongSwan配置了IPSec通路,使用了内核的xfrm框架实现数据包的加解密。为了提升吞吐量,需要使用到内置密码引擎功能。

然后在使用iperf进行流量测试时,发现存在丢包的问题。反馈到了技术支持,最终落到了我的头上。

这个驱动是历史产物了,也算是公司第一代的产品。一直也没有什么客户在用,也就一直没有收到市场的问题,给人一种产品很好的错觉。领导也经常引以为傲哈。

但实际情况是我已经填了不下10个坑。

阅读全文 »

前言

随着摩尔定律的消失,日益增长的数据交换增长并促进更快的硬件及软件的需求。对整个网络和存储也有了更高的要求。
在实际项目中,经常发现应用程序的性能并没有随着CPU数量的增加而提升。在性能为王的时代,如果不能找到产品的性能瓶颈并进行调优,那么产品将会被市场抛弃。

其实,大部分应用程序的性能提升都源于软件栈。下面是一个4096X4096矩阵乘法的性能表现:

阅读全文 »

前言

perf是Linux内置的性能分析工具,主要是利用了硬件技术单元比如CPU, PMU和软件的计数,软件计数器及跟踪点。
perf的源码在Linux内核源码的tools/perf下。

perf

perf包含许多二级命令,实现不同的功能:

阅读全文 »

前言

继续了解一些linux开发使用到的调试手段:

  • devmem: 可以在终端直接查看或者修改设备寄存器的值
  • top: 用于实时运行系统的监控,包括Linux内核管理的进程或者线程的资源占用情况
阅读全文 »

前言

复习一下linux内核中的同步管理机制,内核中用于同步管理的几个机制主要有:

1
2
3
4
5
6
7
8
自旋锁- 同一个时刻只能被一个代码路径持有锁,其他代码路径一直忙等待,不会休眠,适合占用锁比较短的场景,可以用于中断上下文
原子量- 适合临界区只是一个变量的情况,开销比较小
内存屏障-这个主要是为了阻止编译器的优化而进行指令重排,导致实际执行路径不符合预期的场景
信号量-适合生产者消费者模型,等待会进入睡眠状态,不能用于中断上下文,适合情况复杂,加锁时间较长的场景
互斥量-同一个时刻只有一个代码路径持有锁,会进入睡眠状态,不能用于中断上下文,比信号量简单,结构更小
读写锁-允许同时多个读,同时只能一个写,读写互斥
RCU- read-copy-update 目的是减少多CPU间缓存一致性的开销,允许写者在读者访问期间就修改内容,没有读者的时候更新内容

阅读全文 »

背景

本周收到一个客户需求,他们希望在系统里集成我们的驱动,希望驱动能够自动根据硬件来确定是否加载,最好就是只提供一份驱动,在不同机型下能自适应处理。

由于历史原因,我们的这些硬件从设计上就是不兼容的,且分别开发了不同的驱动,并没有一个统一的驱动架构。一般驱动是可以根据设备树或者ACPI表的描述,自动和硬件匹配的。只要硬件的描述不一样,那么加载了驱动后,也只有相应的驱动会匹配生效。

又由于各种原因,有些机型根本就不存在硬件描述,因此在驱动代码里是通过ioremap直接传入固定的地址来获取硬件的寄存器基址。所以平常的设备树和ACPI表机制用不了了。

阅读全文 »

前言

截至当前,工作中涉及的驱动基本都是字符设备驱动,内核通过字符设备向用户空间提供API,实现内核与用户态间的交互。

学习字符设备需要了解以下几方面的知识:

  • 了解Linux内核字符设备驱动程序的架构
  • 了解Linux内核字符设备驱动相关的API
  • 了解Linux内核内存管理的API
  • 了解Linux内核中断管理的API
  • 了解Linux内核同步和锁相关的API
  • 了解具体芯片的工作原理及操作方式

下面围绕几点,概述一下相关知识。

阅读全文 »

前言

总感觉自己在linux驱动这块的基础比较薄弱,再学一下linux内核驱动的基础,重新巩固一下。趁着最近有时间尽快巩固一下,活到老学到老,温故而知新。

阅读全文 »

前言

本周事儿挺多,原先计划的代码开发一行也没写啊,又写文档,又参加会议各种评审,代码review, 然后又支持了几个客户,问题定位修改验证的。

简要挑两三个事简单聊一下。

阅读全文 »

前言

最近在看华为加速引擎KAE的源码,该库通过sysfs文件将设备驱动的一些信息导出到用户态,在用户态代码中通过访问/sys下的文件,获取或者操作加速引擎,而不是使用ioctl的方式。抽空看看内核文档,了解一下sysfs的系统使用及编程。

阅读全文 »

前言

dmadev lib顾名思义就是用来使用dma设备的框架,伴随着摩尔定律的失效,现在CPU的性能几乎很难进行提升了。那么提高性能的方式就只能是软件不够硬件来凑了,让许多工作从CPU卸载到硬件去。
dmadev lib库是DPDK中的一个软件库,提供管理和配置DMA poll mode drivers的软件,定义了统一的操作接口。支持一系列不同的DMA操作。

阅读全文 »

前言

组内代码格式不统一,每当我review的时候,总发现各种规范问题,比如代码行缩进不一致, 操作数和运算符之间空格时有时无,对于代码洁癖的人这是很难忍受。
那么就只能用工具了,鉴于Windows下编码大部分时候使用vscode,所以就找到了clang-format插件,而且在Linux下clang-format还可以集成到git hook里。

我抽空研究了一下,然后形成配置文档,让组里的同事照着配置一下。

阅读全文 »

前言

这两天把前一段时间从图书馆借的《CPU通识课》这本书看了一遍,这是一本科普类书籍,还是蛮适合IT人员阅览的。作者在讲解的过程中会结合自身的实践,感受不会很空洞。
内容还是挺多的,包含CPU的概览、术语、架构原理、生产制造的流程、相关企业及软件生态。

阅读全文 »

前言

最近项目上出了个比较重大的bug,驱动注册的时候会偶发挂死、计算结果不正确,而且在不同内核版本,不同PAGE_SIZE下还表现不一样。
鉴于有合作方已经在使用了我们的驱动了,问题等级就上升了。项目组的小妹搞了快1个半月了,依然没有任何头绪,期间组内也组织过一次代码评审,都没有看出啥问题。
最后我就临时被拉去救火了,其他的工作全部暂停。
目前大部分问题已经定位解决,除了异常分支错误处理外,其他就是DMA-API的滥用了。

阅读全文 »

前言

GDB是程序员调试的必备工具,使用GDB可以解决大部分程序错误问题。

当然还有其他的使用方式,比如近期在项目中就使用GDB截图的方式通过了商密检测,截图作为一种方式证明了数据的确是真实的。

这几天刷头条,偶然刷到了GDB相关的文章,顺便搞个文章重新梳理一下GDB的知识结构及使用方法。

阅读全文 »

前言

最近在技术支持的时候,需要在客户机器上编译驱动代码,遇到了一个问题,客户机器上面没有相应的内核头文件编译环境,没办法编译。

后面由同事通过安装deb包的形式把头文件之类的安装后,就可以正常编译了。

在我之前的理解中,要替换内核的话,只能在目标机器上编译内核,然后按照之前编译内核的文章讲的步骤替换内核。

现在发现,内核也是可以通过软件包的方式安装的,自己动手走一下打包流程。

阅读全文 »

前言

最近一直在忙项目,需要跟固件的同事打交道。
在Linux中,目前设备的信息很多是通过ACPI表描述的,而这个ACPI表是需要固件写入的,我们操作系统驱动没办法控制。在调试的过程中,经常会遇到在不同的机器上面,驱动执行不一致的问题。驱动代码都是同一份的,不同的就是固件了。而固件内部,除了一些硬件寄存器配置外,就是ACPI表的描述了。很多时候,不晓得别人是不是给你描述对了,与其去问,还不如自己动手去看ACPI表了。

上网查了一下,get一个新技能。

阅读全文 »

前言

我有一台机器,经常换内核版本调试。机器是公司的产品,如果使用标准的内核启动的话,常常因为配置问题那个图形用户界面会登录不进去,就没办法在用户界面下配置IP。

之前也没有进行详细的了解,不晓得有一个netplan的工具可以配置IP。所以使用的方法也比较挫,就是在/etc/profile文件中添加了几个命令配置IP的。
这样,就有一个问题,必须有用户登录才能触发执行这些命令。又刚好我有一个串口线接着机器,所以每次重启后我就先通过串口登录,触发IP配置命令,后面就可以使用ssh网络连接了。

最近呢,串口线让同事借走了,然后又有人连着我的机器进行驱动调试,经常就奔溃了,重启后又要接串口,一个串口线就要来回使用,很麻烦。

阅读全文 »

前言

最近在测试程序的性能,发现测试出来的数据波动比较大,不是很稳定。

测试的机器上存在大小核的区别,系统在空闲的时候尽量会使用小核进行运算,这样就可以降低功耗。

正常一个程序在运行的时候,也是会在不同的cpu之间进行切换的。通过设置了CPU亲和性后,测试出来的数据就基本变化不大了。

阅读全文 »

前言

Linux内部提供了一个dm-crypt的模块,支持对映射设备进行加密。Cryptsetup是一个基于DMCrypt内核模块来设置磁盘加密的工具。
此文主要介绍使用该工具实现磁盘加密的步骤,不涉及实现原理。

阅读全文 »

前言

最近项目组要调研一下Linux磁盘加密的技术,测试一下自研XTS模式算法的性能是否满足需求。

采用fio这个Linux下比较流行的磁盘IO性能工具来测试,浅浅地学习了一下fio的使用,所以就有了本文的小结。

fio最初是作者用来保存测试程序的,这些程序用于测试不同工作负载、定位性能问题或者重现bug。最后,作者就整了这么个工具,可以模拟各种IO负载,用于重复测试。

阅读全文 »

2022年小结

自去年元宵节前夕独自开车到长沙,业已一年有余。趁着元宵节刚过,且昨晚下半夜没睡着,稍微回顾小结了一下刚过去的2022年。

阅读全文 »

前言

MAC算法用于验证消息的正确性, 通信的双方根据共享的密钥,分别对消息进行计算。发送方发送原始消息+计算结果A,接收方接收到消息后,也对消息进行计算得到计算结果B,并对比A和B来判断消息是否完整正确。

阅读全文 »

前言

AES是目前最常见的一种对称算法, AES是一种分组算法,所有的数据都按块进行加密,AES的数据块大小为16字节(128bit), 但是AES的密钥有128/192/256bits三种,密钥的长度不同的话,加密的轮数有差异。

阅读全文 »

前言

算法类型定义算法加密的数学实现(如明文块的长度,如何对明文密文进行加解密),算法模式则定义具体类型中加密的流程细节(例如加密的轮数、如何操作加解密的输入输出)。

阅读全文 »

前言

前一段时间,主要在忙着给一个设备驱动设计并开发一个用户态库,并且在项目组里评审。期间,比较系统的学习了华为KAE加速库、Intel的QAT加速库的代码,时间很快两三周就过去了。

阅读全文 »

前言

国庆后这周连续上来7天班,事情做了许多,也包含了许多小事儿,大的部分暂时没有准备好。本周就拼凑着讲一下几个小事儿。

阅读全文 »

1. 前言

最近看了流密码算法的Crypto PMD,稍微总结一下。

2. 介绍

Snow3g/Zuc PMD都是基于intel-ipsec-mb库实现的库。许多数据和操作都是公共的,代码都位于dpdk/drivers/crypto/ipsec_mb目录下。

intel-ipsec-mb库是为包处理提供的一个软件加密库,可以用在IPsec, TLS, Wireless等应用中。

ipsec_mb下还有多个pmd,对应不同的算法。不同pmd类型相关的数据会保存到ipsec_mb_pmds变量中,公共函数根据当前的pmd类型获取对应pmd的数据和函数处理数据。实现不同pmd的分离。PMD类型在PMD初始化时保存到dev的dev_private区域。

阅读全文 »

前言

数据平面开发套件(DPDK, Data Plane Development Kit)是由6WIND,Intel等多家公司开发,主要基于Linux系统运行,用于快速数据包处理的函数库与驱动集合,可以极大提高数据处理性能和吞吐量,提高数据平面应用程序的工作效率。
CryptoDev库是DPDK中的一个软件库,提供的管理和配置Crypto poll mode drivers的软件,定义了统一的操作接口。支持加密、认证、链式加密认证、AEAD等对称类算法操作和非对称类算法操作。

阅读全文 »

前言

相信大家大部分情况都是使用linux服务器写代码编译代码,看代码又是在Windows系统下。那么就需要有种方法,让我们可以在windows下面直接看linux服务器上面的代码,也就是可以共享linux服务器上面的文件到windows系统中。samba就是满足这种需求的软件。这个算是程序员工作中比较基础的脚手架了。

阅读全文 »

前言

这周使用cmake构建了一个新工程代码,目录结构参照GmSSL3.0进行了划分,新增的代码和测试代码都编译测试运行OK,也增加了相应的README说明。在我看来,初步版本已经是完整的了。使用cmake可以使得构建中间文件跟源代码分离,而且cmake还提供了安装、打包的功能,已经相当的完善了。初期的工作是完成了。

阅读全文 »

前言

做驱动开发免不了要用到DMA技术, 这是一种高速的数据传输操作,允许外设直接读写存储器,不需要CPU的介入。这样CPU就可以继续做其它的事情了。控制这个操作的是DMA控制器。

CPU地址和DMA地址

系统内核使用的是虚拟地址,任何从kmalloc, valloc返回的地址都是虚拟地址,可以使用void *变量存储。虚拟地址可以通过内存管理系统(MMU)转换为CPU的物理地址。内核管理的设备资源一般都是物理地址,比如设备的寄存器地址之类的,这些地址的范围都存在于/proc/iomem文件中。物理地址是不能直接使用的,需要通过ioremap映射得到一个虚拟地址,然后代码才可以访问。

阅读全文 »

前言

Linux IO中有阻塞和非阻塞之分。阻塞就是在执行操作的过程中,如果不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。非阻塞则不会挂起,直接返回结果,然后可以不停的来查询直到可以进行操作,也可以放弃操作。

阅读全文 »

前言

ECC椭圆曲线的应用有两种:

  • ECDSA 数字签名验签, 主要是使用私钥对信息的摘要加密,然后发送刚给对端,对端使用发送方的公钥解密得到摘要信息,再计算一下信息的摘要,对比一下确认摘要是否一致。主要用于确认这个信息是发送方发送的,没有被篡改过。
  • ECDH 密钥交换,主要用于协商通信双方使用的对称密钥。
阅读全文 »

前言

这周完成了流密码算法的驱动开发及调试。毕竟对驱动的一些机制了解的还不够深,还是花了许多时间才调试完成,加了三天的班。中间遇到了一个dma内存映射的问题,由于映射时参数错误导致数据一直没有更新。前面写驱动代码的时候,也只是参照着其它算法的代码写的,那个算法的代码比较久了,没有及时地更新,导致又走了些同样弯路。总之,还是自己对驱动相关的知识没有掌握导致的。

阅读全文 »

前言

前面讲过ZUC算法是3GPP LTE 第三套加密标准核心算法,而Snow 3G则是第二套加密标准核心算法,ZUCSnow 3G算法的英文描述可以在这个网站上找到:

https://www.gsma.com/security/security-algorithms/

avatar

阅读全文 »

前言

ZUC是一个对称流密码算法,其以中国古代著名数学家祖冲之的拼音(ZU Chongzhi)首字母命名,中文称作祖冲之算法。

这段时间在实现ZUC算法的驱动,ZUC是一个国产的密码算法集。包含了三个部分,分别是算法的描述,也就是如何产生密钥流的。然后就是保密性算法,用于对数据进行加解密。最后就是完整性算法,类似于MD5等的摘要算法,为给定的数据计算出一个唯一的消息认证码,用于确认消息在传递的过程中不被篡改。

阅读全文 »

前言

Linux内核里有一个密码学框架Linux kernel crypto。框架内部提供了常用的标准算法,比如:AES, DES, MD5, SHA1, RSA,DSA等。框架也是支持开发者自定义算法的,通过框架可以注册我们自己的算法,比如国标的SM2, SM3, SM4等, 或者某个公司内部的私有算法。当然了, 也支持对已有的算法重新注册,可以通过优先级设置让用户调用到我们注册的算法。框架代码在内核源码下的crypto目录。

阅读全文 »

前言

在Linux中一切都是文件,所有的资源都是通过文件的形式来访问控制的。

驱动最终通过文件相关的系统调用来访问,Linux的驱动架构也是基于文件系统而设计的。

阅读全文 »

前言

工作需要,开始接触驱动开发了。

驱动作为硬件和软件的中间层,驱动就是驱使硬件设备行动的简述。驱动与底层的硬件打交道,根据硬件的工作方式,读写寄存器,完成设备的控制。驱动向上提供统一的API,使得软件可以使用通用的接口,通过不同的驱动来控制不同的设备。

阅读全文 »

前言

openssl的性能测试主要就是测试在固定时间内、不同长度数据进行算法操作的次数。最后统计每1000秒钟处理的数据量或是每秒钟进行运算的次数,可以通过执行md5/rsa512/aes-128-cbc算法的性能测试看一下输出的结果:

阅读全文 »

RSA算法概述

RSA算法是常用的非对称算法,应用广泛。比如常见的ssh连接,使用过gitlab的开发者都接触过,通过rsa算法可以生成一对证书,通过把公钥设置到gitlab上面,本地才可以通过ssh的方式下载代码。

阅读全文 »

最近在写代码的时候,因为是一个全新的工程,也没有引入什么日志库,直接就printf输出调试了。

这个总归是有一点儿不雅,然后想到之前用的sysrepo这个开源库,他提供的那个日志功能挺简单的,支持向终端错误stderr输出日志,也支持向syslog输出日志,而且使用起来也比较简单,想着借鉴着写一个。

阅读全文 »

前言

平常每周都会有一些心得感悟,这些在大家工作中可能会有许多共性。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常学习工作的想法和所得,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

平常每周都会有一些心得感悟,这些在大家工作中可能会有许多共性。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常学习工作的想法和所得,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

最近准备从零创建一个工程库,于是就准备专门学习这一块的知识,最主要的就是编译系统搭建了。之前很少进行这方面的系统学习,都是基于已有的工程上面修改,一般就是加个文件或者选项,都是比较简单的,主要工作还是在代码逻辑的编写。鉴于是一个新的C语言的工程,那就选择cmake来作工程编译工具了。周末两天花了些时间,在掘金上面看了一个系列的博客,然后再对比的官网的使用文档学习一下cmake。

阅读全文 »

前言

平常每周都会有一些心得感悟,这些在大家工作中可能会有许多共性。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常学习工作的想法和所得,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

最近看代码的时候看到了许多地方使用TailQ这个数据结构来组织数据,在过往的项目中一般都是直接使用的list这个链表的。稍微看了 一下代码的实现, 其实就是一个双向链表的实现,抽象出链表头保存头尾元素,然后链表的关系结构存放在具体节点的field域,提供一些常用宏的封装而已。链表成员关系主要如图所示:

阅读全文 »

前言

平常每周都会有一些心得感悟,这些在大家工作中可能会有许多共性。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常学习工作的想法和所得,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

平常每周都会有一些心得感悟,这些在大家工作中可能会有许多共性。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常学习工作的想法和所得,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

平常每周都会有一些心得感悟,这些在大家工作中可能会有许多共性。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常学习工作的想法和所得,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

平常每周都会有一些心得感悟,这些在大家工作中可能会有许多共性。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常学习工作的想法和所得,这是一个很好的互动和文章分享的痛点。

阅读全文 »

最近连续看了一个微信公众号小林coding的图解网络的文章,收获挺多。在这里发文小结一下,也方便后续工作中查询。

阅读全文 »

前言

平常每周都会有一些心得感悟,这些在大家工作中可能会有许多共性。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常学习工作的想法和所得,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

在工作中,每周都会遇到一些问题,这些问题在大家工作中可能会有许多共性,于我也是一种经验的积累小结。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常工作遇到的问题,这是一个很好的互动和文章分享的痛点。

阅读全文 »

虚拟化

虚拟化顾名思义就是不是真实的,非实际物理的。而是逻辑上面的一个概念。平常的机器资源大小是固定的,不能灵活改变。而且资源是不能够复用的, 在一台机器上的资源就那么多,系统编号都是按序来的,不能够大家都一样的。怎么说了,其实系统本身也是具有虚拟化的概念,比如进程的虚拟地址,每个进程都有4G的虚拟空间。

阅读全文 »

前言

在工作中,每周都会遇到一些问题,这些问题在大家工作中可能会有许多共性,于我也是一种经验的积累小结。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常工作遇到的问题,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

在工作中,每周都会遇到一些问题,这些问题在大家工作中可能会有许多共性,于我也是一种经验的积累小结。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常工作遇到的问题,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

在工作中,每周都会遇到一些问题,这些问题在大家工作中可能会有许多共性,于我也是一种经验的积累小结。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常工作遇到的问题,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

在工作中,每周都会遇到一些问题,这些问题在大家工作中可能会有许多共性,于我也是一种经验的积累小结。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常工作遇到的问题,这是一个很好的互动和文章分享的痛点。

阅读全文 »

2021小结

2021年过去了,依旧是一个大灾之年,疫情依然笼罩着世界。

对于我而言,也算是一个特别的一年。

阅读全文 »

前言

在工作中,每周都会遇到一些问题,这些问题在大家工作中可能会有许多共性,于我也是一种经验的积累小结。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常工作遇到的问题,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

在工作中,每周都会遇到一些问题,这些问题在大家工作中可能会有许多共性,于我也是一种经验的积累小结。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常工作遇到的问题,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

在工作中,每周都会遇到一些问题,这些问题在大家工作中可能会有许多共性,于我也是一种经验的积累小结。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常工作遇到的问题,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

在工作中,每周都会遇到一些问题,这些问题在大家工作中可能会有许多共性,于我也是一种经验的积累小结。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常工作遇到的问题,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

在工作中,每周都会遇到一些问题,这些问题在大家工作中可能会有许多共性,于我也是一种经验的积累小结。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常工作遇到的问题,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

在工作中,每周都会遇到一些问题,这些问题在大家工作中可能会有许多共性,于我也是一种经验的积累小结。我觉得花一些时间整理一下,跟粉丝读者们分享一下日常工作遇到的问题,这是一个很好的互动和文章分享的痛点。

阅读全文 »

前言

前面学习的进程间的通信主要适用于同一台机器的两个进程间的通信,不同机器间的进程间通信就由网络通信来实现。通过定义好的网络协议,不同机器的进程传递交互的内容。当然,网络通信也可以适用于同一台机器的进程间通信,效率比其他方式差一些。进程间通信最快的属于共享内存。

阅读全文 »

前言

最近跟同事联调的时候,遇到了一个问题。我这边使用sysrepo实现了一个更改系统时间的功能的rpc,然后调用方每次调用的时候,如果设置的是将来的某个时刻,总是返回超时,设置当前时间以前的某个时刻,又是正常的。跟踪查看回调的代码,没有任何异常,而且时间的确设置下去了,也正常返回了。这是一个必现的问题,大概想了一下,应该是代码中使用系统时间判断超时了,需要深入看一下sysrepo的代码。

阅读全文 »

前言

sysrepo对资源的保护自己实现了一个读写锁, 支持多个线程同时读,只有一个线程在写的保护。使用的是互斥量加条件量来实现的。读写互斥使用一个变量控制。结构如下(基于1.4.87版本,新版本变了,原理差不多):

阅读全文 »

前言

几个月前了吧,团队有人测试了一下通过netconf给list类型的节点添加2w条表项,发现随着表项数目的增加,后面创建新表项的时间几乎呈一个线性的增长。到最后,每增加一个配置,大概就要耗时8s左右的时间,很显然,这是一个比较严重的性能问题。另外,即使你修改其他模块的配置,这个耗时也要6s左右的时间。就是如果一个模块的配置量很大,还会影响到其他模块的处理,这个就更严重了。

阅读全文 »

背景

sysrepo是基于共享内存的数据库,实际共享内存的外在体现是一个共享的文件。对这个共享文件的访问控制又是通过文件锁的方式来实现的。因为sysrepo只是一个库而已,会被多个进程链接,共享内存文件的路径都是一致的,在编译的时候确定了的。多进程间的资源互斥这里使用的就是文件锁的方式。

阅读全文 »

最近编码get或者温故了一些skill,小结记录一下。

core dump

Ubuntu系统产生core文件方法
ulimit -c unlimited
sysctl -w kernel.core_pattern=/tmp/core-%e.%p

阅读全文 »

插件顾名思义就是通过宿主程序提供的机制,影响宿主程序而实现特定功能的一种程序。

sysrepo数据库的一个重要的功能是在数据变更的时候,通过共享内存文件保存变更的内容,然后通过变更内容的模块找到相关路径订阅的管道id,通过往管道文件中写入随机数据通知订阅处理线程取数据,然后进行对应的操作处理。 

阅读全文 »

前言

由于项目需要,安排了一个月左右的时间研究一下开源代码sysrepo这个共享内存型的数据库,后面得根据需要实现一些定制的需求,还有性能提升,数据是yang模型的数据。整体代码量大概3w行,每天刷个三四千行,每天日子过得很快很快,安排熟悉代码的时间也就七天,很是紧凑,消耗的还是有点儿慢。收获也颇多吧,从中也看到了许多linux接口的使用,后面陆续分享上来。

阅读全文 »

前言

最近项目上面要在两个进程间通信,传递一些设置的信息。而且之前项目调用系统的一些接口使用了dbus的通信机制,所以想着也使用dbus来做这个功能。

阅读全文 »

基于buildroot框架进行的交叉编译,首先拷贝官网buildroot包,然后拷贝里面的nginx的脚本配置。然后运行make nginx

以下是前段时间编译nginx遇到的一些问题:

阅读全文 »

最近需要编译一个arm平台上面的nginx,项目使用的buildroot构建环境,实现自动化的编译。前期的构建工具之类的已经由平台组的同事弄好了,主要的工作就是进行nginx的交叉编译,中间陆续踩了许多坑,简单聊聊吧。

阅读全文 »

最近看代码,一些服务进程在main函数中会调用daemon函数创建守护进程,然后继续执行。 又联想到之前项目在调试的时候,一般在shell中会执行多次的程序名后加一个&符号,让进程进入后台执行,还可以看到终端的输出。有时候我们自己写的小程序,在shell中使用程序名执行,查看输出结果。

阅读全文 »

前言

最近在英文文档中游离,不断的吸取协议规范的点点滴滴。发现还是有一点儿费劲的,在阅读的同时自然少不了做一些笔记。以往的经验,都是在word或者txt文档里面,记录一下自己感觉比较重要的点,同时在记录的过程中增加理解。阅读文档和阅读代码,我都是这样子做的。相信大多数程序员也都差不多吧。

阅读全文 »

最近有了几天的空闲时间,又开始了学习的征程。之前在极客时间上面订阅了《从0开始学架构》的专栏,在专栏结束之后,作者还陆续增加了一些文章上去,其中有一篇就是讲中台的。

阅读全文 »

最近完成了项目CAN协议模块的编写,CAN作为一种总线类型,多台设备连接到总线上,在短距离传输上有其优势,套用相关公司的广告就是 “CAN协议 – 方便灵活 功能强大”:

阅读全文 »

近两周完成了MODBUS协议RTU格式的开发,包含了从站和主站的功能,算是完成一个简易版的MODBUS协议栈了,做个小结。

阅读全文 »

信号

信号其实是一个很像中断的机制,事先注册号信号的处理函数,或者使用默认的处理函数, 当接收到奥信号的时候,调用对应的处理函数进行处理。中断呢,系统默认有一个中断向量表,存储中断处理程序,当接收到中断的时候,从中断向量表中获取中断处理程序进行处理。只是中断是在内核态处理,信号是在用户态处理。

阅读全文 »

github不稳定,近期老是被墙,换到码云上去。

行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

字符设备中断

前面在学习文件读写的时候,如果是读取设备上的内容, 那么在读取完毕的时候,设备会发送一个中断告知CPU内容读取完毕。同样的,字符设备也是有中断来通知CPU处理事件, 比如鼠标设备就是通过中断来告知系统自己的位置和按键信息,传递给驱动程序。

阅读全文 »

输入输出系统

我们知道计算机由CPU、主板、硬盘、内存、鼠标、键盘、显示器、网卡等部件组成。 这里鼠标、键盘等是输入设备, 硬盘、显示器等是输出设备。网卡既是输入设备也算输出设备。这么多不同的设备,统一由输入输出系统来管理。

阅读全文 »

文件系统

对于运行的进程来说,内存就像一个纸箱子,仅仅是一个暂存数据的地方,而且空间有限。如果我们想要进程结束之后,数据依然能够保存下来,就不能只保存在内存里,而是应该保存在外部存储中,比如磁盘,数据是以文件的形式保存在硬盘上的。文件系统就是对文件进行管理的模块。

阅读全文 »

用户态内存映射

mmap

1
2
3
4
struct mm_struct { 
struct vm_area_struct *mmap; /* list of VMAs */
......}

在进程的mm_struct有一个mmap的成员, 是内存映射的一个重要结构。内存映射不仅仅是物理内存和虚拟内存之间的映射,还包括将文件中的内容映射到虚拟内存空间。

阅读全文 »

2020年小结

嗯,的确这个年度小结来的有点儿迟了。2021年都过了一个月了,惭愧。在过去的一个多月里面,一直在忙着作新项目的性能优化工作,在不断的试验(Start->编译-重启-配置-测试->Start 循环)中渡过,会发现每天时间都过得很快。 还是有点怀念华为的补丁技术,以及RN的动态更新功能。虽然本人也花了点时间了解了一下补丁技术,奈何对系统平台还有这个交叉编译器没有足够的知识储备,性能优化的任务也比较急,只能一遍遍的重启验证,呵呵。

阅读全文 »

墨菲定律的应验

其实第一次接触这个概念是在科幻电影《星际穿越》里,没看过的同学可以去看一下。“墨菲定律”的根本内容是“凡是可能出错的事有很大几率会出错”,指的是任何一个事件,只要具有大于零的机率,就不能够假设它不会发生。

阅读全文 »

物理内存管理

物理内存的组织方式

把内存想象成它是由连续的一页一页的块组成的。我们可以从 0 开始对物理页编号,这样每个物理页都会有个页号。物理内存按固定的页大小划分为多个页,连续的内存分配给连续页号的页。对于任何一个地址,只要直接除一下每页的大小,很容易直接算出在哪一页。每个页有一个结构 struct page 表示,这个结构也是放在一个数组里面,这样根据页号,很容易通过下标找到相应的 struct page 结构。整个物理内存的布局就非常简单、易管理,这就是最经典的平坦内存模型(Flat Memory Model)。

阅读全文 »

内存管理

每个进程应该自己的内存空间。内存空间都是独立的、相互隔离的。对于每个进程来讲,看起来应该都是独占的。每个程序对内存的操作都是一致的,内存的管理是进程无关的, 不会因为进程的不同而区别对待,而都是一视同仁的。在最开始的时候,已经了解到程序对内存的操作都是通过虚拟地址实现的,就比如一个大数组,比如超过4kb的大小,已经超过一个页了,但是虚拟地址一定是连续的。只是物理地址就不大可能会是连续的了,通过分段分页的虚拟地址映射实现了物理地址的复用。

阅读全文 »

自从工作以来,渐渐的已经有大概十个年头了。时间真的是很快。自身也在不经意间不断的成长。在程序员这个行当里,有一个广为流传的35岁危机。在我看来,实际只是那些没有成长的人才需要担心。一年的经验用十年和扎扎实实地积累十年工作经验完全是两回事。

阅读全文 »

进程与线程

进程是系统资源调度和分配的基本单位,实现了操作系统的并发; 线程是CPU资源调度与分配的基本单位,实现进程内部的并发。线程属于进程的一部分,是进程的子任务。一个进程至少包含一个线程,相同进程下的线程共享地址空间等资源。每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。

阅读全文 »

ps命令大家最熟悉不过了,经常用来查看系统资源及进程的基础信息。 使用管道导出结果到grep, xarg等命令,实现一些定位的目的。

1
ps --help
阅读全文 »

系统调用流程

32位的系统调用的过程,首先保存参数、系统调用号到寄存器,然后触发中断int80 ,调用中断处理服务函数,然后取到寄存器里的参数,根据系统调用号获取执行函数,传入参数执行。执行完成后,iret恢复用户态执行上下文,继续执行。

阅读全文 »

BIOS到bootloader

BIOS

在主板的ROM上保存有BIOS程序,计算机启动首先读取BIOS(Basic Input and Output System,基本输入输出系统)程序进行运行。此时,计算机运行在实模式下,只能访问1MB的空间。这个1MB的空间也有一个标准的约定。

阅读全文 »

系统内核体系结构

操作系统是一个挺复杂的软件平台, 运行在其上的程序本身需要存储,涉及到文件管理子系统;运行时需要资源,涉及到内存管理子系统、进程管理子系统、系统调用子系统;如果程序与其他机器通信, 涉及网络子系统。运行时需要与用户交互,如显示 涉及设备子系统。 操作系统的内核主要就包含了这些子系统。

阅读全文 »

这个月有时间刷完了一遍极客时间上面订阅的《趣谈linux操作系统》这个专栏, 可以说比较系统的梳理了一下操作系统相关的基础知识。这个专栏是去年12.04号订阅的了, 订阅这个专栏的初衷是当时在准备换工作,发现工作后操作系统的知识只剩大学操作系统课程学习后的遗留映像,很多东西都模糊了,想着要好好全面的补一把相关知识,陆陆续续的学习了近10个月了,里面的内容应该还算是干货满满, 从原理到代码的讲解还是比较细节的。刷完一遍感觉收获多多,不论是复习巩固,还是温故而知新,都有所得。后面还需要安排二刷、三刷。里面有一个很好的观点, 读书先把书读厚,再把书读薄,又把书读厚。。。 其实,一直以来我学习也是按照这个套路来学习,一万小时定律嘛。

阅读全文 »

sed

stream editor 顾名思义为流编辑工具。通过正则表达式匹配到行,并进行相应处理,输出新行。用于自动编辑文件。

概要

1
sed 【OPTION】 ... {script-only-if-no-other-script} {input-file} ...
阅读全文 »

无论使用什么产品,照着使用指南进行一番操作是学习它最便捷快速的方法。使用指南都是给用户看的, 一般都是简单易懂,有示例。linux命令行也是一样。

阅读全文 »

上一周,我在调试项目性能指标时遇到了一个问题,支持的节点数在到达60718644时,程序就出错了。由于节点索引是一个27位的结构体位域,当值为60718644时,最高位为1,此时,代码中有一个转换函数,作了对位域的左移操作并赋给一个更大空间类型的变量,使得最后的结果不是预期的。show u code:

阅读全文 »

最近工作使用了几个小skill,优化了代码,还帮团队的小伙子搞定了插入排序的功能。现在有些年轻人技术有点不足啊, 一个二分查找插入搞了快一周还没完成, 汗!!!

阅读全文 »

近期工作回顾

新项目红红火火的开展了,前一阵子也忙了一下,嗯,现在自己这部分的代码终于吭哧吭哧的完成的差不多了,其他同事的工作离完成还善待时日。可以抽出空来对这段时间的编程工作做个小小的回顾。

阅读全文 »

运行库

每种语言的程序运行都需要其运行库的支持, java需要java虚拟机、JavaScript需要js引擎, C语言也需要glibc(Linux上)的支持。所谓运行库,就类似于语言的框架,编写语言时,需要根据框架的定义进行编程。比如,我们约定程序都是从main函数开始执行,用户就必须编写main函数,运行库在准备好运行环境之后,再调用main函数开始运行。

阅读全文 »

程序的内存布局

一个程序运行时的进程,都会被分配一块虚拟内存空间,虚拟内存空间再映射到内存中。程序可访问的虚拟内存空间的大小由CPU的位数决定,针对32位的系统最大可访问空间为4GB。 内存空间包含几个部分: 栈、堆、可执行文件映像、保留区。当然4GB不是全部分配给程序使用的,linux一般会把高1GB地址分配给系统内核,低3GB为用户进程空间。

阅读全文 »

共享库的组织

共享库的兼容

由于共享库的优点,许多程序都采用了共享库作为通用的库,而减少了静态库的使用。系统中,就会存在许多的共享库, 各个版本不一。在编译的时候,会在可执行文件的.dynamic段中写入程序依赖的动态库的SO_NAME。SO_NAME是一个类似libname.so.3的字符串,表示依赖名称为name的动态库, 动态库的版本为3.x.x。对于linux,动态库有其命名的规则,为libname.so.3.1.2。版本号的定义遵循semver格式。在linux中,还会存在一个libname.so.3的软链接,指向name对应的主版本为3的最新的版本文件,这样就解决了版本的兼容问题。

1
gcc -o main -lname // -lname 表示需要链接libname.so.a.b.c, 具体的版本由编译环境决定
阅读全文 »

动态链接

经过前面一些列的学习,可以知道一个程序运行时,可执行文件映像是需要被载入到内存中的。为了复用,很多程序使用了相同的静态库,那么这些静态库都是需要被分别链接合并到各个程序的可执行文件的。那么在磁盘上,其实有很多同一个静态库的内容的副本。 各个程序同时运行时,内存中也存在多个同一个静态库的内容的副本。很显然,浪费了很多空间, 也增加了许多载入内存的时间。同一个静态库,比如是C语言的基础库的静态版本,还有许多自研的共享库。

阅读全文 »

可执行文件的装载与运行

虚拟地址空间

程序通过编译链接之后,各个变量及函数的虚拟地址就已经确定了。每个程序都拥有独立的内存空间,程序运行时使用的是虚拟地址,操作系统通过内存映射的方式,把虚拟地址映射到物理地址,程序只需要通过虚拟地址操作即可,不需要关心实际的物理内存地址。程序可访问的虚拟地址的大小与系统的总线位宽相关, 32位系统允许访问4GB的地址。操作系统通过页映射的方式,加载程序的数据和指令到内存,没有被使用的数据和指令就被替换到磁盘中。

阅读全文 »

gdbserver是用于远程gdb的工具, 可以实现远程调试代码。很多嵌入式平台没有安装gdb,可以通过gdbserver启动,然后在网络可达的另一台主机起一个gdb进行远程代码调试。gdbserver占用空间比较小, 很适合在嵌入式系统里使用。

阅读全文 »

最近修改了同事写的一块算法处理代码,有一个地方看得很不舒服,如下

1
2
3
4
if (likely(offset)) {
offset = 0;
}

阅读全文 »

图片替换文本

看这边书的初衷是要重新复习一下C语言基础的语法,毕竟很长一段的工作没有用到C语言(严格的说OC也算是类C的语言吧)的,这本书也很适合初学者入门C语言, 感觉比谭xx的好一点吧,虽然我大学入门C语言的时候也是用的谭xx的书。

原本以为自己会从中学到一些遗漏的知识,结果却没有,看来C语言的基础在脑海中还是比较记忆深刻。每个章节后面是带有习题的,前几年也买过这个书,习题也都做过了,这次只是过一下内容,没有花时间做习题。只是粗粗的浏览了一下这本书。毕竟不需要在基础上面花太多时间,没有太大的意义。这个阶段,主要看书的所得应该是思想架构这类的,而不是太具体的实现细节,主要还是时间有限,O(∩_∩)O哈哈~。

行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

结构体偏移

项目通过定义union联合体使用同一块内存, 在代码运行的不同阶段访问具体的成员。针对一些希望跨阶段存在的数据在不同的结构中保持了一份相同的成员,保证在不同的阶段都可以方便的访问到该内容。要实现这样的目的,必须使各个结构中的相同成员在整个联合体的偏移是一样的。

阅读全文 »

背景

工作中,存在着这么一个问题。开发提供给测试的二进制版本,都是记录在一个excel表中,保存着对应版本的提测日期和文件的Md5值、以及对应的svn标签信息。但是,文件这种东西,是需要靠人来填写的。许多临时的版本,就没有记录了。经常出现测试的文件找不到对应的记录,不知道是何时提供、解决了什么问题。 那么,就有这么个需求,把对应的信息保存到二进制文件,在编译的时候,获取编译的时间,svn版本号,编译机器的用户名(一般可以对应到开发人员)等信息,自动生成源代码文件,记入编译文件。然后,还需要提供一种方式读取这些信息,让二进制文件支持参数处理是一个不错的方式。

阅读全文 »

对于嵌入式开发这种对空间要求比较苛刻的环境,对程序包的大小还是比较敏感的。一来, 可以节省空间。二来,在一定程度上可以减少页错误导致的载入载出,提升程序的性能。第三,对一些低速网络(比如:zigbee)连接的设备,提升OTA升级的效率。

可执行文件都是elf格式的, 文件都是由各个段组成的,对文件大小的优化就可以归结为各个段的优化。
第一,可以去掉执行时不需要的段,比如:release版本不需要调试信息、符号表等, 可以直接strip掉。 第二,还可以缩小一些段的内容,比如代码段。通过优化合并代码,减少重复代码。数据段,对于一些全局变量,定义的时候可以不进行初始化,在程序启动的时候初始化,使得这些全局变量放到bss段,不占用程序大小。只读的数据段,主要是一些字符串、const等不可变量。在发布的时候,通过宏控制删除大部分无用的调试信息,仅保留必要的错误日志的信息输出,这样可以减少只读数据段的大小。这个是单个文件的优化思路。

对于同时运行不同程序的平台,可以使用动态库,共享基础库。

行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

杂谈

很快,从去年11月份到现在已经半年多了,新工作的第一个项目也大抵结束了,近来有时间来说一说感想。

这次工作变动比较大,不仅仅更换了公司,还换了工作的城市。从做前端iOS转回到做网络设备安全, 从福建福州来到了湖南长沙,家庭成员也在长沙安顿下来了,福州的房子暂时还空闲着,一方面不舍得出租,另一个方面呢,疫情原因楼市不大景气,目前过着又还房贷、又租房的相对拮据的日子。

阅读全文 »

这是所有笔记的入口

行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

事情是这样的,项目在同一个系统下运行着2个程序A和B,A由同事负责,B由我负责。 A和B会有共享的一块内存, 内存主要分成几种情况:

  • 由A填写, B来读取
  • 由B填写, A来读取
  • B自己读写
  • A自己读写

各部分内存没有机制保证被合法读写, 只能通过代码写入的地址保证。 这种情况下, 应该各自封装接口,对地址越界的情况进行判断,然后通过接口调用,这样才能保证内存的安全访问。

阅读全文 »

2020书单

人不读书要落后,每年都需要读一些书来支持自我提升。电子书也好、实体书也好、亦或者是极客时间/知乎上的专栏都可以纳入,看完之后,对应写一篇读后感总结之类的文章。书籍可以是新书,也可以是读过的书,不论是增长见识、还是温故而知新都是不错的体验。主要是要保证自己坚持写博客。

书单列表

  • [x]《数学之美》 实体书
  • 《C程序设计语言》 实体书 2020.05-06 读后感
  • 《程序员的自我修养》 实体书 2020.06
  • 《Linux命令行与shell脚本编程大全》实体书
  • 《明朝那些事儿》 微信读书电子书 2020.04.19读完
  • 巨人三传 // 贝多芬传、米开朗基罗传、托尔斯泰传

行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

在linux下开发的工程师们对CoreDump肯定都不陌生,但凡有些许经验的工程师都或多或少使用过CoreDump文件定位过崩溃问题。之前工作中,在Android系统下开发C++程序时, 经常用到CoreDump。 中间转行去搞iOS已经五年了, 最近换了新工作,遇到程序宕掉同事让我看一下coredump文件,一时还没有反应过来, 今天好好复习一下。

阅读全文 »

iOS接口的单元测试

近期把一个业务复杂,功能繁多的库进行了拆分,实现了功能的单一性。代码重构告一段落,功能验证并且提测了,在QA测试阶段,终于闲下来把单元测试的代码也进行拆分与补充了。

现在就来聊聊iOS代码的单元测试。

单元测试本质上就是对我们写的代码接口进行执行,传入特定的参数,返回执行结果,然后对比结果与期望的值是否一致,确定功能是否执行正确。

阅读全文 »

不要滥用设计模式

最近在做代码剥离重构, 有一个基础库A,作为面向业务开发者的接口库,随着业务的发展,很多内容都往里面塞。虽然,中间每次添加都或多或少考虑了解耦,抽象了很多协议接口,但架不住常年累月的堆积啊。

阅读全文 »

YTKKeyValueStore是一个轻量级的sqlite数据库开源库,基于FMDB封装的一个key、value的数据库, 由猿题库团队开源。适用于数据量不大的情况,进行简单的数据存储。比如配置信息,或者用户信息等。

在工作中,我用它来存储版本及组件的信息, 通过查询数据,确认ipa是否升级以及确定组件是否需要更新(RN热更新)等策略。

阅读全文 »

有时候我们需要对某些对象作快照,需要复制对象当前的状态。OC中提供了copy/mutableCopy的方法。系统提供的集合类,比人NSArray、NSSet、NSDictionary都提供了对于的方法。 对于我们自定义的对象,则可以通过实现NSCopying/NSMutableCopying协议来实现对应的功能。

阅读全文 »

前言

最近,业务方提了一个需求,希望RN页面支持横竖屏。就去研究了一下, 顺便聊聊遇到的一些问题。

首先,应用要支持横竖屏旋转, 首先要在工程配置中勾选支持的方向。然后,不同的ViewController通过实现对应的接口实现横竖屏, 以及代码调用接口来手动实现横竖屏切换。

实现

勾选支持方向

工程 - General - Deployment Info - Device Orientation

controller接口

UIViewController需要实现3个接口

1
2
3
4
5
6
7
8
9
10
11
12
- (BOOL)shouldAutorotate {
return _isAutoRotate;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return self.supportedOrientation;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return self.preferredOrientation;
}

只有当shouldAutorotate为YES时,其它两个接口才生效。
UIInterfaceOrientationMask 标识支持的方向集合, UIInterfaceOrientation用于当控制器被present出来后的视图方向

方向

我们看代码, 可以看到2个方向, 界面方向和设备方向

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 用户界面方向
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown,
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
} API_UNAVAILABLE(tvos);


// 用户方向,一般与状态栏方向一致, 可以通过获取状态栏方向 来获取当前界面的方向

[[UIApplication sharedApplication] statusBarOrientation]



// 设备方向, 当前设备的方向
typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait, // Device oriented vertically, home button on the bottom
UIDeviceOrientationPortraitUpsideDown, // Device oriented vertically, home button on the top
UIDeviceOrientationLandscapeLeft, // Device oriented horizontally, home button on the right
UIDeviceOrientationLandscapeRight, // Device oriented horizontally, home button on the left
UIDeviceOrientationFaceUp, // Device oriented flat, face up
UIDeviceOrientationFaceDown // Device oriented flat, face down
} API_UNAVAILABLE(tvos);


// 设备方向, 通过当前设备的接口获取, 需要事先调用

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

[[UIDevice currentDevice] orientation]

... // 操作

[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];

很多时候, 界面方向会和设备方向不一致(支持当前设备方向的前提下)。 我们可以调用接口使其自动旋转。

1
2
3

[UIViewController attemptRotationToDeviceOrientation];

手动切换方向

目前只能通过修改orientation的方向来达到切方向的功能

1
2
3
4

[[UIDevice currentDevice] setValue:@(deviceOrientation) forKey:@"orientation"];
[UIViewController attemptRotationToDeviceOrientation];

根控制器支持横竖屏

大部分应用window不是以UIViewController为rootViewController。 一般是TabbarController或者NavigationControler。 要使得他们支持横竖屏,需要额外添加一个分类, 重新对应的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

@implementation UINavigationController (Rotation)

- (BOOL)shouldAutorotate {
if (self.viewControllers && [self.viewControllers count] > 0) {
return [self.topViewController shouldAutorotate];
}

return [super shouldAutorotate];
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
if (self.viewControllers && [self.viewControllers count] > 0) {
return [self.topViewController supportedInterfaceOrientations];
}

return [super supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
if (self.viewControllers && [self.viewControllers count] > 0) {
return [self.topViewController preferredInterfaceOrientationForPresentation];
}

return [super preferredInterfaceOrientationForPresentation];
}

@end


@implementation UITabBarController (Rotation)
- (BOOL)shouldAutorotate {
return [self.selectedViewController shouldAutorotate];
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return [self.selectedViewController supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return [self.selectedViewController preferredInterfaceOrientationForPresentation];
}
@end


// 大部分ViewController只支持竖屏, 不支持切换

@implementation UIViewController (rotate)

- (BOOL)shouldAutorotate {
return NO;
}

@end


具体实现代码 请参考github库 https://github.com/fishmwei/iOSLearnList

番外:最近家里添丁,事情比较多,挺久没有更新博客了, 以后坚持一周至少一篇。

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

最近在详细阅读React-Native源码,准备出一系列React-Native源码的解析及实现原理的连载文章,后续一一发布。 同时对遇到的iOS知识点进行梳理。基于React-Native 0.59.9版本的代码讲解。

本文讲的是NSCache,在RCTImage库中使用到的, 具体可以看 RCTImage/RCTImageCache.m中_decodedImageCache的使用。

RCTImage把获取到的图片缓存到RCTImageCache中,具体保存在_decodedImageCache。对于没有loaderHandler处理的url的图片, 会先从cache中查找,否则就从网络下载。

阅读全文 »

react-native: 0.49.3

推广RN之后, 经常收到Bugly指派过来的bug, 只是因为调用栈中包含了RN的一个符号 RCTFBQuickPerformanceLoggerConfigureHooks。

看了一下代码, RCTFBQuickPerformanceLoggerConfigureHooks这个函数是个空函数, 没有任何实现。

1
2
3
4
5
6
7
8
9
// RCTBridget.m

void RCTFBQuickPerformanceLoggerConfigureHooks(__unused JSGlobalContextRef ctx) { }


// RCTBridge+Private.h

RCT_EXTERN __attribute__((weak)) void RCTFBQuickPerformanceLoggerConfigureHooks(JSGlobalContextRef ctx);

在头文件中, 通过 attribute((weak)) 修饰了函数声明。

将本模块的RCTFBQuickPerformanceLoggerConfigureHooks转成弱符号类型,如果遇到强符号类型(即外部模块定义了RCTFBQuickPerformanceLoggerConfigureHooks),那么我们在本模块执行的RCTFBQuickPerformanceLoggerConfigureHooks将会是外部模块定义的RCTFBQuickPerformanceLoggerConfigureHooks。

如果外部模块没有定义,那么,将会调用这个弱符号,也就是在本地定义的RCTFBQuickPerformanceLoggerConfigureHooks

相当于增加了一个默认函数。

原理:链接器发现同时存在弱符号和强符号,优先选择强符号,如果发现不存在强符号,只存在弱符号,则选择弱符号。如果都不存在:静态链接,恭喜,编译时报错,动态链接:对不起,系统无法启动。

我们通过machoView可以看到即使是release的二进制文件, 符号中也存在RCTFBQuickPerformanceLoggerConfigureHooks这个符号。

堆栈符号化是根据地址相离最近的符号来解析的, 在没有上传符号表时,许多堆栈都会解析成 RCTFBQuickPerformanceLoggerConfigureHooks + 偏移地址。无形中加大了RN维护人员的问题定位的时间成本。

删掉这个RCTFBQuickPerformanceLoggerConfigureHooks函数的声明与实现。从此,再没有bug来骚扰。

另外,最新版本的react-native已经删除RCTFBQuickPerformanceLoggerConfigureHooks的实现了。
github删除该段代码的记录:
https://github.com/facebook/react-native/commit/c49d3653ef35bb3b932055027af0c0a6bab91d84#diff-3694567fdb59b754cc845377d26f6ee2

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

做RN开发,需要fork一份官网的库,来做一些修修改改以满足业务需求。同样的, 在开发中也需要fork一些库,然后就修改。在源库不断演进之后,我们需要同步自身库的代码。 就需要进行代码同步了。

阅读全文 »

CocoaLumberJack是一个用于mac或者iOS的日志库,简单易用, 可扩展。

可以通过设置Logger,分别把日志写入文件、终端、系统日志中。

DDLogLevel 7个等级

库不大,代码结构比较清晰。

阅读全文 »

我们在install一些库的时候, 可能会看到一些提示, 表明这个js库已经废弃了, 让大家去用xx库的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14

0524$ npm i jQuery
npm WARN deprecated jQuery@1.7.4: This is deprecated. Please use 'jquery' (all lowercase).
npm WARN saveError ENOENT: no such file or directory, open '/Volumes/Code/test/0524/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/Volumes/Code/test/0524/package.json'
npm WARN 0524 No description
npm WARN 0524 No repository field.
npm WARN 0524 No README data
npm WARN 0524 No license field.

+ jQuery@1.7.4
added 1 package from 1 contributor in 0.298s

阅读全文 »

终于开盘了

Hello EveryOne!

很久以前就萌生了要创建一个独立的个人博客,由于个人的懒惰,迟迟没有付诸实现。在此之前, 在QQ空间、百度空间、chinaUnix博客、简书上零零散散的发布着文章, 终了感觉还是需要一个属于自己搭建的专业的博客,经过漫长的岁月,近期终于铆足了劲,花了些时间在github上搭建好博客了。同时也创建了自己的个人公众号。从此就有一个发布个人博文的小天地了,不再流浪。

ChinaUnix博客地址: http://blog.chinaunix.net/uid/24459558.html

简书地址: https://www.jianshu.com/u/1eaa68a7efc1

开篇是一个立Flag的时机, 嗯, 这个博客用来记录分享个人技术生涯的一些学习总结、经验分享以及想法杂谈,欢迎拍砖。

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei (IT攻城狮小明),欢迎沟通交流。