自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(626)
  • 收藏
  • 关注

原创 RTT 电源管理(一)

RTT的PM组件采用分层设计思想,分离架构和芯片相关的部分,提取公共部分作为核心。在对上层提供通用的接口同时,也让底层驱动对组件的适配变得更加简单。基于模式来管理功耗,空闲时动态调整工作模式,支持多个等级的休眠。对应用透明,组件在底层自动完成电源管理。支持运行模式下动态变频,根据模式自动更新设备的频率配置,确保在不同的运行模式都可以正常工作。支持设备电源管理,根据模式自动管理设备的挂起和恢复,确保在不同的休眠模式下可以正确的挂起和恢复。

2024-04-26 14:10:38 545

原创 RTT学习

STM32具有运行、睡眠、停止和待机四种工作模式。上电后默认是在运行模式,当内核不需要继续运行时,可以选择后面三种低功耗模式。STM32L476是ST公司推出的一款超低功耗的Cortex-M4内核的MCU,支持多个电源管理模式,其中最低功耗shutdown模式下,待机电流仅30nA。

2024-04-25 11:31:24 709

原创 RTT学习 cortex-m移植

在动态创建线程和初始化线程的时候,会使用到内部的线程初始化函数_rt_thread_init(),_rt_thread_init()函数会调用栈初始化函数rt_hw_stack_init(),在栈初始化函数里会手动构造一个上下文内容,这个上下文内容被作为每个线程第一次执行的初始值。libcpu层向上对内核提供统一的接口,包括全局中断的开关,线程栈的初始化,上下文切换等。修改PSP为to线程的栈地址,在退出PendSV中断时,硬件会自动弹出to线程的R3-R0,R12、LR、PC、PSR寄存器。

2024-04-24 09:30:22 1423

原创 RTT学习 开发环境搭建

Kconfig用来配置内核,menuconfig命令通过读取工程的各个KConfig文件,生成配置界面供用户配置内核,最后所有配置相关的宏定义都会自动保存到BSP目录里的rtconfig.h文件中,每个BSP都有一个rtconfig.h文件,这也就是BSP的配置信息。同样以上文提到的hello.c和hello.h为例,需要把他们作为一个单独的模块管理,并且在MDK或者IAR的工程文件里有自己的分组,且可以通过menuconfig选中是否使用这个模块。这里要介绍一个新的文件Kconfig。

2024-04-23 17:07:43 613

原创 RTT学习 MQTT

MQTT是机器对机器(M2M)/物联网(IoT)连接协议,它是专为受限设备和低带宽、高延迟或不可靠的网络而设计的,是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。几个客户端的角色是订阅者Subscriber,如手机APP从Broker订阅了“Temp”主题,便能在手机上获取到温度传感器publish在Broker中的温度值。发布者也可以同时从Broker订阅主题,同理,订阅者也可以向Broker发布主题;

2024-04-23 14:14:26 226

原创 RTT学习

RTT NetUtils作为网络工具合集,既有用于测试调试的ping命令,同步时间的NTP工具,性能和带宽测试的Iperf、NetIO,还有在嵌入式系统中广泛使用的轻量级文件传输工具TFTP,方便地通过网络完成两个设备间的文件互传,可以远程登录的RTT Finsh/MSH Shell的Telnet工具,以及基于LWIP的网络抓包工具tcpdump。Ping:利用ping命令可以检查网络是否连通,可以很好地帮助我们分析和判定网络故障NTP:网络时间协议。

2024-04-23 13:34:51 432

原创 RT-Thread电源管理组件

RTT的PM组件采用分层设计思想,分离架构和芯片相关的部分,提取公共部分作为核心。在上层提供通用的接口同时,也让底层驱动对组件的适配变得更加简单。

2024-04-23 10:34:30 802

原创 RT-Thread 组件

FinSH是RTT的命令行组件,提供一套供用户在命令行调用的操作接口,主要用于调试或查看系统信息。它可以使用串口/以太网/USB等与PC机进行通信。用户在控制终端输入命令,控制终端通过串口将命令传给设备里的FinSH,FinSH会读取设备输入命令,解析并自动扫描内部函数表,寻找对应函数名,执行函数后输出回应,回应通过原路返回,将结果显示在控制终端上。

2024-04-22 20:26:57 848

原创 计算机网络概述

