1.正点原子嵌入式linux驱动开发——Linux C编程入门
2.正点原子嵌入式linux驱动开发——外置RTC芯片PCF8563
3.正点原子lwIP学习笔记——网络数据包管理
4.正点原子是正点干嘛的
5.正点原子FPGA连载第九章基于OV5640的字符叠加实验--领航者ZYNQ之HLS 开发指南
6.正点原子lwIP学习笔记——ICMP协议
正点原子嵌入式linux驱动开发——Linux C编程入门
这一章主要利用Ubuntu自带的vi编辑器进行C语言代码编写。对原理不感兴趣的原源源码读者,可以自行搜索并使用VSCode等编辑器进行操作。码正
首先,点原创建一个名为"C_Program"的正点文件夹,用于管理所有代码。原源源码mui手机app源码每次编写的码正代码放在"C_Program"文件夹下的子文件夹中,便于管理。点原
在"/etc/vim/vimrc"文件中,正点设置tab为4个空格,原源源码并启用行号显示,码正通过在文件最后两行添加相应的点原代码实现。
设置完成后的正点vi编辑器,用于编写经典代码"Hello World!"。原源源码创建名为"main.c"的码正文件,内容如下:
使用"cat"命令查看内容,如图所示。
进行代码编译。Ubuntu下的C语言编译器为GCC,若Ubuntu未安装GCC工具,需手动安装gcc、g++和make等工具。通过安装"build-essential"软件包即可。安装完成后,使用命令查看,如图所示。
安装成功后,GCC编译器版本为7.5.0,适用于x架构CPU。对于ARM架构,需要使用针对ARM的GCC编译器,即交叉编译器。需记住不同架构下的GCC编译器不同。
使用GCC编译器编译"main.c"文件,GCC命令模式下输入命令,编译完成后生成可执行文件"a.out",使用命令"./a.out"执行,如图所示。
可自定义命名生成的可执行文件,在使用gcc命令时加上"-o"指定文件名,如编译"main.c"后生成名为"main"的cwmp源码可执行文件,操作如图所示。
GCC编译器命令格式如下,主要选项如下:
编写示例代码演示GCC错误警告,代码中有两处错误:在第8行少写了一个分号;第9行中的printf语句错误。编译后,GCC会给出错误提示,根据提示修改代码即可。
GCC编译流程包括预处理、编译、汇编和链接,预处理展开头文件、替换宏、解析条件编译;编译将预处理后的代码编译成汇编代码;汇编将汇编语言编译成二进制目标文件;链接将多个目标文件链接成可执行文件。
使用make命令进行编译,通过一个Makefile文件描述编译哪些源码文件、如何编译。Makefile跟脚本文件类似,执行系统命令,使用make命令即可自动完成工程编译,提高开发效率。在Linux下使用最多的GCC编译器,需要自行编写Makefile。
创建名为"Makefile"的文件,描述工程中需要编译的源码文件和依赖关系。在命令行输入"make"即可编译工程,可能遇到编译失败的情况。修改Makefile,确保在修改文件后能正确编译。Makefile中规则描述目标文件及其依赖文件,命令执行更新。
总结,Makefile中规则定义目标文件及其依赖文件,命令执行更新。Makefile的"终极目标"是Makefile文件中第一个规则的目标,没有指定目标时,默认为目标。Makefile变量用于简化代码,变量赋值使用"="或"==","=="只使用已定义的值。模式规则用于编译所有以特定后缀结尾的miuilauncher源码文件,自动化变量用于简化命令执行。Makefile中的伪目标不生成文件,用于避免与实际文件冲突。Makefile支持条件判断和函数调用,实现逻辑控制和字符串处理。
本章节介绍了在Linux环境下使用GCC和Makefile进行C语言代码的编译和执行。学习后可直接进行实践,实践过程中会更直观地理解操作流程。基础了解即可,具体应用需在实践中深入体会。
正点原子嵌入式linux驱动开发——外置RTC芯片PCF
学习正点原子STMMP开发板上的外置RTC芯片PCF驱动开发,首先了解PCF基本特性与结构。PCF是一个CMOS RTC芯片,具备时间、日历功能与可编程时钟输出、中断输出及低电压检测能力。它以两线式IIC接口进行数据传输,支持最大Kbit/S的传输速率,在读写寄存器时,地址会自动递增。其主要功能包括时钟输出、中断输出、低电压检测等。PCF的特性与结构如下:
PCF拥有个内部寄存器,全部为8位。前两个寄存器作为控制/状态寄存器,0x-0x寄存器保存时间与日期信息,0x-0x0C为闹钟寄存器,而0x0D为时钟输出频率寄存器,0x0E和0x0F为时钟控制寄存器。BCD格式用于存储时间与日期信息。
接下来,详细探讨PCF的寄存器结构与用途。控制状态寄存器1与2用于控制RTC的运行模式、停止状态与中断功能,而时间与日期寄存器则分别对应秒、分、时、日、星期、kilobot源码月与年。闹钟寄存器用于设定闹钟信息,时钟输出频率寄存器调整RTC的输出频率,时钟控制寄存器用于控制RTC的时钟输出。
此外,PCF支持中断功能,中断引脚与外部硬件相连接。Linux系统集成PCF驱动,因此在开发板上使用时,只需要在设备树中添加相应的配置信息,如IIC接口的引脚配置与中断引脚的定义。内核内部的驱动使得使用过程非常简单,只需通过修改设备树添加PCF节点信息,并使能内核中的PCF驱动即可。
硬件原理图显示PCF通过IIC接口连接到STMMP上,中断引脚连接到PI3,用于中断处理。在实验中,首先在设备树中配置IIC引脚与中断引脚信息,然后按照Linux内核提供的文档说明使用自带的PCF驱动。配置内核与设备树后,重新编译,启动开发板验证驱动功能。
测试结果显示系统可以识别PCF并提供时间信息,即使在开发板掉电后,纽扣电池仍能继续为RTC供电,确保时间的连续性。驱动源码分析揭示了核心功能在于初始化PCF并使用RTC驱动框架进行时间与闹钟的读写操作。
总结,通过设备树配置与Linux内核集成的驱动,使用PCFRTC芯片非常简便。对于IIC接口的RTC芯片驱动开发,基本思路相似,可根据实际项目需求选择合适的芯片。
正点原子lwIP学习笔记——网络数据包管理
TCP/IP作为一种数据通信机制,其协议栈的实现本质上是对数据包的处理。为了实现高效率的处理,lwIP数据包管理提供了一种高效的机制。协议栈各层能够灵活处理数据包,同时减少数据在各层间传递时的ray 源码时间和空间开销,这是提高协议栈工作效率的关键。在lwIP中,这种机制被称为pbuf。
用户的数据经过申请pbuf,拷贝到pbuf结构的内存堆中。在应用层,数据的前面加上应用层首部,在传输层加上传输层首部,最后在网络层加上网络层首部。
pbuf用于lwIP各层间数据传递,避免各层拷贝数据!
lwIP与标准TCP/IP协议栈的区别在于,lwIP是一种模糊分层的TCP/IP协议,大大提高了数据传输效率!
这是定义在pbuf.h中的关键结构体pbuf。通过指针next构建出了一个数据包的单向链表;payload指向的是现在这个结构体所存储的数据区域;tot_len是所有的数据长度,包括当前pbuf和后续所有pbuf;而len就是指当前pbuf的长度;type_internal有四种类型;ref代表当前pbuf被引用的次数。
右边展示的pbuf_layer就是用来首部地址偏移,用来对应相应的结构体。
PBUF_RAM采用内存堆,长度不定,一般用在传输数据;PBUF_POOL采用内存池,固定大小的内存块,所以分配速度快(一般字节,就是分配3个PBUF_POOL的内存池),一般用在中断服务中;PBUF_ROM和PBUF_REF都是内存池形式,而且只有pbuf没有数据区域,数据都是直接指向了内存区(PBUF_ROM指向ROM中,PBUF_REF指向RAM中)。
左边第一幅对应PBUF_RAM;中间两幅对应PBUF_POOL;最后一幅对应PBUF_ROM和PBUF_REF。
其中PBUF_RAM和PBUF_POOL相对更为常用。
更多的函数,都可以在pbuf.c和.h中找到。pbuf_alloc()如果是PBUF_REF或者是PBUF_ROM,就会如上图所示,创建一个结构体指针p,然后会进入pbuf_alloc_reference;该函数中,会申请一个pbuf结构体大小的内存;然后调用pbuf_init_alloced_pbuf进行初始化,初始化可以如上图所示。
如果是PBUF_POOL,会定义q和last两个pbuf结构体指针,q和last都初始化为NULL,rem_len(剩余长度)初始化为(用户指定需要构建的长度);然后q会经过内存申请,qlen则是去rem_len和当前可申请的数据大小(PBUF_POOL_BUFSIZE_ALIGNED - LWIP_MEM_ALIGN_SIZE(offset))取小值,然后同样经过pbuf_init_alloced_pbuf初始化q中的pbuf结构体;然后会把offset清零,就是说之后的pbuf都没有offset了,只有第一个链表的元素有offset;经过if判断并判断rem_len的大小,只要还有剩余就会回去循环继续执行上述操作,直到完成3个内存块的初始化。
首先会计算payload_len和alloc_len,如果是传输数据,那么LWIP_MEM_ALIGN_SIZE(offset)就是,计算得到payload_len=,alloc_len=;然后进入判断payload和alloc的长度是否
进入判断p是否为空,不为空证明还没有释放;进入while语句,每一次都--ref(引用次数);然后类似链表删除,调用相应的pbuf类型的内存释放(内存堆或者内存池),直到p全部被释放。源码如下:
这个就要看你使用的是什么类型,然后会根据类型来决定payload_len的大小,进行相应的payload指针指向数据区前的首部字段。
这一章主要讲述了lwIP中重要的pbuf缓冲,具体有哪些数据构成,为之后的学习奠定基础,确定了pbuf除了所需传输的数据,还有哪些变量需要添加,如何申请对应的pbuf内存大小,以及对应的内存堆和内存池。
正点原子是干嘛的
正点原子专注于嵌入式开发平台、智能开发工具、IoT物联网、仪器仪表以及企业服务的软硬件研发和销售。自年成立以来,这家公司已成为国内知名的嵌入式开发平台供应商,其产品不仅远销至东南亚、欧美等地,还被众多国内高校实验室和培训机构选为实验教学平台,为超过万名电子工程师提供服务。
作为嵌入式开发平台行业的领先者,正点原子推出的STM、Linux和FPGA等产品深受用户喜爱。公司拥有多项专利和著作权,并出版了包括《原子教你玩STM》、《例说STM》和《FreeRTOS源码详解与应用开发》在内的余本专业书籍。正点原子与北航出版社及意法半导体(STMicroelectronics)保持长期合作关系,意法半导体的曹锦东先生(ST中国区高级市场部经理)和彭祖年先生(ST华南区市场部经理)等业界专家曾莅临公司交流指导。
年,正点原子被评为国家高新技术企业,年荣获广州科技创新小巨人企业称号,标志着公司在技术创新和发展方面的成就。
正点原子FPGA连载第九章基于OV的字符叠加实验--领航者ZYNQ之HLS 开发指南
领航者ZYNQ的HLS开发教程中,我们详细介绍了基于OV的字符叠加实验。首先,实验目标是在视频图像上叠加字符,以实现监控系统中的实时信息显示。这个过程包括了从视频字符的概念理解,到使用PCtoLCD工具提取汉字“正点原子”的字模,以及如何通过HLS设计生成字符叠加的IP核。
在实验步骤中,我们演示了如何通过软件获取字符的点阵表示,通过配置字符格式,将四个汉字合并成一个大字模,并将其保存为BMP格式。接着,使用Vivado HLS工具创建工程,编写源代码,利用hls_video.h库进行字符叠加的逻辑实现。综合并导出IP核后,验证阶段将生成的IP添加到Block Design中,并连接至OV和VDMA模块,确保正确显示字符叠加后的图像。
在下载验证阶段,通过Vivado SDK将程序下载到领航者开发板,将字符叠加的IP应用到实际的摄像头监控系统中,最终在LCD屏幕上看到摄像头捕获的图像与字符叠加的效果。这个实验不仅锻炼了HLS编程技能,还展示了字符叠加技术在实际应用中的价值。
正点原子lwIP学习笔记——ICMP协议
ICMP协议是一个网络层协议。一个新搭建好的网络,通常需要先进行一个基本的测试,以验证网络是否畅通;但IP协议并不提供可靠传输。如果数据包丢失了,IP协议并不能通知传输层是否丢失以及丢失的原因。因此,我们需要ICMP协议来完成这样的功能。
总结来说,为了更有效地转发IP数据报和提高交付成功机会。
ICMP协议类型与结构:对于ICMP协议中的差错报告报文,在lwIP中实现的是目的不可达以及超时的报文;对于超时报文,又分为两种,一种是生存时间TTL(在IP首部中),另一种是分片传输中,接收到一个分片后的超时等待时间超时;ICMP协议中的询问报文,lwIP实现的则是回送请求/应答报文。
无论是差错还是询问报文,前4个字节是一样的:第一个是类型,第二个是代码,例如超时就是0/1,0代表生存时间为0、1则是超时等待时间为0;后两个是校验和;之后的4个字节则是取决于ICMP报文的类型;整个ICMP的数据部分,长度取决于类型;整个ICMP报文是在网络层,可以说IP数据包包含了IP首部以及ICMP报文。
ICMP差错报文用于检测IP数据报在传输过程中的异常信息(目的不可达、源站抑制、重定向、超时、参数错误)。
ICMP类型为3,则代表了是目的不可达;lwIP实现了代码值2、3、4的差错;ICMP类型为则代表了是超时错误;代码值0代表传输期间生存时间为0,1代表数据报组装期间生存时间为0。
ICMP查询报文用于诊断两个网络设备之间是否能够通信。
lwIP只处理ICMP类型0/8,代表了回显请求/应答;目的主机收到ICMP回送请求报文后立即回送应答报文,若源主机能收到ICMP回送应答报文,则说明到达该主机的网络正常(PING)。
ICMP报文数据结构:以上结构体位于icmp.h中;包括有ICMP的类型、代码、校验和、标志符以及序号五个变量。
差错报文中,前4个字节是类型、代码和校验后;后4个字节全为0;然后传输的数据就是因其差错的IP首部以及他的pbuf的前8个字节的数据;查询报文的前4个字节与差错报文一样;后4个字节中,2格式标识符,2个事序号;数据部分则是请求报文发送和应答报文重复(就是类型为8,就是回送请求,直接把类型改为0,变成回送应答)。
lwIP只实现目的不可达、超时差错报文,它们分别为icmp_dest_unreach和icmp_time_exceeded函数;这两种差错报文都是调用icmp_send_response发送;其源码和注释如下:
以上源码的逻辑,就是根据当前的type和code判断处理方式,判断得到是差错报文,就把被丢弃数据包的pbuf中的IP首部和前8个字节数据拷贝到差错报文中(同样也是一个pbuf)。
请求报文发送,应答报文重复。简单来讲,应答包是在请求包的基础上修改得来;查询报文的源码和注释如下:
总结来说,ICMP的回送请求,把ICMP结构体的type从8改成0,然后把pbuf的payload上移个字节,添加IP首部,就变成了回送应答包。
这一篇的源码还是比较简单易懂的,没有太多要F跳转的内容,总的原理也比较清晰。
至此,lwIP的大部分协议都学完了,还剩下TCP和UDP协议,现在的lwIP框架如下:
正点原子寄存器版本的程序源码文件夹介绍
正点原子寄存器版本程序源码文件夹详解
正点原子的开发资源提供了寄存器版本和库函数两种源码,鉴于其在嵌入式开发中的优势,我选择深入研究寄存器版本。该版本的源码虽然结构复杂,但更贴近硬件底层,便于理解和优化。
程序源码文件夹被精心组织,以模块化和层次结构划分,有助于降低复杂度和代码管理。四个主要的子文件夹分别是:
1. HARDWARE:这个文件夹主要用于配置实验时的片外设备,如LCD和BEEP,代码设计清晰易懂,有助于理解硬件接口操作。
2.
OBJ:包含编译后的.hex文件,是单片机可执行的程序,是程序开发过程中的重要产物。
3.
USER:存放Keil工程文件,这些文件与用户界面和自定义功能紧密相关。
4.
SYSMEER:是STMFX系列的核心驱动,由《原子教你玩stm》一书提及,对于快速搭建工程至关重要。其中的子文件夹如delay、sys、usart,详细记录了底层硬件操作和通信功能。
4.1 delay文件夹包含7个处理延时的函数,对于控制程序执行节奏很有帮助。
4.2 sys文件夹包含了系统相关功能,如sys.c处理寄存器定义和IO口操作,sys.h定义了IO口操作的宏,使得编写代码更加直观。
4.2.2 sys.c则负责配置系统时钟、IO口和中断,是系统初始化的核心部分。
4.3 usart文件夹涉及串口通信,usart.c提供了串口初始化和中断接收的函数,还支持串口printf功能,对通信功能的实现至关重要。
这些文件夹和文件的详细结构,为嵌入式开发人员提供了一个清晰的框架,使得代码调试和维护更加便捷。