《Redis设计与实现》读书笔记(六) ——Redis中的压缩列表 (原创内容,转载请注明来源,谢谢) 一、概述 压缩列表(ziplist)是列表键(list)和哈希键(hash)底层的实现之一。当列表项较少,且每项要么是小的整数值,要么是长度比较短的字符串,则使用ziplist。当哈希的键值对较少,且每个键值对都是小整数或短字符串,也是使用ziplist。 二、压缩列表构成 压缩列表是redis为了节约内存开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构。每个压缩列表有多个节点(entry),节点
「Redis所有的数据结构都是在内存占用和执行效率之间找一个比较好的均衡点,不一味的节省内存,也不一味的提高执行效率」
压缩列表是 Redis 为了节约内存而开发的, 由一系列特殊编码的连续内存块组成的顺序型 (sequential) 数据结构.
本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I2C外设读取环境光强度传感器数据(BH1750)。
编译环境:我用的是(Keil)MDK4.7.2 stm32库版本:我用的是3.5.0 一、本文不对FLASH的基础知识做详细的介绍,不懂得地方请查阅有关资料。 对STM32 内部FLASH进行编程操作,需要遵循以下流程: FLASH解锁 清除相关标志位 擦除FLASH(先擦除后写入的原因是为了工业上制作方便,即物理实现方便) 写入FLASH 锁定FLASH 实例: #define FLASH_PAGE_SIZE ((uint16_t)0x400) //如果一页为1K大小 #define WRITE_START_ADDR ((uint32_t)0x08008000)//写入的起始地址 #define WRITE_END_ADDR ((uint32_t)0x0800C000)//结束地址 uint32_t EraseCounter = 0x00, Address = 0x00;//擦除计数,写入地址 uint32_t Data = 0x3210ABCD;//要写入的数据 uint32_t NbrOfPage = 0x00;//记录要擦除的页数 volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;/*FLASH擦除完成标志*/ void main() { /*解锁FLASH*/ FLASH_Unlock(); /*计算需要擦除FLASH页的个数 */ NbrOfPage = (WRITE_END_ADDR - WRITE_START_ADDR) / FLASH_PAGE_SIZE; /* 清除所有挂起标志位 */ FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); /* 擦除FLASH 页*/ for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter)); } /* 写入FLASH */ Address = WRITE_START_ADDR; while((Address < WRITE_END_ADDR) && (FLASHStatus == FLASH_COMPLETE)) { FLASHStatus = FLASH_ProgramWord(Address, Data); Address = Address + 4; } /* 锁定FLASH */ FLASH_Lock(); } 二、FLASH 擦除(以及防止误擦除程序代码) 1、擦除函数 FLASH_Status FLASH_ErasePage(u32 Page_Address)只要()里面的数是flash第xx页中对应的任何一个地址!就是擦除xx页全部内容! 防止误擦除有用程序代码的方法 方法一:首先要计算程序代码有多少,把FLASH存取地址设置在程序代码以外的地方,这样就不会破坏用户程序。原则上从0x0800 0000 + 0x1000 以后的FLASH空间都可以作为存储使用。如果代码量占了 0x3000, 那么存储在 0x0800 0000+ 0x4000 以后的空间就不会破坏程序了。 方法二:先在程序中定义一个const 类型的常量数组,并指定其存储位置(方便找到写入、读取位置),这样编译器就会分配你指定的空间将常量数组存入FLASH中。当你做擦除。读写操作时,只要在这个常量数组所在的地址范围就好。 const uint8_t table[10] __at(0x08010000) = {0x55} ; MDK3.03A开始就支持关键字 __at() 。 需要加#include <absacc.h> 方法三:在程序中定义一个const 类型的常量数组,无需指定其存储位置。只要定义一个32位的变量存储这个数组的FLASH区地址就行。 uint32_t address;//STM32的地址是32位的 const uint8_t imageBuffer[1024] = {0,1,2,3,4,5,6,7}; address = (uint32_t) imageBuffer;/*用强制类型转换的方式,可以把FLASH中存储的imageBuffer[1024]的地址读到RAM中的变量address 里,方便找到写入、读取位
本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I2C外设,读取SHT30温湿度传感器的数据并通过串口发送。
在上一节提到的图中,我们知道,可以通过 redisObject 对象的 type 和 encoding 属性。可以决定Redis 主要的底层数据结构:SDS、QuickList、ZipList、HashTable、IntSet、ZskipList 。
AT24C02的原理图如下(该原理图中有bug,A0的上拉电阻无效,实际A0为低电平):
本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用
[TEA(Tiny Encryption Algorithm) ](https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm)是一种简单高效的加密算法,以加密解密速度快,实现简单著称。算法真的很简单,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作为key,算法采用迭代的形式,推荐的迭代轮数是64轮,最少32轮。
TEA(Tiny Encryption Algorithm) 是一种简单高效的加密算法,以加密解密速度快,实现简单著称。算法真的很简单,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作为key,算法采用迭代的形式,推荐的迭代轮数是64轮,最少32轮。 TEA 算法最初是由剑桥计算机实验室的 David Wheeler 和 Roger Needham 在 1994 年设计的。该算法使用 128 位的密钥为 64 位的信息块进行加密,它需要进行 64 轮迭代,尽管作者认为 32 轮已经足够了。该算法使用了一个神秘常数δ作为倍数,它来源于黄金比率,以保证每一轮加密都不相同。但δ的精确值似乎并不重要,这里 TEA 把它定义为 δ=「(√5 - 1)231」(也就是程序中的 0×9E3779B9)。 下面是维基百科中个关于该算法的C语言描述的代码片段,如下:
假设现在我们要开发一个图片存储系统,要求这个系统能够根据图片 ID 快速查找到图片存储对象 ID。图片 ID 和图片存储对象 ID 的样例数据如下:
音视频传输的基石:RTP和RTCP。对于协议的讲解主要是是对于RFC文档的阅读和理解。不同的使用场景用到的字段也有所侧重,RTP和RTCP定义在RFC3550中。其中RTP用于数据流的传输;RTCP用于数据流的控制。可以说rtp/rtcp协议是即时通讯不可或缺的组成。RTCP协议介绍见:音视频协议-RTCP协议介绍
本章节为大家讲解RL-TCPnet的TCP多客户端实现,因为多客户端在实际项目中用到的地方还挺多,所以我们也专门开启一个章节做讲解。另外,学习本章节前,务必要优先学习第14章TCP客户端。学会创建一个TCP客户端了,创建多个客户端是一样的。
本文将从一个 Native Crash 分析入手,带大家了解我们平时开发中,那些容易忽略但又很值得学习的底层源码知识。
I²C(Inter-Integrated Circuit),常读作“I方C”,它是一种多主从架构串行通信总线。在1980年由飞利浦公司设计,用于让主板、嵌入式系统或手机连接低速周边设备。如今在嵌入式领域是非常常见通信协议,常用于MPU/MCU与外部设备连接通信、数据传输。
我正在尝试将byte []转换为字符串,将byte []的字符串表示形式转换为byte []的转换...我将byte []转换为要发送的字符串,然后我期望我的Web服务(用python编写)将数据直接回显给客户端。
PMSA003 是一款「基于激光散射原理的数字式通用颗粒物传感器」, 可连续采集并计算单位体积内空气中不同粒径的悬浮颗粒物个数,即颗粒物浓度分布,进而换算成为质量浓度,并以通用数字接口形式输出。本传感器可嵌入各种与空气中悬浮颗粒物浓度相关的仪器仪表或环境改善设备,为其提供及时准确的浓度数据。
传输控制/网际协议,又叫网络通信协议。实际上,它包含上百个功能的协议,如ICMP(互联网控制信息协议)、FTP(文件传输协议)、UDP(用户数据包协议)、ARP(地址解析协议)等。TCP负责发现传输的问题,一旦有问题就会发出重传信号,直到所有数据安全正确的传输到目的地。
不得不说,看了太多的人在各种地方讨论指针……越发看下去,越发觉得简单的事情被搞那么复杂,真是够了,求求你们,放开那个变量,让我来!
摘要:本文在探讨传统数据收发不足之后,介绍如何使用带FIFO的串口来减少接收中断次数,通过一种自定义通讯协议格式,给出帧打包方法;之后介绍一种特殊的串口数据发送方法,可在避免使用串口发送中断的情况下,提高系统的响应速度。
本文在探讨传统数据收发不足之后,介绍如何使用带FIFO的串口来减少接收中断次数,通过一种自定义通讯协议格式,给出帧打包方法;之后介绍一种特殊的串口数据发送方法,可在避免使用串口发送中断的情况下,提高系统的响应速度。
Redis(Remote Dictionary Server ),即远程字典服务,是一个使用 ANSI C 编写的开源、支持网络、基于内存、分布式、可选持久性的键值对(key-value) 数据库,与 Memcached 类似,却优于 Memcached。
概念 socket又称“套接字”,socket在应用层和传输层之间,我们的应用层只要将数据传递给socket就可以了,socket会传递给传输层、网络层等。 网络通信其实就是Socket之间的通信。
P35 、Solidity Types - 字符串(String Literals)
对于单片机开发者,调试工具就必不可少,有时需要显示波形、发送文本、数据和一些复杂的数据包。例如PID参数整定,然而四轴匿名上位都有这些功能。本文就介绍匿名四轴上位机怎么显示波形和调试,以及一些接收发送代码。
IPv4套接字地址结构 POSIX规范只要求3个字段:sin_family、sin_addr和sin_port。 #include <netinet/in.h> struct sockaddr_in { uint8_t sin_len; sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; ... }; 通用套接
在进行Modbus协议通信和网络编程时,有时需要将从串口或者网络中接收的数据从字节数组转换成对应的int,float,double等数据,有时还要考虑大小端字节序以及Swap的问题,发现在C++中需要自己写相关的转换函数,于是/写了一个函数,用于从输入的byte数组中获取指定类型的数据,目前支持int16,int32,int64,float,double,对应的代码如下:
总的来说,.NET的值类型和引用类型都映射一段连续的内存片段。不过对于值类型对象来说,这段内存只需要存储其字段成员,而对应引用类型对象,还需要存储额外的内容。就内存布局来说,引用类型有两个独特的存在,一个是字符串,另一个就是数组。我在《你知道.NET的字符串在内存中是如何存储的吗?》一文中对字符串的内存布局作了详细介绍,今天我们来聊聊数组类型的内存布局。
STM32读取SHT3x系列(SHT30、SHT31、SHT35)温湿度传感器的数据并显示在0.96寸OLED屏上。
作为后端开发,redis是工作中最绕不开的中间件之一,在工作中通常有以下几个常用用途:
前面几周我们一起看了Redis底层数据结构,如动态字符串SDS,双向链表Adlist,字典Dict,跳跃表,整数集合intset,如果有对Redis常见的类型或底层数据结构不明白的请看上面传送门。
Redis 中字符串都用自定义的结构**简单动态字符串(Simple Dynamic Strings,SDS),而不是C语言的字符串。 Redis 中使用到的字符串都是用 SDS,例如 key、string 类型的值、sorted set 的 member、hash 的 field 等等等等
前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用
本章节为大家讲解RL-TCPnet的TCP服务器实现,学习本章节前,务必要优先学习第12章TCP传输控制协议基础知识。有了这些基础知识之后,再搞本章节会有事半功倍的效果。
本章节为大家讲解RL-TCPnet的TCP客户端实现,学习本章节前,务必要优先学习第12章TCP传输控制协议基础知识。有了这些基础知识之后,再搞本章节会有事半功倍的效果。
面向过程开发,就像是总有人问你要后续的计划一样,下一步做什么,再下一步做什么,意外、事物中断、突发事件怎么做。理论上来说,任何一个过程都可以通过“顺序,循环,分支”来描述出来,但是实际上,很多项目的复杂度,都不是“顺序循环分支”几句话能说清楚的。稍微大一点的项目,多线程,几十件事情并发, 如果用这种最简单的描述方式,要么几乎无法使用,缺失细节太多,要么事无巨细,用最简单的描述,都会让后期复杂度提升到一个爆炸的状态。
由于前文《C/C++面向对象编程之封装》存在一些小错误或者难以理解的地方,Gorgon Meducer(傻孩子,PLOOC开源项目的作者)对此进行了修改和必要的补充,故将修正后的文章重新上传,若给大家带来不便请谅解。
ByteArray是字节数组的实现,顾名思义,该数组的元素大小的一个字节,不过类似js的Uint16Array,Uint32Array数组一样,我们可以把多个元素看做一个,把多个字节合并成一个元素看待。下面我们看一下实现。
HyperLogLog 是一种基数估算算法。所谓基数估算,就是估算在一批数据中,不重复元素的个数有多少。最常见的场景就是统计uv。首先要说明,HyperLogLog实际上不会存储每个元素的值,它使用的是概率算法,通过存储元素的hash值的第一个1的位置,来计算元素数量。这样做存在误差,不适合绝对准确计数的场景。redis中实现的HyperLogLog,只需要12K内存,在标准误差0.81%的前提下,能够统计2的64次方个数据。
RGB24格式图像输出颠倒可以使用以下方法转换过来。 实现 将数据强制转换为3字节(符合RGB24的数据排列方式); 使用std::reverse函数将每3字节数据从头到尾颠倒一次。 struct Rgb24Byte { uint8_t r; uint8_t g; uint8_t b; }; Rgb24Byte *rgb24Buf = (Rgb24Byte *)rgb24Data; std::reverse(rgb24Buf, rgb24Buf + bufSize); // 反转数
学习完《redis设计与实现》前面关于数据结构与对象的章节,以上问题都能得到解答。你也能了解到redis作者如此的煞费苦心设计了这么多丰富的数据结构,目的就是优化内存。学完这些内容,在使用redis的过程中,也会合理的使用以适应它内部的特点。当然新版本的redis支持了更多更丰富的特性,该书基于redis3版本,还没有涉及到那些内容。
完整代码参见gitee仓库:https://gitee.com/l0km/jimgutil/blob/master/native/src/rotate.cpp
ziplist中的每个entry都使用一个元数据作为前缀,该元数据包含两部分的信息:首先保存了前一个entry的长度,用于倒序查找;再者保存了entry的编码类型,表示entry的类型,如整数或字符串,当编码类型为字符串时,该字段也表示了字符串的长度。字符串的entry-data的长度就等同于该字符串的长度,而整数的entry-data的长度需要根据编码类型进行判断,并不一定等同于其entry-data字符串的长度(见下文encoding)。一个完整的entry为:
STM32使用硬件I2C读取SHTC3温湿度传感器的数据并显示在0.96寸OLED屏上
现在的Solidity中文文档,要么翻译的太烂,要么太旧,决定重新翻译下。 写在前面 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊、智能合约有所了解, 如果你还不了解,建议你先看以太坊是什么 Solidity教程会是一系列文章,本文是第一篇:介绍Solidity的变量类型。 本文前半部分是参考Solidity官方文档(当前最新版本:0.4.20)进行翻译,后半部分是结合实际合约代码实例说明类型的使用(仅针对专栏订阅用户)。 类型 Solidity是一种静态类型语言,意味着每个变量(
国庆中秋这些天没有回汕头,一直留在深圳家里,据说深圳回汕头300公里的路,老爸国庆中秋当天早上10点回去,开了20个小时才到家,也就是第二天才到,于是我就选择不回去了,白天带家人出去吃吃玩玩,晚上就在给客户开发和调试一款手持仪器,顺便把之前报考的MBA国际商务课老师布置的作业写完了;这个国庆中秋可谓过得相当充实,一点都没有浪费!简直棒!下面这幅图来自国庆中秋当前,显示8小时,但是大部分朋友都开了16个小时以上,国庆中秋在高速上度过。
STM32单片机使用软件IIC读取AM2320温湿度传感器的数据并显示在0.96寸OLED屏上。
领取专属 10元无门槛券
手把手带您无忧上云