对于不同的网络应用需要有不同的应用层协议,在互联网中的应用层协议很多,如域名系统DNS,支持万维网的HTTP协议,支持电子邮件的SMTP协议,等等。运输层的任务就是负责向两台主机中进程之间的通信提供通用的数据传输服务。网络层的另一个任务是选择合适的路由,使源主机运输层所传下来的分组,能够通过网络中的路由器找到目的主机。在TCP/IP体系中,由于网络层使用IP协议,因此分组也叫作IP数据报,简称数据报。所谓通用的,是指并不针对某个特定网络应用,而是多种应用可以使用同一个运输层服务。数据链路层通常称为链路层。

2024-04-22 09:34:28 1379

原创 RTT设备驱动框架学习(UART)

在drv_usart.c中要实现串口驱动框架层定义的接口。然后在初始化函数里去注册设备驱动程序。在drv_usart.h中。在serial.h中。在serial.c中。

2024-04-21 11:23:16 208

原创 RTT设备驱动框架学习(GPIO)

设备基类,定义在rtdef.h中(属于设备接口层)在drv_gpio.c中(属于设备驱动层)在pin.h中(属于设备驱动框架层)基类对象,定义在rtdef.h中。设备驱动框架层pin.c中定义了。实现了设备驱动框架层的操作接口。

2024-04-21 09:33:53 222

原创 RTT设备驱动框架学习(CAN设备)

RTT设备框架属于组件和服务层,是基于RTT内核之上的上层软件。设备框架是针对某一类外设,抽象出来的一套统一的操作方法及接入标准,可以屏蔽硬件差异,为应用层提供统一的操作方法。RTT设备框架分为三层:设备驱动层、设备驱动框架层、I/O设备管理层。其中设备驱动层直接对接底层硬件设备;I/O设备管理层向应用层提供了rt_device_find、open、read、write、close、register等访问设备的统一标准接口。

2024-04-21 08:31:34 367

原创 RTT学习

SCons是一套由Python语言编写的开源构建系统,类似于GNU Make。它采用不同于通常Makefile文件的方式,而是使用SConstruct和SConscript文件来代替。这些文件也是Python脚本,能够使用标准的Python语法来编写。所以在SConstruct、Sconscript文件中可以调用Python标准库进行各类复杂的处理,而不局限于Makefile设定的规则。

2024-04-18 16:22:41 989

原创 RTT学习

在RTT实时操作系统中,各种各样的设备驱动是通过一套I/O设备管理框架来管理的。设备驱动框架给上层应用提供了一套标准的设备操作API,开发者通过调用这些标准设备操作API,可以高效地完成和底层硬件外设的交互。使用同一套标准的API开发应用程序,使应用程序具有更好的移植性。底层驱动的升级和修改不会影响到上层代码。驱动和应用程序相互独立,方便多个开发者协同开发。片上外设驱动:指MCU芯片上的外设,例如硬件定时器,ADC和看门狗等。

2024-04-18 14:52:36 1115

原创 RTT学习

UART(Universal Asynchronous Receiver/Transmitter)通用异步收发器,UART作为异步串口通信协议的一种,工作原理是将传输数据的每个字符一位接一位地传输。是在应用程序开发过程中使用频率最高的数据总线。UART串口的特点是将数据一位一位地顺序传送,只要2根传输线就可以实现双向通信,一根线发送数据的同时用另一根线接收数据。

2024-04-18 10:24:10 941

原创 RTT学习

绝大部分的嵌入式系统都包括一些 I/O(Input/Output,输入 / 输出)设备,例如仪器上的数据显示屏、工业设备上的串口通信、数据采集设备上用于保存数据的 Flash 或 SD 卡,以及网络设备的以太网接口等,都是嵌入式系统中容易找到的 I/O 设备例子。例如上图中的块 4,驱动程序需要先把块 4 所对应的设备块读出来,然后将需要写入的数据覆盖至从设备块读出的数据上,使其合并成一个新的块,最后再写回到块设备中。字符模式设备允许非结构的数据传输,即通常数据传输采用串行的形式,每次一个字节。

2024-04-18 09:29:45 838

原创 RTT学习

中断处理程序里处理完中断事务之后,中断退出之前,检查 rt_thread_switch_interrupt_flag 变量,如果该变量的值为 1,就根据 rt_interrupt_from_thread 变量和 rt_interrupt_to_thread 变量,完成线程的上下文切换。_rt_thread_init(),_rt_thread_init() 函数会调用栈初始化函数rt_hw_stack_init(),在栈初始化函数里会手动构造一个上下文内容,这个上下文内容将被作为每个线程第一次执行的初始值。

