自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(67)
  • 资源 (1)
  • 收藏
  • 关注

原创 代码随想录二刷栈与队列

具体思路如下:程序如下:队列模拟栈具体思路如下:程序如下:用一个队列实现的思路如下:滑动窗口最大值这道题要求滑动窗口中的最大值并记录下来。这里考虑用单调队列,单调队列指的是单调递减或者单调递增队列。这里我们要求到这个滑动窗口的最大值,所以采用单调递减队列。具体来说我们这个单调队列中一直维护就是窗口的最大值。具体程序如下:前 K 个高频元素要用小顶堆,因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。具体程序如下:

2024-08-05 22:59:42 239 1

原创 代码随想录二刷字符串

看leetcode这样一道题目:这道题若是用python库函数直接就秒了。但是那这道题就失去了本身的意义。题目注意事项中也说了输入字符串S可能存在前导空格、尾随空格或者单词间的多个空格。所以首先是对字符串处理。去除其中的空格。这与之前去除数组中去除特定元素是一样的思路。接下来来看下字符串中的KMP算法。

2024-08-04 20:52:00 334

原创 笔试查漏补缺

遍历完成后,最大的元素会被移动到数组的最右端。如果处理器是小端,则返回1.联合体 union的存放顺序是所有成员都从低地址开始存放,如果能够通过改代码知道CPU对内存是采用小端模式读写,还是采用大端模式读写,一定会令面试官刮目相看。希尔排序是基于插入排序的以下两点性质而提出改进方法的:插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;快速排序的核心操作是“哨兵划分”,其目标是:选择数组中的某个元素作为“基准数”,将所有小于基准数的元素移到其左侧,而大于基准数的元素移到其右侧。

2024-08-04 12:22:16 821

原创 代码随想录二刷(哈希表)

四数之和相当于三数之和升级了一下,并且target不是0了。按照三数之和的思路,再加一个变量作为外层循环。组合出来四个数即可。若这道题还是采用哈希表的思路去做,非常麻烦,并且还要考虑去重的操作。所以这道题其实用双指针,是更方便的。三数之和思路反正对于我来说是真的难想出来。

2024-07-31 21:45:00 337

原创 代码随想录二刷(链表章节)

链表就是通过指针串联在一起的线性结构,每个节点都是由一个数据域和指针域(存放下一个节点的指针)。双链表就是每个节点中既有指向前一个节点的,也有指向后一个节点的。循环链表就是把头和尾连起来。

2024-07-30 19:29:46 635

原创 代码随想录螺旋矩阵二刷

来看下螺旋矩阵。螺旋矩阵这道题确实很容易写着写着就绕进去了。首先读下题。给出正整数n,生成n*n的矩阵。我们来看其中一个用例,完成一个圈是需要四个循环去填充。但是四条边填充的时候要始终保持一样的规则,比如左闭右开的规则。那么转几圈呢。需要外部一个循环来控制,是不是就是n决定的。也就是n//2.决定循环次数。我们需要定义开始填充的x和y坐标。也就是行开始坐标和列开始坐标。并且由于我们遍历的终点是取不到的,并且这个位置是跟你在第几圈循环是有关系的。

2024-07-21 21:18:28 242

原创 代码随想录数组二刷:长度最小的子数组(滑动窗口)

这道题采用滑动窗口的思想去做。接下来来具体分析这个代码,因为是滑动窗口,那么这个窗口是怎么构成的呢,是不是就是left和right组成的区间长度,那么何时去计算这个长度,是不是区间里面的和大于等于target时候开始去计算长度。,然后左边开始移动,移动的原因是因为这个和可能远超你要求的target,所以可以移动左边来缩小窗口。由于你左边移动了,就要把个值从总体的和剔除掉。那么啥时候退出这个内部循环呢。也就是求出的和小于target时候,就去移动右边界。

2024-07-20 23:36:44 844

原创 代码随想录移除元素二刷

这道题思路的话可以这样去理解,用两个指针,一个慢指针,一个快指针。先让快指针往前面去探路,也就是去遍历数组,遇到不为val的值再去把该值赋值给nums[slow],slow指针+1,遇到为val的值,nums[slow]不做任何操作,继续移动fast指针。因为还要返回元素的个数,所以返回slow即可。如何不理解为啥返回slow的话找个例子代入一下就可以看出来,

2024-07-20 19:26:03 466

