- 博客(73)
- 资源 (1)
- 收藏
- 关注
原创 内联函数,用还是不用
内联函数和宏定义在作用上有一定的类似,但细节上还是有几点区别,所以具体用宏定义还是内联函数,看具体的需求是什么。内联函数有返回值。内联函数有参数检查。断点支持。内联函数支持打断点调试。方便外部进行调用,各模块需要用到的时候包含对应头文件即可,而不需要重复定义。值得注意的是,内联函数前面通常还会有static关键字进行修饰,这样的好处是限定了内联函数的作用域,因为内联并不是总会展开的,如果没有展开,且没有static修饰,则会出现重复定义的错误。
2023-10-30 17:23:31
162
原创 container_of解析及应用
container_of是一个C语言中比较少见,但实际在Linux kernel和zephyr rtos中都经常用到的宏。它的作用是通过结构体成员的指针获取整个结构体的指针。通常用于实现一些数据结构或者在底层编程中进行指针操作。是C编译器的内置宏。它是GCC编译器提供的一个特殊宏,用于计算结构体成员的偏移量。
2023-10-25 12:04:00
485
原创 优雅的c语言宏定义比较大小
写一个宏定义,返回两个数中较大的一个。相信绝大部分同学都能闭着眼睛写出来,但闭着眼睛写的真的对吗,怎么样写可以做到极致的优雅,适用几乎所有应用场景。
2023-10-25 11:58:46
1975
1
原创 zephyr核心数据结构 - struct device
struct device 的zephyr中的地位相当于linux中的 struct file_operations .在linux中,奉行一切皆文件的思想;而在zephyr中,与linux相似,奉行一切皆设备的思想。
2023-10-24 17:16:13
371
原创 基于zephyr-rtos创建自己的应用程序(树外创建)(草稿)
若要将zephyr-rtos应用在自己的项目中,不在zephyr树内增加自己的代码是非常推荐的。原因是zephyr目前功能虽然已经很强大,但该项目仍然在持续更新中,如果以后想要切换zephyr版本,而树内还有自己的代码,将会是一件头疼的事情。本文将介绍如何在树外创建自己的应用程序,并无差别使用zephyr提供的各种库和api。
2023-10-16 18:44:23
189
原创 在uboot中运行imx6ull裸机程序
在学习嵌入式Linux之前,还是有必要了解一下嵌入式处理器的裸机程序。但一些教程中提供的裸机程序烧写方法都相对比较复杂,有些需要使用sd卡烧写,烧钱前还要格式化SD卡,然后再给裸机程序加入头部信息,用专用的下载上位机烧写。其实裸机程序在我们学习嵌入式的过程中只是一个引导作用,用来了解这些处理器是如何工作的,因此编写好裸机程序后其实没必要真正地烧写到系统里面,只需要等让它运行,观察实验现象即可。...
2020-05-04 15:17:58
1228
2
原创 [学习分享]嵌入式linux字符驱动详解(四)设备树及设备树下驱动的编写
Linux从3.x版本开始支持设备树,关于设备树的由来以及设备树语法等可以查阅网上资料,有详细的描述,这里只简单地修改一下设备树内容,让内核访问设备树,然后驱动程序从设备树中获取描述信息进行驱动程序的编写。上一篇文章中,我们是通过直接在驱动程序中写死寄存器的地址来实现led的驱动,如果更换一个开发板,使用的GPIO引脚不同,那么这个驱动程序又将无法使用。本篇将介绍把这么硬件描述信息放到设备树中,通...
2020-05-04 14:58:08
684
原创 [学习分享]嵌入式linux字符驱动详解(三)
前面第一篇文章开头中提到过,一个led灯的驱动程序无非就是配置一下GPIO寄存器,让它具有输出功能,同时提供数据寄存器给用户来操作实现对led灯的控制。前面我们做的所有工作都是在搭建一个Linux驱动框架,现在框架搭建好了,我们只需要在这个框架的基础上添加少量的代码即可完成一个真正的led驱动。我用的处理器是i.mx6ull,板上载的led灯使用的是GPIO1_IO04。通过查找芯片手册,找到...
2020-05-03 22:39:15
375
原创 [学习分享]嵌入式linux字符驱动详解(二)
接着上一篇文章的内容,继续编写我们的led驱动程序。通过上一篇文章的实验,我们知道内核在加载模块驱动时,会进入的函数是module_init()里面指定的函数,我们称之为入口函数,因此,要向内核注册设备,肯定要在入口函数处完成。...
2020-05-03 21:16:09
435
1
原创 [学习分享]嵌入式linux字符驱动详解(一)
只不过Linux是个庞大的操作系统,提供了标准的驱动程序模板,供我们参考如何把我们的驱动加入到Linux里面,然后应用程序或者称用户程序,就可以使用标准的Linux操作方法来操作led灯(open、read、write等)。编写Linux设备驱动,可以理解为是把设备描述成文件的一个过程。但此时,我们并没有做任何处理,查看根文件目录下的dev文件夹也没有对应的设备,这是因为我们只是编写了驱动的出入口函数,没有向内核注册一个真正的设备(文件),下一节将描述如何在驱动程序中向内核注册一个设备。
2020-05-03 18:32:34
1556
1
原创 AT指令发送网络数据的两种方式比较
使用联网模块进行应用程序开发中,比较常使用到的联网模块,如4G模块,Wi-Fi模块等,使用AT指令方式发送数据时,查看数据手册,发现一般都支持两种数据发送方式。 1:指定数据长度。AT+CIPSEND=0,n。其中n代表本次发送的数据长度。 2:不指定数据长度。AT+CIPSEND=0, 发送该指令后等待模块返回 “>”字符,再发送数据,并在数据发送完成后,发送<...
2020-02-21 15:11:03
12788
原创 浅谈STM32在应用中编程(IAP)的应用(俗称在线更新程序)
STM32等单片机是可编程处理器,内部运行着我们编写的程序,而把我们编写的程序“下载”到单片机中,方法有两种:一、使用烧写器,如jlink,stlink,串口下载(需要配置boot0,boot1)。二、通过IAP实现一个在线更新功能。 对于很多使用单片机作为主要处理器的电子产品,如遇到需要替换芯片内部程序以满足需求的情况,通常的解决办法是寄回该产品然后通过烧写器直接替换程序...
2020-01-21 11:04:11
6146
2
原创 浅谈UCOSIII任务管理
UCOSIII是一个广泛应用于嵌入式设备的小型嵌入式实时操作系统,小巧而具备操作系统的特性,可以说是麻雀虽小五脏俱全。 对于单核处理器,在任何时刻,都控制器只能处理一个任务。这样的特性明显是不能满足各种设备的需求的,必须用多线程才能设计出一个比较好的作品。为了使处理器能实现处理不同任务的能力,在硬件上,MCU引入了中断的方式,有多种中断方式,如定时器中断,串口中断,外部中断等。但...
2019-12-13 15:13:03
370
原创 基于51单片机+12864中文液晶+GSM的智能家居报警系统
一个经典的单片机课程设计。主要用到的模块和资源有:LCD12864中文液晶模块,at24c02存储器模块用于存用户密码,ds18b20温度传感器模块,ISD1802语音模块用于语音报警,红外接收探头,用于接收红外键盘的信息、矩阵键盘4*4、红外势热,用于检测人体,GSM模块用于发送报警短信或者拨打用户手机等。IO口输入输出、串口发送。编译环境:Uv4 for c51主要的文件有:...
2019-12-13 15:09:37
1182
5
原创 浅谈链表对stm32程序的提升作用(C语言)
当然,链表也并不是完全优于数组的,链表的访问只能从头节点开始,而数组的访问,可以直接使用下标,结合一定的算法,如二分排序法等,使用数组的方法的查找效率就高于链表的方法,具体如何选择,需要看实际的应用场景。3,当学生数量比较大时,遇到删除信息的操作,程序的处理效率非常低,处理方法通常是,找个需要删除的信息的存放位置,然后把后面的信息逐步往前覆盖,如果删除的是最后一个,则设置为0,从而达到删除的目的。但这样的做法存在很多方面的问题,当一个数组被创建时,其在内存中的大小就已经被固定了,所以,
2019-06-22 11:47:33
3130
1
原创 浅谈算法与数学对程序效率的作用
程序的效率可以分为空间和时间两个方面。空间表现在一个程序所占的代码空间大小,即ROM或FLASH空间(虽然大多数情况下这个无关紧要可以忽略,因为运行程序的设备的ROM空间一般都足够大)和所占的内存空间大小,即RAM空间。时间则表现在运行完一段程序所消耗的时间,这个时间与处理器的运行速度有关,同样的程序在不同的设备运行的时间可能是不一样的。程序使用的运算方式也有关系,比如在部分处理器或单片机中,对于...
2019-04-21 23:09:48
1001
1
原创 用DMA实现printf
printf作为标准库常用的一个函数,应用在嵌入式系统里,只需要将fputc函数重定向到串口,就可以使用printf进行格式化打印了。但在嵌入式系统中,printf是一个相对比较占资源的函数,特别是stm32这种主频不高的处理器,调试过程中如果过多地使用printf甚至会影响程序本来的结果。stm32有DMA这种好东西,把程序运行过程中的调试信息通过DMA的方式打印出来,无疑提高了程序运行...
2017-05-27 15:28:11
9696
10
原创 串口中断结合定时器实现稳定可靠的串口接收
串口的接收方式可以有很多种,之前也提到过使用延时判断串口接收指正的值是否改变来进行接收完成的判断。也介绍过使用DMA的空闲中断触发以判断串口接收完成。以上两种方式,在一定情况下可以使用效果也还可以。延时判断的方式,对于不跑操作系统的工程里影响不大,但是到了一个跑实时系统的工程里,这种方式就显得不稳定了。而DMA方式接收,效率很高而且不占用处理器时间,但是这样接收就是太快了,在数据频繁发送的情况下,
2017-04-17 17:18:18
11419
2
原创 使用memmove对数组中的指定内容进行删除操作
#include #include #include using namespace std;int main(){ int i,len,cnt; unsigned short t; char *p,*p_end; char buffer[200]; char s[256]="使用memmove函数对数组中指定的内容进行删除操作"; char *q=s;
2017-04-17 16:45:56
1519
1
原创 串口+DMA+空闲中断实现接收不定长数据
记录一下串口dma的使用,dma的好处在于他的传输是不需要经过CPU的,可以实现内存和外设的直接双向通信。合理使用dma能使程序设计变得简单。以串口3为实例介绍一下串口dma的配置过程,其他串口也是一样的,只需要修改一下dma的通道。 首先串口的配置过程与常规的配置基本一致,不过说明一点就是,如果使用dma接收不定长数据的话,比较常用的一种方法是利用空闲中断。所以在配置的时候就不要使能RXN
2017-01-28 16:42:37
9355
1
原创 STM32 特殊功能脚设置为普通脚的方法
一个项目中用到了STM32中的PB3,使用的时候发现这个脚不受控制,查看手册发现这是个特殊功能引脚。PB3 和PB4 分别是JTAG的JTDO和NJTRST脚,在默认情况下,STM都是把他们复用为特殊功能脚,在没有关闭JTAG功能之前,这连个脚不受GPIO的ODR寄存器控制。 要把他们配置为普通的引脚,需要禁止他们的复用功能。库函数是GPIO_PinRemapConfig(GPIO
2016-12-06 13:36:46
5758
3
原创 STM32 IIC通信简介+PCF8563时钟芯片示例
IIC总线是嵌入式设备最常用的接口之一,包括51单片机在内的MCU一般都可以进行IIC通信。IIC通信有3种类型的信号:开始信号,结束信号,和应答信号。开始信号:SCL为高电平,SDA由高电平向低电平跳变,表示可以开始传输信号,进行通信了。结束信号:SCL为高电平,SDA由低电平向高电平跳变,表示传输信号的时间已经过了。应答信号:接收数据的IC在接收到8bit数据后,向发送数据的I
2016-09-01 15:06:29
29994
7
原创 STM32 RS485通信
RS485是主流的一种多机通信方式,多用于不同设备间的数据传送。最常见的是主控板和485接口的传感器间的通信。下面介绍常用的通信方式及代码,包括常用的CRC校验。初始化代码:(初始化控制引脚(收发)和对应串口(看硬件连接))//bound:波特率 void RS485_Init(u32 bound){ GPIO_InitTypeDef GPIO_InitStru
2016-07-27 22:34:00
20440
1
原创 搜索算法入门
本文将讨论一个简单的搜索算法:深度优先搜索DFSDFS的思想可以概括为:选择一个方向,一直往前走,直到无路可走。再回到有其他路可走的结点,重复上述步骤 ,直到回到出发点。实际上就是一个递归的思想。先来看一个递归求阶乘的例子。f(n)=n!,f(n)=n*f(n-1);...可以看成为从n开始,不断减1遍历,直到n变为1(递归结束点,也就是这条路已经无路可走了)。虽然这个例子只有一条
2016-02-18 18:02:01
645
原创 图书管理系统
控制台界面的图书管理系统:程序分为两块:管理员操作(收录图书、删除图书等)和会员操作(注册、借书、还书等);2019.12.16更新:上传了程序文件,工程可直接用DEV-CPP打开。下载地址://download.youkuaiyun.com/download/u013053268/12034863------------------------------------------------...
2016-01-06 14:21:20
19603
8
原创 stm32+neo6m GPS模块定位系统
开发平台:主处理器是意法半导体的stm32f103系列,这款芯片应用广泛,并且资料很多。主要定位模块:ublox的一款芯片开发环境:MDK5.0主要代码还是参考原子的历程,在它的基础上实现了只提取经纬度,海拔等操作硬件连接:3.3V电源给GPS模块供电,stm32串口2接GPS。软件实现主要流程:stm32串口初始化,模块初始化,设置更新速率,保存配置,串口2接收消息,对接收到
2015-12-09 17:20:49
20012
19
原创 Windows 批量删除文件简单方法
在windows环境下批量处理文件,可以新建一个批处理文件(新建一个txt文件后把后缀名改为bat,如:new.txt --> new.bat)点击右键,编辑(或用记事本打开)在文本里面输入del *(要删除的文件类型) /s可以输入多个文件类型,如:del *.txt /s del *.rar /sdel *.dsw /s等。注意*号后面有一个点(英文
2015-12-09 14:27:50
14106
原创 归并排序
#includeusing namespace std;const int N = 20;void Merge(int *ins,int *tmp,int startIndex,int midIndex,int endIndex){ int i = startIndex, j=midIndex+1, k = startIndex; while(i!=midIndex+1 && j!
2015-12-06 16:16:51
391
原创 快速排序算法
算法思想:对待排数组按某一数分成两个数组步骤:找一个基准元素,这个元素可以是数组里的任意一个数在待排数组里遍历,把所有比基准小的放在左半数组,大的放在右半数组,这个操作结束以后,这个基准元素处于中间位置(基准归位)递归的把左半部分数组排列和半右半部分数组排列平均时间复杂度:O(nlogn)代码如下:#includeusing namespace std;const
2015-12-06 15:41:43
487
原创 stm32串口间通信
最近要写个串口间通信的程序,要求PC端输入消息到串口1,然后stm32内部把该消息通过串口2转发出去,串口2得到消息返回,则通过串口1打印在PC端。实际上总体效果就是要是连接了设备的串口2具有串口1的功能,以便观察设备返回的信息以作后续的处理。使用的芯片是stm32l151,采用中断接收方式,把串口2所收到的消息全部打印出来。一开始直接参考原子的程序以接收回车键判断接收一次数据结束,实际上
2015-12-06 13:42:36
4389
原创 STM32l151低功耗芯片串口通信(HAL库)
参考原子的stm32F1系列的串口通信实验,移植到stm32L1系列的程序代码。1、采用串口中断方式,串口接收到消息产生中断,因此需要使能RXNE寄存器。HAL库函数的调用方式是__HAL_UART_ENABLE_IT(&UartHandle1, UART_IT_RXNE); UartHandle1是UART_HandleTypeDef类型,具体参考stm32lxx_ha...
2015-11-17 16:53:57
14812
1
转载 STL中的set容器的一点总结
原文出处:http://www.cnblogs.com/BeyondAnyTime/archive/2012/08/13/2636375.html1.关于setC++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作。vector封装数组,list封装
2015-09-11 10:39:44
490
book_mgmt_in_c.zip
2019-12-16
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人