2024-04-17 16:45:14 824

原创 RTT学习

Cortex-M系列CPU的寄存器组里有R0-R15共16个通用寄存器组和若干特殊功能寄存器。通用寄存器组里的R13作为堆栈指针寄存器(Stack Pointer,SP);R14作为连接寄存器(Link Register,LR),用于在调用子程序时,存储返回地址;R15作为程序计数器(Program Counter,PC),其中堆栈指针寄存器可以是主堆栈指针(MSP),也可以是进程堆栈指针(PSP)。

2024-04-17 15:06:33 908

原创 RTT学习

动态内存使用总结:检查从 rt_malloc 函数返回的指针是否为 NULL不要访问动态分配内存之外的内存不要向 rt_free 传递一个并非由 rt_malloc 函数返回的指针在释放动态内存之后不要再访问它使用 sizeof 计算数据类型的长度,提高程序的可移植性常见的动态内存错误:对 NULL 指针进行解引用对分配的内存进行操作时越过边界释放并非动态分配的内存释放一块动态分配的内存的一部分 (rt_free(ptr + 4))动态内存被释放后继续使用。

2024-04-17 10:07:45 759

原创 RTT学习

空闲链表指针lfree初始指向32字节的内存块,当用户要分配一个64字节的内存块时,但此lfree指针指向的内存块只有32字节并不能满足要求,内存管理器会继续寻找下一内存块,当找到再下一块内存块,128字节时,它满足分配的要求。每个信号量对象都有一个信号量值和一个线程等待队列,信号量的值对应了信号量对象的实例数目、资源数目,假如信号量值为5,则表示共有5个信号量实例(资源)可以被使用,当信号量实例数目为零时,再次申请该信号量的线程就会被挂起在该信号量的等待队列上,等待可用的信号量实例(资源)。

2024-04-17 08:52:35 1363

原创 RTT学习

当指定的 flag 为 RT_TIMER_FLAG_HARD_TIMER 时,如果定时器超时,定时器的回调函数将在时钟中断的服务例程上下文中被调用;当指定的 flag 为 RT_TIMER_FLAG_SOFT_TIMER 时,如果定时器超时,定时器的回调函数将在系统时钟 timer 线程的上下文中被调用。调用定时器启动函数接口后,定时器的状态将更改为激活状态(RT_TIMER_FLAG_ACTIVATED),并按照超时顺序插入到 rt_timer_list 队列链表中。

2024-04-16 20:08:17 368

原创 RTT学习

RTT的定时器提供两类定时器机制:第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动停止。第二类是周期触发定时器,这类定时器会周期性地触发定时器事件,直到用户手动的停止,否则将永远持续执行下去。另外,根据超时函数执行时所处的上下文环境,RTT的定时器分为HARD_TIMER模式与SOFT_TIMER模式。HARD_TIMER。

2024-04-16 15:48:59 723

原创 RTT学习

在RT-Thread中,与上述子任务对应的程序实体就是线程,线程是实现任务的载体,是RTT中最基本的调度单位,它描述了一个任务执行的运行环境,也描述了这个任务所处的优先等级,重要的任务可设置相对较高的优先级,非重要的任务可以设置较低的优先级,不同的任务还可以设置相同的优先级,轮流运行。线程调度器是抢占式的,主要工作是从就绪线程列表中查找最高优先级线程,保证最高优先级的线程能够被运行,最高优先级的任务一旦就绪,总能得到CPU的使用权。RT-Thread 线程的优先级是表示线程被调度的优先程度。

2024-04-16 10:22:02 698

原创 RTT学习

初始化函数主动通过这些宏接口进行申明,如INIT_BOARD_EXPORT(rt_hw_usart_init),链接器会自动收集所有被申明的初始化函数,放到RTI符号段中,该符号段位于内存分布的RO段中,该RTI符号段中的所有函数在系统初始化时会被自动调用。在调用以上接口时,系统首先需要根据对象类型获取对象信息(特别是对象类型的大小信息以用于系统能够分配正确大小的内存数据块),而后从内存堆中分配对象所对应大小的内存空间,然后再对该对象进行必要的初始化,最后将其插入到它所在的对象容器链表中。

2024-04-16 07:08:57 770

原创 RT-Thread学习