原创 代码随想录二刷复习(二分法)

第一种写法,我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right] (这个很重要非常重要)。区间的定义这就决定了二分法的代码应该如何写,因为定义target在[left, right]区间,所以有如下两点:while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=

2024-07-17 22:06:15 1016

原创 Linux MISC 驱动实验学习

MISC 设备驱动就用于解决此问题。MISC 设备会自动创建 cdev,不需要像我们以前那样手动创建,因此采用 MISC 设备驱动可以简化字符设备驱动的编写。我们需要向 Linux 注册一个 miscdevice 设备, miscdevice是一个结构体,定义在文件示例代码 57.1.1 miscdevice 结构体代码/* 子设备号 *//* 设备名字 *//* 设备操作集 */67 };

2024-07-03 10:18:59 448

原创 设备树下的 platform 驱动编写

platform 驱动框架分为总线、设备和驱动,其中总线不需要我们这些驱动程序员去管理,这个是 Linux 内核提供的,我们在编写驱动的时候只要关注于设备和驱动的具体实现即可。在没有设备树的 Linux 内核下,我们需要分别编写并注册 platform_device 和 platform_driver,分别代表设备和驱动。在使用设备树的时候,设备的描述被放到了设备树中,因此 platform_device 就不需要我们去编写了。

2024-06-30 15:58:41 630

原创 platform 设备驱动实验

总线(bus)、驱动(driver)和设备(device)模型,比如 I2C、 SPI、 USB 等总线。但是在 SOC 中有些外设是没有总线这个概念的,但是又要使用总线、驱动和设备模型该怎么办呢?为了解决此问题, Linux 提出了 platform 这个虚拟总线,相应的就有 platform_driver 和 platform_device.

2024-06-26 19:56:26 760

原创 异步通知实验学习

算是在软件层次上对中断的一种模拟,驱动可以通过主动向应用程序发送信号的方式来报告自己可以访问了,应用程序获取到信号以后就可以从驱动设备中读取或者写入数据了。整个过程就相当于应用程序收到了驱动发送过来了的一个中断,然后应用程序去响应这个中断,在整个处理过程中应用程序并没有去查询驱动设备是否可以访问,一切都是由驱动设备自己告诉给应用程序的。fasync_helper 函数的前三个参数就是 fasync 函数的那三个参数,第四个参数就是要初始化的 fasync_struct 结构体指针变量。设置信号的处理函数。

2024-06-21 15:53:14 989

原创 Linux 阻塞和非阻塞 IO 实验学习

FD_ZERO 用于将 fd_set 变量的所有位都清零, FD_SET 用于将 fd_set 变量的某个位置 1,也就是向 fd_set 添加一个文件描述符,参数 fd 就是要加入的文件描述符。传统的 selcet 和 poll 函数都会随着所监听的 fd 数量的增加,出现效率低下的问题,而且poll 函数每次必须遍历所有的描述符来检查就绪的描述符,这个过程很浪费时间。等待队列头就是一个等待队列的头部,每个访问设备的进程都是一个队列项,当设备不可用的时候就要将这些进程对应的等待队列项添加到等待队列里面。

2024-06-21 10:05:28 760

原创 Linux 中断实验

假如 A 任务调用 local_irq_disable 关闭全局中断 10S,当关闭了 2S 的时候 B 任务开始运行, B 任务也调用local_irq_disable 关闭全局中断 3S, 3 秒以后 B 任务调用 local_irq_enable 函数将全局中断打开了。在 Linux 内核中要想使用某个中断是需要申请的, request_irq 函数用于申请中断, request_irq函数可能会导致睡眠,因此不能在中断上下文或者其他禁止睡眠的代码段中使用 request_irq 函数。

2024-06-19 20:42:16 991

原创 Linux 内核定时器实验学习

Linux 内核中有大量的函数需要时间管理,比如周期性的调度程序、延时程序、对于我们驱动编写者来说最常用的定时器。硬件定时器提供时钟源,时钟源的频率可以设置, 设置好以后就周期性的产生定时中断,系统使用定时中断来计时。中断周期性产生的频率就是系统频率,也叫做节拍率(tick rate)(有的资料也叫系统频率),比如 1000Hz, 100Hz 等等说的就是系统节拍率。CONFIG_HZ 为 100, Linux 内核会使用 CONFIG_HZ 来设置自己的系统时钟。

2024-06-16 20:24:11 916

