- 博客(21)
- 资源 (1)
- 收藏
- 关注
原创 FreeRTOS_vTaskDelayUntil
笔者在音频项目上使用`vTaskDelayUntil`函数时遇到一个奇怪的现象,就是vTaskDelayUntil绝对延时不精准。
2022-08-26 11:05:09
560
1
原创 FreeRTOS堆栈溢出检查
RTOS任务都需要分配堆栈,堆栈大小不合理,会造成内存越界或者资源的浪费。如果在没有把握堆栈大小,尽量将堆栈往大的方向设置,这样能保证任务堆栈上下文切换不会溢出。
2022-08-26 11:01:45
3111
原创 【Fatfs】f_close返回FR_DISK_ERR
项目涉及到数据存储,由于时间比较赶,采用Fatfs文件系统,直接通过STM32CubeMX生成代码。在补全Fatfs底层I/O接口之后,测试读写数据是否正常。结果出乎意料,第一次f_open文件是成功的,第二次f_open直接返回FR_LOCKED。经过很久的排查,才发现第一次f_close返回了FR_DISK_ERR。简单来说,我们实际移植出错,大多还是我们的底层有问题。Fatfs官方上层代码肯定经过测试才发布,因此,我们只需要检测底层接口哪里出问题。
2019-10-08 09:44:38
4034
1
原创 【物联网-设备端】移植阿里云物联网SDK中iotkit至STM32平台
移植环境: 开发包或平台 版本或要求 链接 Link Kit SDK(阿里云物联网设备端C-SDK) iotkit-embedded-2.3.0.zip https://help.aliyun.com/document_detail/96623.html?spm=a2c4g.111...
2019-03-07 10:23:49
5608
4
原创 【LwIP - UDP】- 实现UDP通信
目录 基于LwIP实现UDP通信1 什么是UDP2 基于raw/callback API的UDP3 raw/callback API UDP的绑定、连接和发送基于LwIP实现UDP通信1 什么是UDPUDP,即用户数据包协议,属于TCP/IP 中的传输层。同样,TCP,即传输控制协议,也是属于TCP/IP传输层。这两者区别在此处不加以解释,本文主要讲解如何通过LwI...
2018-09-10 14:47:24
14226
转载 【LwIP - 网络五层模型】 - 一张图了解TCP/IP五层网络模型
转载:https://blog.csdn.net/u012909091/article/details/62888061计算机网络有OSI七层模型和TCP/IP五层模型两种,七层模型在应用层和传输层之间多了表示层和会话层,有兴趣的可以去了解一下。下面是我在学习TCP/IP五层网络协议的时候画的一张图,通过这张图就可以简单的了解这五层网络模型的层级划分,并且不同层根据它的职责产生了不同的协议。上...
2018-09-10 10:09:07
803
原创 【LwIP - UDP】 - udp_bind和udp_connect分析
目录前言1 udp_bind2 udp_connect 前言udp_bind和udp_connect两者具体的工作原理,笔者在网上找不到正确的说法。对此,笔者主要对UDP中的这两个接口进行分析。1 udp_bindudp_bind将一个UDP PCB与IP和端口进行绑定。当然不是简简单单的把该IP和端口记录到UDP PCB中。会做如下的操作:(1) 判断UD...
2018-09-07 16:53:27
4959
1
转载 路由转发过程的IP及MAC地址变化
A-----(B1-B2)-----(C1-C2)-------E就假设拓扑图是这个样子吧,B1和B2是路由器B上的两个接口,C1和C2是路由器C上的两个接口,A和E是PC,由主机A向主机E发送数据包,那么在主机A形成的数据包的目的IP就是E的IP,源IP就是主机A的IP地址,目标MAC地址就是B1的MAC地址,源MAC地址就是A的MAC地址由A发给路由器B,B经过重封装后,源IP和目标IP是...
2018-09-06 14:53:39
8247
原创 【LwIP-移植(NO_SYS)】- 工程添加LwIP源码(一)
工程添加LwIP源码源码版本:lwip-1.4.1、STM32F107_ETH_LwIP_V1.0.0硬件平台:STM32F103xxIDE: MDK KEIL51 前言写LwIP移植的文章主要记录个人的移植技巧和思路。有一段时间看了大量的LwIP的移植教程和博客,都没有很好地阐明移植的思路和方法,让初学者无法完全的掌握移植技巧,同时导致一大部分初学者对移植...
2018-08-22 14:05:27
5445
1
原创 【LwIP移植】 - 简介
简介LWIP是瑞典计算机科学院(SICS)的Adam Dunkels等开发的一个小型开源的TCP/IP协议栈。LWIP 是轻量级 IP 协议,有无操作系统的支持都可以运行,LWIP 实现的重点是在保持 TCP 协议主要功能的基础上减少对 RAM 的占用,它只需十几 KB 的 RAM 和 40K 左右的 ROM 就可以运行,这使 LWIP 协议栈适合在低端的嵌入式系统中使用特点 ...
2018-08-21 17:31:48
1446
原创 【嵌入式Linux驱动程序-进程间通信】-完成量
完成量1 完成量概述很多情况下,我们需要让某一个线程等待另一个线程执行完某个操作后,才能继续执行后续操作。Linux内核中提供完成量这种机制可实现这个同步过程。当然,信号量也是可以完成同步操作。但是完成量比信号量效率更高。此处引用《Linux设备驱动程序第三版》的一段程序,如下:struct semaphore sem;init_MUTEX_LOCKED(&sem);st...
2018-08-17 14:57:34
390
原创 【嵌入式Linux驱动程序-进程间通信】- 信号量 1
信号量1 信号量的简述信号量是Linux内核保护临界资源的一种方式。在FreeRTOS等嵌入式系统中的信号量可能会分为互斥信号量或者计数信号量。Linux内核中的信号量也可分为这两种,但是大多情况下,信号量作为互斥锁方式来时用。Linux内核中的信号量只有当得到信号量的进程时才能够进入临界区,执行临界代码。当一个信号量试图去获取一个已经上锁的信号量(即该信号量已经被其他进行占用了)时,进程...
2018-08-16 15:10:41
320
原创 【嵌入式Linux驱动程序-基础篇】- tasklets机制
Tasklets机制tasklet在某些方面类似于内核定时器,它们一直在中断时间运行,它们一直运行在调度它们的同一个CPU上,并且它们接收到一个unsigned long参数。不像内核定时器,我们无法请求在一个指定的时间执行函数,需要通过调度tasklet,当我们简单的调用调度后,内核将在一个适当的时间去执行。这个行为对于中断处理特别有用,即“上下半部(前后半部)”。实际上,一个tasklet...
2018-08-15 15:07:31
288
原创 【嵌入式Linux驱动程序-基础篇】- 前和后半部
前和后半部实际开发中,我们常常会面对一个问题:中断处理应当如何去处理一个较长时间的任务。我们都知道,中断处理不能被阻塞过长时间,不然就影响中断的效率。既要保证工作量大,又要保证中断速度快,确实是很难解决的难题。因此,内核开发者就通过前和后半部的方法来解决这难题。内核开发者将中断分为2部分处理,前半部分实际响应中断的入口,即我们request_irq注册时所传递的中断处理函数。后半部则是前半...
2018-08-15 10:52:15
283
原创 【嵌入式Linux驱动程序-基础篇】- 中断处理
中断处理1 中断的请求和释放当设备需要中断功能时,应当向内核请求中断。如果驱动工程师没有通过请求中断的方式通知Linux内核需要使用中断,那么内核只会简单的应答并且忽略该中断。 1.1 请求中断线请求中断线可以使内核知道外设应该使用哪一个中断号,哪一个中断处理函数。请求中断线在需要与外部设备交互时发生。Linux内核提供了request_irq()函数请求中断线。该函数如下:...
2018-08-14 17:13:35
1192
原创 【嵌入式Linux驱动程序-基础篇】- 混杂设备
混杂设备在设备号比较紧张的情况下,我们可以采用混杂设备,可用将一些之间没有联系的设备使用同一个主设备号,而使用不同的次设备号。主设备号通常为10。混杂设备使用miscdevice结构体来表示,如下所示:struct miscdevice{ int minor; // 次设备号 const char *name; ...
2018-08-14 11:05:59
511
原创 【嵌入式Linux驱动程序-基础篇】- 驱动与硬件层间的通信
驱动与硬件层间的通信1 IO端口和IO内存目前大多数处理器外设都是通过读写寄存器操作芯片外设,这些寄存器处于内存地址或者I/O地址上。从硬件角度考虑,内存和IO区域没有概念上的区别,均是通过地址总线、数据总线和控制总线(读写信号)来进行读写操作。并非所有处理器厂商将IO端口和IO内存给予独立的地址空间,但有些厂商认为IO端口属于外设,有别于内存,需要将两者的地址区别开来。inter处理...
2018-08-13 11:22:55
1478
原创 Linux Shell - 语法
Shell 语法1 变量 在shell中,使用变量之前不需要事先声明的。在默认情况下,所有变量都被看作字符串并以字符串来存储,即使它们被赋值为数值时也是如此。shell和一些工具程序会在需要时把数值型字符串转换为对应的数值以对它们进行操作。Linux是一个区分大小写的系统。 在shell中,你可以通过在变量名前加一个$符号来访问它的内容。赋值的时候,只需要通过变量名。一种检查变...
2018-08-09 11:07:41
303
原创 【嵌入式Linux驱动程序-基础篇】- 块设备
块设备驱动程序框架1 块设备加载过程 在块设备的模块加载函数中,需要完成一些重要的工作,这些工作涉及将在后面的内容中进行详解,本节的目的是为了给出一个整体的概念。块设备驱动加载模块中需要完成的工作如下图所示。 (1) 使用alloc_disk()函数分配通用磁盘gendisk结构。 (2) 通过register_blkdev()函数注册设备,该过程是一个可选的过程,也可...
2018-08-08 10:18:37
908
原创 【嵌入式Linux驱动程序-基础篇】 - FrameBuffer架构
FrameBuffer架构 Linux内核中,FrameBuferr设备驱动的源码主要分布在linux/include/fb.h和linux/drivers/video/fbmem.c,它们处于FrameBuffer驱动体系结构中的中间层,它为上层的用户程序提供系统调用接口,也为底层特定硬件驱动提供了接口。1 FrameBuffer驱动程序的实现 从应用程序角度看,其通...
2018-08-06 10:48:06
1427
原创 【嵌入式Linux驱动程序-基础篇】 - 驱动模块组成
驱动模块主要包含头文件、模块参数(可选)、模块功能函数(可选)、模块加载和卸载函数以及模块许可声明等。这些模块组成具体作用如下:1 头文件驱动程序与内核联系十分密切,因此其所需的大多函数声明以及宏定义均来自内核,需要根据实际使用需求从内核中加入所需的头文件。驱动模块中有个必须的头文件如下:#include <linux/module.h> // 包含了加载模块需要用到的符...
2018-07-20 14:11:35
781
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人