RT-Thread是一款完全由国内团队开发维护的嵌入式实时操作系统,具有完全的自主知识产权。经过16个年头的沉淀,伴随着物联网的兴起,它正演变成一个功能强大、组件丰富的物联网操作系统。内核是一个操作系统核心,负责管理系统的线程、线程间通信、系统时钟、中断及内存等。内核处于硬件层之上,内核部分包括内核库、实时内核实现。内核库是为了保证内核能够独立运行的一套小型的类似C库的函数实现子集。这部分根据编译器的不同自带C库的情况会有些不同,当使用GNU GCC编译器时,会携带更多的标准C库实现。

2024-04-15 16:37:43 1011

原创 Leetcode算法题

当一个版本为正确版本,则该版本之前所有的版本均为正确版本,当一个版本为错误版本,则该版本之后的所有版本均为错误版本。最朴素的想法是存储数组nums的值,每次调用sumRange时,通过循环的方式计算和,一共计算j-i+1个元素的和。产品的最新版本没有通过质量检测,由于每个版本都是基于之前的版本开发的,所以错误的版本之后的所有版本都是错的。每一轮投票过程中,从数组中删除两个不同的元素,直到投票过程无法继续,此时数组为空或者数组中剩下的元素都相等。扫描过程中,维护当前整理好的字符串,记为ret。

2024-04-13 08:50:07 710

原创 Linux中APP读取按键的4种方法

APP 调用 open 时,导致驱动中对应的 open 函数被调用,在里面配置 GPIO 为输入引脚。APP 调用 read 时,导致驱动中对应的 read 函数被调用,它读取寄存器,把引脚状态直接返回给 APP。APP得到poll/select函数的返回结果后,如果确认是有数据的,则再调用read函数,这会导致驱动中的read函数被调用,这时驱动程序中含有数据,会直接返回数据。这会导致驱动中对应的poll函数被调用,如果有按键数据则直接返回给APP,否则APP在内核态休眠一段时间。这里发的是SIGIO。

2024-03-27 18:48:20 948

原创 Linux设备树

根节点下也有compatible属性,用来选择哪一个“machine desc”:一个内核可以支持machine A,也支持machine B,内核启动后会根据根节点的compatible属性找到对应的machine desc结构体,执行其中的初始化函数。设备树文件不需要我们从零写出来,内核支持某款芯片比如imx6ull,在内核的arch/arm/boot/dts目录下就有了能用的设备树模板,一般命名为xxx.dtsi,i表示include,被别的文件引用的。对于数值,可以用hexdump把它打印出来。

2024-03-27 17:22:36 870

原创 C++多态

多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码。在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容。虚析构或纯虚析构都是用来解决通过父类指针释放子类对象的问题。有了纯虚析构之后,这个类也属于抽象类,无法实例化对象。如果子类没有堆区数据,可以不写虚析构或纯虚析构。子类中的虚函数表内部会替换成子类的虚函数地址。开闭原则:对扩展进行开放,对修改进行关闭。多态是C++面向对象三大特性之一。因此可以将虚函数改为纯虚函数。当子类重写父类的虚函数时。

2024-03-14 15:48:08 642

原创 Leetcode算法题

显而易见的是,如果石头堆中只有一块、两块、或是三块石头,那么在你的回合,你就可以把全部石子拿走,从而在游戏中取胜;因此,要想获胜,在你的回合中,必须避免石头堆中的石子数为 4 的情况。对二叉树的根节点root进行深度优先搜索,在搜索过程中,根据规则对遍历的节点的值进行恢复,并且将遍历的节点的值加入哈希表valSet中。如果当前遍历到的节点root的左右子树都已经翻转,那么只需要交换两棵子树的位置,即可完成以root为根节点的整棵子树的翻转。从根节点开始,递归地对树进行遍历,并从叶子节点开始翻转。

2024-03-13 13:48:58 876 1

原创 C++继承

当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢?子类继承父类后,当创建子类对象,也会调用父类的构造函数。多继承可能会引发父类中有同名成员出现,需要加作用域区分。先构造父类,再构造子类,析构的顺序与构造的顺序相反。继承同名静态成员处理方式:与非静态成员一致。利用开发人员命令提示工具查看对象模型。这种继承称为菱形继承,或者钻石继承。C++实际开发中不建议用多继承。跳转文件路径 cd 具体路径下。又有某个类同时继承两个派生类。C++允许一个类继承多个类。两个派生类继承同一个基类。

2024-03-13 11:39:43 674

原创 C++运算符重载