原创 Linux 按键输入实验

读取按键 IO 的电平,如果为 0 的话就表示按键按下了,如果按键按下的话就等待按键释放。在本章实验中蜂鸣器使用的 PIN 为 UART1_CTS_B,因此先检查 PIN 为 UART1_CTS_B 这个 PIN 有没有被其他的 pinctrl 节点使用,如果有使用的话就要屏蔽掉,然后再检查 GPIO1_IO18这个 GPIO 有没有被其他外设使用,如果有的话也要屏蔽掉。本章我们实现按键输入,在驱动程序中使用一个整形变量来表示按键值,应用程序通过 read 函数来读取按键值,判断按键有没有按下。

2024-06-16 09:57:33 518

原创 Linux 并发与竞争实验学习

每次打开驱动设备的时候先使用 atomic_dec_and_test 函数将 lock 减 1,如果 atomic_dec_and_test函数返回值为真就表示 lock 当前值为 0,说明设备可以使用。其他设备正在使用 LED 灯,那么就只能退出了,在退出之前调用函数 atomic_inc 将 lock 加 1,因为此时 lock 的值被减成了负数,必须要对其加 1,将 lock 的值变为 0。使用了那么变量就加一,设备被释放以后变量就减 1,我们只需要使用自旋锁保护这个变量即。出现如图则证明成功。

2024-06-15 19:57:48 983

原创 Linux 并发与竞争基础知识学习

设备结构体变量就不是整型变量,我们对于结构体中成员变量的操作也要保证原子性,在线程 A 对结构体变量使用期间,应该禁止其他的线程来访问此结构体变量,这些工作原子操作都不能胜任,需要本节要讲的锁机制,在 Linux内核中就是自旋锁。如果使用的是 64 位的 SOC,那么就要使用 64 位的原子操作函数。防止并发访问共享资源,换句话说就是要保护共享资源,防止进行并发访问,因为驱动程序各不相同,那么数据也千变万化,一般像全局变量,设备结构体这些肯定是要保护的,至于其他的数据就要根据实际的驱动程序而定了。

2024-06-14 11:26:48 1076

原创 Linux 蜂鸣器实验

在本章实验中蜂鸣器使用的 PIN 为 SNVS_TAMPER1,因此先检查 PIN 为 SNVS_TAMPER1这个 PIN 有没有被其他的 pinctrl 节点使用,如果有使用的话就要屏蔽掉,然后再检查GPIO5_IO01 这个 GPIO 有没有被其他外设使用,如果有的话也要屏蔽掉。其余步骤仍旧和上一节编写驱动开发类似。

2024-06-11 23:09:49 326

原创 pinctrl 和 gpio 子系统实验学习

gpio1 节点的 compatible 属性描述了兼容性,在 Linux 内核中搜索“fsl,imx6ul-gpio”和“fsl,imx35-gpio”这两个字符串,查找 GPIO 驱动文件。示例代码 45.2.2.3 mxc_gpio_dt_ids 匹配表158 };第 156 行的 compatible 值为“fsl,imx35-gpio”,和 gpio1 的 compatible 属性匹配,因此 gpiomxc.c 就是 I.MX6ULL 的 GPIO 控制器驱动文件。

2024-06-11 11:14:24 1016

原创 设备树下的 LED 驱动实验

新建名为“4_dtsled”文件夹,然后在 4_dtsled 文件夹里面创建vscode 工程,工作区命名为“dtsled”。①、在 imx6ull-alientek-emmc.dts 文件中创建相应的设备节点。②、编写驱动程序(在第四十二章实验基础上完成),获取设备树中的相关属性值。③、使用获取到的有关属性值来初始化 LED 所使用的 GPIO。index 参数用于指定要映射的具体内存段。of_iomap函数上一节已经学习了函数,剩余编译测试和之前的是一样的。

2024-06-08 19:32:47 341

原创 Linux 设备树学习

设备树(Device Tree),将这个词分开就是“设备”和“树”,描述设备树的文件叫做 DTS(DeviceTree Source),这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息,比如CPU 数量、 内存基地址、 IIC 接口上接了哪些设备、 SPI 接口上接了哪些设备等等。具体如下图所示:树的主干就是系统总线, IIC 控制器、 GPIO 控制器、 SPI 控制器等都是接到系统主线上的分支。

2024-06-07 18:10:19 769

原创 新字符设备驱动实验学习

