嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读

技术阅读

  • 设备树下的 platform 驱动开发框架

    2024-07-07

    点击下方名片关注公众号1. 设备树下的platform驱动开发platform驱动框架分为总线、设备和驱动,其中总线是由Linux内核提供,在编写驱动时只要关注于设备和驱动的具体实现即可。一文中介绍了没有设备树的情况,需要分别编写并注册platform设备和platform驱动。而在使用设备树的时候,设备的描述被放到了设备树中,因此只需要实现platform_driver即可本文将介绍如何在设备树下编写platform驱动,编写框架如下图示:2. 程序编写2.1 修改设备树将设备的描述放到了设备树中,而无需单独编写和注册。步骤如下示:⏩ 添加pinctrl节点:在iomuxc节点的imx...

  • Linux 下的 platform 驱动开发模板

    2024-07-07

    点击下方名片关注公众号本文介绍如何使用platform驱动框架来编写一个LED灯驱动,采用自定义platform_device的方式来编写LED的设备信息。需要编写一个驱动模块(platform驱动程序)和一个设备模块(platform设备信息)。当这两个模块都加载成功后就会匹配成功,然后platform驱动模块中的probe函数就会执行1. platform设备程序编写platform设备信息框架如下图所示新建设备文件leddevice.c,并根据上面的框架图,编写设备信息程序/* 寄存器地址定义 */#define CCM_CCGR1_BASE (0X020C406C)#define SW_MUX_GPIO1_IO03_BASE (0X020E0068)#define ...

  • 用信号驱动I/O降低CPU使用率

    2024-07-07

    点击下方名片关注公众号信号类似于硬件上使用的"中断",只不过信号是软件层次上的,可以理解为软件层次上对中断的一种模拟,驱动通过主动向应用程序发送可访问的信号,应用程序获取到信号后即可从驱动设备中读取或写入数据了1. 驱动和应用中的信号处理驱动程序中需要定义fasync_struct结构体指针变量,一般在设备结构体中定义该变量,fasync_struct结构体原型如下:struct fasync_struct { spinlock_t fa_lock; int magic; int fa_fd; struct fasync_struct *fa_next; struct file *fa_file; struct rcu_head fa_rcu;};⏩ fasync...

  • 用非阻塞式I/O模型降低CPU使用率

    2024-07-07

    点击下方名片关注公众号若应用程序以非阻塞的方式读取,则驱动程序也要以非阻塞的方式返回,也就是轮询的方式。poll、epoll和select函数可以用于处理轮询,应用程序可通过这些函数来查询设备是否可以操作,如果可以操作的话就从设备读取或者向设备写入数据1. 驱动中的poll操作函数应用程序调用select、poll或epoll函数来对驱动程序进行非阻塞访问时,驱动程序中file_operations操作集中的poll函数就会执行。所以驱动程序中需要提供对应的poll函数,其原型如下所示:unsigned int (*poll) (struct file *filp, struct poll_table_struct *wai...

  • 浅析 Linux 五种IO模型

    2024-07-07

    点击下方名片关注公众号在Linux驱动开发中,应用程序通过循环读取或者中断的方式都会使得CPU的占用率很高。本文介绍五种IO模型,可以用来优化文件读写方式,降低CPU的使用率1. 阻塞式I/O模型阻塞式I/O模型是最常用、最简单的模型。当应用程序对设备驱动进行操作时,若不能获取到设备资源,阻塞式IO就会将应用程序对应的线程挂起,直到设备资源可以获取为止阻塞就是进程被休息, CPU处理其它进程去了。如下图,应用程序进行recefrom系统调用,操作系统收到recefrom系统调用请求,经过等待数据准备好和内核将数据从内核缓冲区复制到用户缓冲区这两个阶...

  • 用 Linux 内核中断检测按键输入

    2024-07-07

    点击下方名片关注公众号一文中介绍了基本的按键输入捕获流程,这里将进一步介绍如何使用中断的方式来驱动按键,同时通过定时器实现按键消抖功能,应用程序读取按键值并通过终端打印出来下面根据一文中介绍的内核中断使用模板,来进行代码的编写1. 修改设备树文件在Linux按键驱动的设备树key节点基础上,添加中断相关属性key { #address-cells = <1>; #size-cells = <1>; compatible = "andyxi-key"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_key>; key-gpio = <&gpio1 18 GPIO_ACTIVE_LOW>;  interrupt-parent =...

  • Linux下的按键输入驱动开发模板

    2024-07-07

    点击下方名片关注公众号之前的文章中,介绍了各种各样的花式点灯方法,其本质都是通过操作GPIO输出高低电平,控制灯的亮灭。按键驱动也是要操作GPIO,只不过是要读取GPIO的高低电平。在驱动程序中使用一个整形变量来表示按键值,应用程序通过read函数来读取按键值,判断按键有没有按下如下图示,本文中使用的开发板按键KEY0与芯片的UART1_CTS引脚相连接,并接了一个10K的上拉电阻,因此当按键没有按下时UART1_CTS是高电平,当按键按下后UART1_CTS就是低电平下图为基于pinctrl与gpio子系统的按键输入驱动模板,接下来根据此模板,进行代码的编写:1. ...

  • 如何使用 Linux 内核定时器

    2024-07-07

    点击下方名片关注公众号1. 内核定时器介绍1.1 内核时间管理内核中很多函数需要时间管理,比如周期性的调度程序、延时程序、定时器。硬件定时器提供时钟源,时钟源频率可以设置,设置好后就周期性的产生定时中断,系统使用定时中断来计时中断周期性产生的频率就是系统频率,也叫节拍率 (tick rate),节拍率是可设置的,在编译内核时可通过图形化界面设置,按照如下路径打开配置界面:-> Kernel Features    -> Timer frequency (<choice>[=y])默认系统节拍率为100Hz,内核使用全局变量jiffies来记录系统从启动以来的节拍数,系统启动时会将j...

  • Linux 信号量实现互斥点灯

    2024-07-06

    点击下方名片关注公众号1. 信号量介绍信号量常用于控制对共享资源的访问,有计数型信号量和二值信号量之分。初始化时信号量值大于1的,就是计数型信号量,计数型信号量不能用于互斥访问,它允许多个线程同时访问共享资源。若要互斥访问共享资源,信号量的值就不能大于1,此时就是二值信号量Linux内核使用semaphore结构体表示信号量,结构体内容如下所示:struct semaphore {    raw_spinlock_t lock;    unsigned int count;    struct list_head wait_list;};信号量操作相关API函数如下图示:2. 信号量实例本实例中使用信号量...

  • Linux 自旋锁实现互斥点灯

    2024-07-06

    点击下方名片关注公众号1. 自旋锁介绍自旋锁最多只能被一个可执行线程持有。如果一个线程试图获得一个已经被持有的自旋锁,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环;如果锁未被持有,请求锁的执行线程就可以立即得到它,继续执行等待自旋锁的线程一直处于自旋状态,会浪费处理器时间,降低系统性能,因此自旋锁的持有时间不能太长,适用于短时期的轻量级加锁内核使用结构体spinlock_t表示自旋锁,结构体定义如下所示:typedef struct spinlock {    union {        struct raw_spin...

  • pinctrl与gpio子系统下的字符设备驱动框架

    2024-07-06

    点击下方名片关注公众号pinctrl与gpio子系统下的字符设备驱动框架一文中将与外设有关的寄存器信息,定义到驱动代码中,直接操作寄存器来控制外设。缺点是当芯片的寄存器发了变动,就要对底层的驱动进行重写。一文中将与外设有关的寄存器信息,写到了设备树文件中,通过设备树API函数获取外设信息。当外设的信息有变化时,只需要修改设备树文件即可,无需修改底层驱动,提高了驱动代码的复用能力,但仍需要直接操作寄存器来控制外设。本文介绍的pinctrl和gpio子系统实现了对寄存器的操作,我们只需要使用子系统提供的API函数即可,而无需再直接操作寄...

  • 如何将BootLoader与APP合并成一个固件

    2024-07-06

    1、前言嵌入式固件一般分为BootLoader和App,BootLoader用于启动校验、App升级、App版本回滚等功能,BootLoader在cpu上电第一阶段中运行,之后跳转至App地址执行应用程序。因此,在发布固件的时候,会存在BootLoader固件和App固件;此时我们期望是将BootLoader固件和App固件合并成为一个固件,这样在量产时只需烧录一次即可。2、传统方式一些传统的方法都是“土办法”,没什么毛病,但比较繁琐。项目种类增加,或者版本发布频繁时更加体现出繁琐性,且易出错,操作稍微失误可能导致固件不完整;烧录不完整的固件,机子变“砖头”。烧录两次,分别烧...

  • 详解 Linux 系统调用的实现机制

    2024-07-06

    系统调用概述计算机系统的各种硬件资源是有限的,在现代多任务操作系统上同时运行的多个进程都需要访问这些资源,为了更好的管理这些资源进程是不允许直接操作的,所有对这些资源的访问都必须有操作系统控制。也就是说操作系统是使用这些资源的唯一入口,而这个入口就是操作系统提供的系统调用(System Call)。在linux中系统调用是用户空间访问内核的唯一手段,除异常和陷入外,他们是内核唯一的合法入口。一般情况下应用程序通过应用编程接口API,而不是直接通过系统调用来编程。在Unix世界,最流行的API是基于POSIX标准的。操作系统一般是通过中...

  • 这是我见过的最强的AI大模型教程!可以上车!!

    2024-07-06

    随着AI大热“AI大模型”无疑是最火爆的话题!Google、百度、腾讯等等巨头互联网公司,无不在布局人工智能技术和市场,甚至还有超高年薪,挖掘AI大模型人才!作为普通程序员,如何不被时代抛弃,享受AI技术带来的红利?!????知乎知学堂特发起: 行业前沿资源——AI大模型公开课 已为本号粉丝开通免费领取权限预计24小时后关闭通道!速进!AI大模型-重塑程序员核心竞争力(不限年龄!不限岗位!IT人都可学习!)直播时间 01月11日 晚20:00直播内容           大模型的发展历程与训练方法解析AI技术应用场景如何用LangChain、Fine-tuning 定...

  • 这么写代码,有问题吗?

    2024-07-06

    写代码是一件特别有意思的事情,你有时候写代码是给人看的,有时候写代码不是写给人看的。今天在群里看到这样一小段代码,我觉得还是挺初学者的这个代码不多,但是暴露出来的问题很多。1 双目运算符两边需要空格2 变量命名需要指明确定的用途,最后一个变量shut_down看起来还可以。3 标识位用bool变量,如果没有就自己typedef 4 下划线命名和驼峰命名在文件中需要统一不过话说回来,又不是不能跑,你说对不对?关注公众号,加星标,回复1024获取学习资料,每天进步一点点。声明:本号原创、转载的文章、图片等版权归原作者所有,如有侵权,请联系...

  • 适合在单片机上练手的小型图形库

    2024-07-06

    这个小型图形库提供点、线和字符绘图命令,用于 ATtiny85 上的 I2C 128x64 OLED 显示器。它通过避免显示缓冲器来支持RAM有限的处理器,并且可以与基于SH1106驱动芯片的I2C OLED显示器配合使用。   由于 I2C 只需要两条 I/O 线,因此图形显示可在 ATtiny85 上留出三行空闲线路供您自己的应用程序使用:请注意,此库仅适用于具有四个引脚的 I2C 显示器。它不适用于SPI显示器或基于SSD1306或SSD1309驱动程序芯片的显示器,因为这些都不支持读回显示器内存。这是一个基于ST7735和ST7789驱动芯片的小型彩色TFT显示器系列的。     此库允许您使用可...

  • 计算机如何实现UTF-8、UTF-32编码方法

    2024-07-06

    Unicode,又称统一码、万国码、单一码,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode产生的背景1.为何要有Unicode?ASCII编码使用 8bit (b0-b7)中的最高位b7位作为奇偶校验位,用来保障传输的可靠性,所以ASCII一共定义了2^7=128个字符集合。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1)2.ASCII编码的...

  • 单片机 SWD 下载通信底层原理

    2024-07-06

    基于Cortex-M内核的单片机,目前主流的下载接口就是JTAG和SWD。JTAG:TDI:Test Data In。串行输入引脚TDO:Test Data Out,串行输出引脚TCK:Test Clock,时钟引脚TMS:Test Mode Select,模式选择(控制信号)引脚TRST:Test Reset,复位引脚SWD:SWDIO:Serial Wire Data Input Output,串行数据输入输出引脚SWCLK:Serial Wire Clock,串行线时钟引脚其中SWD只需要两根线(SWCLK和 SWDIO),在PCB布局有限、引脚资源紧张的情况下,SWD算是一种不错的选择。SWD简介SWD:Serial Wire Debug,代表串行线调试,是ARM设计的协议,用于对其微控制器进...

  • 学 RTOS 从配置文件开始!

    2024-07-06

    最近有小伙伴问:学RTOS从哪里开始?这个问题说简单也简单,说难也难,因为每个人掌握的基础不同,自然,从哪里开始学起也各有不同。我认为,首先你要去了解 RTOS 相关的一些基础知识,然后再下载源码实践运行,跑起来!接下来真正入门的第一步,我觉得还得从“配置”文件开始,这里的配置,可以理解为大家说的“裁剪系统”及相关的一些配置。比如 FreeRTOS 中“FreeRTOSConfig.h”配置文件:当然,配置文件是你已经具备一定基础知识,上手源码第一步要掌握的内容。不仅仅是 FreeRTOS,其他μCOS、RT-Thread,甚至Linux都是从配置开启第一步的。可...

  • STM32开源驱动库集合!

    2024-07-06

    平时的开发,经常需要用到很多重复的代码,因此有必要花一些时间整理一些常用的、通用的代码,到时候就可以直接拿来用了。如果没有精力自己去整理,也可以用一些网上比较成熟的代码。这个库里包含了很多常用的外设驱动及常用器件的驱动:USART、I2C、SPI、ADC、DAC、RTC、USB、PWM、ILI9341、MPU6050等。本文推荐一个开源的STM32外设驱动库。项目地址:https://github.com/MaJerle/stm32f429    每个驱动的使用都配有单独的keil工程的例子:    每个工程都支持如下四个目标板:    有相关开发板的话可以直接用来测试。    核心代码...

  • 北大硕士7年嵌入式学习经验分享

    2024-07-06

    大家现在状态是怎么样的?这几年技术进步怎么样,职场晋升,管理水平有没有提升?欢迎留言!本文内容来自于知乎,觉得内容很不错,分享给大家。下文的我代表的是原作者。作者:梦人亦冷链接:https://www.zhihu.com/question/370606355/answer/1865920389来源:知乎阶段 1大一到大三这个阶段我与大多数学生相同:学习本专业知识(EE专业),学习嵌入式软件开发需要的计算机课程(汇编原理,计算机组成原理,操作系统,C语言等),学习嵌入式项目(来源于实验室项目,自己想到的项目以及各种比赛)。关于如何学习嵌入式软件开发:① 学习51单片机。这...

  • ELF 文件、镜像(Image)文件、可执行文件、对象文件详解

    2024-07-06

    ELF 文件规范ELF(Executable and Linking Format)是一个二进制文件规范。用于定义不同类型的对象文件(Object files)中都放了什么东西、以及都以什么样的格式去放这些东西。现在流行的二进制可执行文件格式 (Executable File Format),主要是 Windows 下的 PE(Portable Executable)和 Linux 的 ELF(Executable and Linking Format)可执行和链接格式)。他们都是 COFF(Common Object File Format)的变种。ARM 体系中采用的也是 ELF 文件格式。COFF 是在 Unix System V Release 3 时由 UNIX 系统实验室(UNIX System Laboratories, USL...

  • 这个小架构又美又秀

    2024-07-06

    我们通常认为,在中断中,不能执行耗时的操作,否则会影响系统的稳定性,尤其对于嵌入式编程。对于带操作系统的程序而言,可以通过操作系统的调度,将中断处理分成两个部分,耗时的操作可以放到线程中去执行,但是对于没有操作系统的情况,又应该如何处理呢比较常见的,我们可能会定义一些全局变量,作为flag,然后在mainloop中不停的判断这些flag,再在中断中修改这些flag,最后在mainloop中执行具体的逻辑,但是这样,无疑会增加耦合,增加程序维护成本。cpostcpost正是应用在这种情况下的一个简单但又十分方便的工具,它可以特别方便的进行上下文...

  • 嵌入式软件架构设计-建立抽象层

    2024-07-06

    大家好,今天分享一篇嵌入式软件架构设计相关的文章。软件架构这东西,众说纷纭,各有观点。什么是软件架构,我们能在网上找到无数种定义。比如,我们可以这样定义:软件架构是软件系统的基本结构,体现在其组件、组件之间的关系、组件设计与演进的规则,以及体现这些规则的基础设施。怎么定义一般来说,基本上不重要,我们不是在写学术书籍,工程人员嘛,只关心软件架构能解决什么问题。软件架构不是制定出来的,而是产品和业务需求所决定的,架构师所做的,只是忠于需求,并合理的表达了需求。软件架构也从来都不是一成不变的。在产品或者产品线的...

  • 嵌入式软件架构设计-建立基础设施

    2024-07-06

    大家好,今天分享一篇嵌入式软件架构设计相关的文章。软件架构这东西,众说纷纭,各有观点。在我看来,软件架构是软件系统的基本结构,包含其组件、组件之间的关系、组件设计与演进的规则,以及体现这些规则的基础设施。软件架构,从来不是一件容易事,它贯穿在产品的整个生命周期,需要所有团队成员遵守并自律,才能将架构思想在软件中体现。新手工程师,由于经历的项目太少,看不到项目全貌,很难从全局理解软件架构。但软件架构真的只是资深工程师的专利吗?这个也不见得。古人作文,讲究立意为先。今天工程师做项目和产品,也应该先立意。这个意...

  • 35岁还没进入管理层,人生就完蛋了?真实,进入管理层,人生才是真的完蛋了....

    2024-07-06

    程序员职场上一直流传着35岁职业危机的说法,很多公司甚至明确要求招聘对象年龄在35岁以下。不少人认为,如果35岁还没有进入管理层,那基本上职业上升空间已经到顶了,人生也就完蛋了... 因为大部分公司管理层薪资待遇高于基层人员,职场上升空间也不会面临所谓的35岁职业危机,一个公司50岁、60岁的管理人员比比皆是,而很少有基层管理者或者技术人员有50岁,60岁的。这位网友以自身的经历告诉大家,进入管理层后的工作,不像大家想象的那么光鲜亮丽。为什么说管理层的压力和焦虑要大于基层员工。因为管理层主要核心价值就是管事、管人,少则几个...

  • 汽车行业年薪60万要什么水平?网友:根本没有60万这么低的水平...

    2024-07-06

  • C语言指针这么理解,真透彻!

    2024-07-05

    本文为作者原创文章,原创不易,如需转载请附上本号链接或者联系作者。谢谢!一、C语言基础变量的定义首先,C语言变量定义的基本形式:  <变量类型> <变量名称>变量类型,就是确定了变量名称对应的实体是什么?比如,int a; //变量a是一个整型数char b; //变量b是一个字符现实生活也有<变量类型> <变量名称>这样的形式,比如,有一个名称angle,那angle是什么?一个人?一个物品?加上对angle的类型描述后,那就确定了angle的对象属性。女人 angle; //angle是一个女人物品 angle; // angle是一个物品画个表格,帮助理解<变量类型> <变量...

  • 嵌入式 C 语言史上最愚蠢的一个BUG

    2024-07-05

    本文来自“The most stupid C bug ever”,很有意思,分享给大家。我相信这样的bug,就算你是高手你也会犯的,你来看看作者犯的这个Bug吧。。首先,作者想用一段程序来创建一个文件,如果有文件名的话,就创建真正的文件,如果没有的话,就调用tmpfile()创建临时文件。他这段程序就是HTTP下载的C程序。code==200就是HTTP的返回码。else if (code == 200) {     // Downloading whole file    /* Write new file (plus allow reading once we finish) */    g = fname ? fopen(fname, "w+") : tmpfile();}但是...

  • C语言断言函数assert()的应用,清晰明了!

    2024-07-05

    来源:https://blog.csdn.net/houxiaoni01/article对于断言,相信大家都不陌生,大多数编程语言也都有断言这一特性。简单地讲,断言就是对某种假设条件进行检查。  在 C 语言中,断言被定义为宏的形式(assert(expression)),而不是函数,其原型定义在 <assert.h> 文件中。其中,assert 将通过检查表达式 expression 的值来决定是否需要终止执行程序。也就是说,如果表达式 expression 的值为假(即为 0),那么它将首先向标准错误流 stderr 打印一条出错信息,然后再通过调用 abort 函数终止程序运行;否则,assert 无任何作用。原型定义:#inc...