如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题。堆区内存重复释放,程序崩溃!解决方案:利用深拷贝,解决深拷贝带来的问题。

2024-03-13 09:28:25 355

原创 C++类和对象

C++认为,对象上有其属性和行为。具有相同性质的对象,可以抽象为类,人属于人类,车属于车类。

2024-03-12 08:37:41 876

原创 Leetcode算法题

为了让数组之和最小,我们按照1,2,3的顺序考虑,但添加了x之后,就不能添加taget-x,因此最大可以添加到target/2,如果个数不够,就继续从target,target+1,…我们可以遍历secret和 guess,统计满足 secret[i] == guess[i] 的下标个数,即为公牛的个数。需要构造一个大小为n的正整数数组,该数组由不同的数字组成,并且没有任意两个数字的和等于target,在满足这样的前提下,要保证数组的和最小。给定一个大小为 n 的数组 nums ,返回其中的多数元素。

2024-03-10 09:38:01 902

原创 Leetcode算法题

如果当前节点在哈希集合中,则后面的节点都在哈希集合中,即从当前节点开始的所有节点都在两个链表的相交部分,因此在链表 headB\textit{headB}headB 中遍历到的第一个在哈希集合中的节点就是两个链表相交的节点,返回该节点。每次到达一个节点,如果该节点已经存在于哈希表中,则说明该链表是环形链表,否则就将该节点加入哈希表中。初始时,慢指针在head,快指针在head.next,若在移动过程中,快指针反过来追上慢指针,说明链表是环形。定义两个指针,慢指针每次移动一步,快指针每次移动两步。

2024-03-07 21:12:09 809

原创 C++核心编程

C++中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置。堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符delete。如果某个位置函数有默认值,那么从这个位置往后,从左向右,必须都要有默认值。在函数形参列表中,可以加const修饰形参,防止形参改变实参。如果函数声明有默认值,那么函数实现的时候就不能有默认参数。如果自己传入数据,就用自己的数据,如果没有,就用默认值。利用new创建的数据,会返回该数据对应的类型的指针。在C++中,函数的形参列表中的形参是可以有默认值的。

2024-03-07 13:54:25 481

原创 初学C++

将函数中的形参改为指针,可以减少内存空间,而且不会复制新的副本出来。结构体属于用户自定义的数据类型,允许用户存储不同的数据类型。如果表达式1的值为真,执行表达式2,并返回表达式2的结果。取模运算,如果第一个数小于第二个数,结果等于第一个数。数据类型存在的意义:给变量分配合适的内存空间。在C++中,三目运算返回的是变量,可以继续赋值。指针的指向可以修改,但指针指向的值不可以修改。作用:利用指针作函数的参数,可以修改实参的值。空指针:指针变量指向内存中编号为0的空间。指针的指向不可以改,指针指向的值可以改。

2024-03-06 19:15:37 1064

原创 Leetcode算法题

给定一个二叉树的根节点root,返回它的中序遍历。中序遍历:按照访问左子树——根节点——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候我们按照同样的方式遍历,直到遍历完整棵树。因此整个遍历过程天然具有递归的性质,我们可以直接用递归函数来模拟这一过程。相同的树给两棵二叉树的根节点p和q,编写一个函数验证这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。示例 1:输入:p = [1,2,3], q = [1,2,3]输出:true示例 2:输入:p = [1,

2024-03-06 14:57:27 1201

原创 Leetcode算法题

本题是一道常见的面试题,面试官一般会要求面试者在不使用 x\sqrt{x}x​函数的情况下,得到 xxx 的平方根的整数部分。一般的思路会有以下几种:通过其它的数学函数代替平方根函数得到精确结果,取整数部分作为答案;通过数学方法得到近似结果,直接作为答案。函数的情况下,得到 xxx 的平方根的整数部分。一般的思路会有以下几种:通过其它的数学函数代替平方根函数得到精确结果,取整数部分作为答案;通过数学方法得到近似结果,直接作为答案。

2024-03-05 15:23:07 883

原创 Leetcode算法题

你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。将一个栈当作输入栈,用于压入push传入的数据;另一个栈当作输出栈,用于pop和peek操作。void push(int x) 将元素 x 推到队列的末尾。int pop() 从队列的开头移除并返回元素。int peek() 返回队列开头的元素。

2024-03-04 17:53:54 406

随机过程-排队论-习题解答

随机过程-排队论-习题解答

2022-10-27

随机过程排队论习题解答

课后习题答案

2022-10-27

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除