register_chrdev 和 unregister_chrdev 这两个函数是老版本驱动使用的函数,现在新的字符设备驱动已经不再使用这两个函数,而是使用Linux内核推荐的新字符设备驱动API函数。新字符设别驱动API函数在驱动模块加载的时候自动创建设备节点文件。

2024-06-05 21:04:29 879

原创 嵌入式 Linux LED 驱动开发实验学习

I.MX6U-ALPHA 开发板上的 LED 连接到 I.MX6ULL 的 GPIO1_IO03 这个引脚上,进行这个驱动开发实验之前,需要了解下地址映射。

2024-06-05 19:57:44 1310

原创 ARM Linux 驱动开发学习之字符设备驱动开发

字符设备是 Linux 驱动中最基本的一类设备驱动,字符设备就是一个一个字节,按照字节流进行读写操作的设备,读写数据是分先后顺序的。比如我们最常见的点灯、按键、 IIC、 SPI,LCD 等等都是字符设备,这些设备的驱动就叫做字符设备驱动。Linux 应用程序对驱动程序的调用如下图所示:使用 open 函数来打开文件/dev/led,使用完成以后使用 close 函数关闭/dev/led 这个文件。

2024-06-03 16:32:52 1124

原创 U-boot、linux内核、根文件系统移植以及程序

终于这几天把这个移植的流程过了一遍,所以特此回来总结。

2024-06-02 19:46:14 1467

原创 Linux学习C语言版 LED 灯实验

大部分情况下都是使用 C 语言去编写的。只是在开始部分用汇编来初始化一下 C 语言环境,比如初始化 DDR、设置堆栈指针 SP 等等,当这些工作都做完以后就可以进入 C 语言环境,也就是运行 C 语言代码,一般都是进入 main 函数。所以我们有两部分文件要做:①、汇编文件汇编文件只是用来完成 C 语言环境搭建。②、C 语言文件C 语言文件就是完成我们的业务层代码的,其实就是我们实际例程要完成的功能。

2024-05-10 10:36:54 805

原创 嵌入式Linux学习第四天启动方式学习

当 BOOT_MODE1 为 1,BOOT_MODE0 为 0 的时候此模式使能,在此模式下,芯片会执行内部的 boot ROM 代码,这段 boot ROM 代码会进行硬件初始化(一部分外设),然后从 boot 设备(就是存放代码的设备、比如 SD/EMMC、NAND)中将代码拷贝出来复制到指定的 RAM 中,一般是 DDR。内部 Boot ROM 要求 IVT 应该放到指定的位置,不同的启动设备位置不同,而 IVT 在整个 load.imx 的最前面,其整个位置都是相对于存储设备的起始地址的偏移。

2024-05-08 20:54:17 1031

原创 嵌入式linux学习第三天汇编语言点灯

反之,时间越多波形就越缓,压摆率就越低。IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00 的寄存器,寄存器地址为 0X020E005C,这个寄存器是 32 位的,但是只用到了最低 5 位,其中bit0~bit3(MUX_MODE)就是设置 GPIO1_IO00 的复用功能的。IMR 寄存器也是一个 GPIO 对应一个位,IMR 寄存器用来控制 GPIO 的中断禁止和使能,如果使能某个 GPIO 的中断,那么设置相应的位为 1 即可,反之,如果要禁止中断,那么就设置相应的位为 0 即可。

2024-05-07 22:19:54 1044 1

原创 嵌入式Linux学习第二天

今天学习linuxC编程。首先要熟悉linux下编写c程序的过程。

2024-05-06 20:01:24 897 1

原创 嵌入式linux学习第一天

参考正点原子Linux开发文档。记录下知识点。

2024-05-06 09:43:57 802 1

原创 FreeRTOS 软件定时器

软件定时器允许设置一段时间,当设置的时间到达之后就执行指定的功能函数,被定时器调用的这个功能函数叫做定时器的回调函数。回调函数的两次执行间隔叫做定时器的定时周期,简而言之,当定时器的定时周期到了以后就会执行回调函数。在实时操作系统(RTOS)中,软件定时器的设计通常是为了在特定的时间点执行一段代码,而这段代码是通过定时器的回调函数来实现的。定时器服务任务(或称为定时器守护任务)是一个特殊的任务,负责管理和执行所有软件定时器的回调函数。任务优先级定时器服务任务通常运行在一个相对较低的优先级。

2024-05-04 14:59:01 1171

原创 FreeRTOS任务通知

此函数也是用来获取任务通知的,不过此函数比 ulTaskNotifyTake()更为强大,不管任务通知用作二值信号量、计数型信号量、队列和事件标志组中的哪一种,都可以使用此函数来获取任务通知。使用任务通知的话效率会更高,任务通知在 FreeRTOS 中是一个可选的功能,任务通知是一个事件,假如某个任务通知的接收任务因为等待任务通知而阻塞的话,向这个接收任务发送任务通知以后就会解除这个任务的阻塞状态。函数只是将任务通知值简单的加一,此函数是个宏,真正执行的是函数 xTaskGenericNotify(),

2024-05-03 20:13:36 1195

原创 FreeRTOS 事件标志组

从上图可以看出时间标志组就是一个整数,分别为无符号16和32位整数,事件标志组的数据类型为 EventGroupHandle_t,当 configUSE_16_BIT_TICKS 为 1 的时候事件标志组可以存储 8 个事件位,当 configUSE_16_BIT_TICKS 为 0 的时候事件标志组存储 24个事件位。此函数用于获取当前事件标志组的值,也就是各个事件位的值。事件位用来表明某个事件是否发生,事件位通常用作事件标志,事件标志组是一组事件标志位的集合, 可以简单的理解事件标志组,就是一个整数。

2024-05-03 10:40:54 958

原创 优先级翻转以及互斥信号量

当阻塞时间1000ms过去后,高优先级抢占,开始获取信号量,但是低优先任务获取信号量后进入delay_ms,占有该信号量,所以此时高优先级任务进入阻塞,此时中优先级任务开始运行,接下来阻塞1000ms,发现1000ms后低优先级还在延时当中,所以中优先级一直运行,直到低优先级释放信号量,此时高优先级任务解除阻塞,继续正常运行。:如果在中断服务例程中,RTOS调度器决定另一个任务比当前运行的任务有更高的运行优先级,那么当中断服务完成,从ISR返回到用户任务执行时,系统会切换到那个更高优先级的任务执行。

2024-05-02 20:47:15 1311 2

原创 Freertos计数和二值信号量学习

有些资料中也将计数型信号量叫做数值信号量,二值信号量相当于长度为 1 的队列,那么计数型信号量就是长度大于 1 的队列。同二值信号量一样,用户不需要关心队列中存储了什么数据,只需要关心队列是否为空即可。计数型信号量通常用于如下两个场合:1、事件计数在这个场合中,每次事件发生的时候就在事件处理函数中释放信号量(增加信号量的计数值),其他任务会获取信号量(信号量计数值减一,信号量值就是队列结构体成员变量uxMessagesWaiting)来处理事件。在这种场合中创建的计数型信号量初始计数值为 0。

2024-05-01 17:02:55 683

原创 FreeRTOS队列

在实际的应用中,常常会遇到一个任务或者中断服务需要和另外一个任务进行“沟通交流”,这个“沟通交流”的过程其实就是消息传递的过程。在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式,但是如果在使用操作系统的应用中用全局变量来传递消息就会涉及到“资源管理”的问题。需要队列的原因如上图所示:当我们同时操作一个变量时候,比如进行a++这个操作,其实内部是分为这三个步骤:读数据、修改数据、写数据。假如同时进行任务1和任务2,a的值是否为2呢。但其实a的值是未知的。

2024-04-20 18:22:33 799

原创 FreeRTOS时间管理

通过检查。

2024-04-16 21:08:01 972

原创 FreeRTOS任务切换学习

所谓任务切换,就是CPU寄存器的切换。假设当由任务A切换到任务B时,主要分为两步:1:需暂停任务A的执行,并将此时任务A的寄存器保存到任务堆栈,这个过程叫做保存现场;2:将任务B的各个寄存器值(被存于任务堆栈中)恢复到CPU寄存器中,这个过程叫做恢复现场;对任务A保存现场,对任务B恢复现场,这个整体的过程称之为:上下文切换。下面要补充几个知识,以便更好理解任务切换。

2024-04-10 22:09:51 976

傅里叶变换C语言实现以及python验证.zip

傅里叶变换C语言实现版本,可用python的matplotlib来验证正确性。里面的程序注释很充分,学习傅里叶变换是一个很有用的帮手

2020-06-28

空空如也

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

TA关注的人

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