- 博客(96)
- 资源 (1)
- 收藏
- 关注
原创 Keil5软件仿真error65报错解决
使用STM32F407编写代码,进行Keil5仿真时,代码一直在 SystemInit函数中出不去。可以正常仿真了(一次次尝试出更精确的简单软件延时函数)进入Options(魔术棒)中的Debug。(根据第二步的SIM参数,修改。
2024-07-28 23:43:37
285
原创 【uC/OS-III篇】uC/OS-III 入门教程-两个任务切换(滴答定时器提供OS节拍)
上一篇博客:【uC/OS-III篇】uC/OS-III 创建第一个任务(For STM32)-CSDN博客 中使用的延时函数是软件延时但是软件延时一方面不精确,另一方面并不会引起任务的调度所以想要使用精确的延时,就需要使用到STM32的滴答定时器,并且利用滴答定时器为 uC/OS-III 操作系统提供节拍观察STM32F103的参考手册中的时钟章节,能够发现SYSTEM时钟是经过 72MHz(最高)8分频后的,所以滴答定时器的时钟一般为: 72MHz / 8 = 9MHz简单来说:默认滴答定时器的
2024-04-30 23:32:26
1118
原创 设置Linux开发板开机自启动QT程序的报错解决办法
PS:下面这个脚本是最终的脚本,文章所展示的是我解决问题的调试过程,最后发现只需要加一句 s。是自己编写的自启动脚本,内容例如下:(也可以将这些直接写到。在移植QT的时候我们设置了一些链接库的路径,终端里运行。环境变量中,添加内容后的启动脚本如下所示。环境变量中,添加内容后的启动脚本如下所示。将这些路径复制下来,修改启动脚本如下所示。在系统中寻找 fonts 文件。将这些路径复制下来,添加到。将这些路径复制下来,添加到。然后重启开发板,出现新报错。然后重启开发板,出现新报错。终端运行如下命令,获取。
2024-04-23 13:37:33
1203
原创 双机 Cartogtapher 建图文件配置
这个必须设置正确,否则TF树连接不成功,一般设置为地盘的 link name为了区别其他的无人车,我这里加了前缀 “car1/”
2024-03-31 18:58:18
1251
1
原创 【uC/OS-III篇】uC/OS-III 创建第一个任务(For STM32)
例如至少会创建空闲任务(OS_IdleTask)和时钟节拍任务。 (3)将原本的DCM.DLL改成 DARMSTM.DLL ,Parameter 修改为自己的板子型号,例如 -pSTM32F103C8。还可能创建统计任务(OS_StackTask())、定时任务(OS_TmrTask())、中断处理队列管理任务(OS_IntQTask())空闲任务主要在其他任务不运行的时候运行,空闲任务优先级最低,默认为63(uC/OS的优先级规则是数字越小优先级越高,默认0~63)(1)设置频率为8MHz。
2024-03-31 18:30:27
725
原创 【uC/OS-III篇】uC/OS-III 移植到 STM32 简明教程
uC/OS-III 是 MicroC/OS-III 的一种版本,是由 Micrium 公司开发的一款实时操作系统(RTOS)。以下是有关 uC/OS-III 的一些介绍:发布时间和来源:uC/OS-III 于 2008 年发布,由 Jean Labrosse 创立的 Micrium 公司开发。Micrium 公司专注于提供嵌入式系统软件解决方案,包括实时操作系统、TCP/IP 协议栈、USB 协议栈等。
2024-03-31 18:05:47
2426
3
原创 C语言编写二维数组环形缓冲区
定义 rplidar_ranges 二维数组,保存10组数据,每组360个数据定义 rplidar_front 指针,指向二维数组中的第一个数组,代表存入数据指针定义 rplidar_tail 指针,指向二维数组中的第一个数组,代表取出数据指针。
2024-02-29 14:03:12
499
1
原创 mmap底层驱动实现(remap_pfn_range函数)
PS:注意到读写进程的pfn_start相同,这个值是映射的物理内存地址,vm->vm_pgoff 是偏移(单位页,一页=4K(4096))在驱动代码中,打印出 buff 的地址,可以看到内核中(驱动代码中)申请的 buff 空间存在于进程虚拟地址空间中的内核空间部分。表示的是 vm->vm_flags,"rw"表示可读可写,"s"表示 share共享,"p"表示 private 私有。以上图中的写进程为例,画出进程虚拟地址空间中内存映射部分,和物理内存被映射的部分。当读和写的进程内存映射地址的。
2023-10-07 10:04:36
1062
原创 添加驱动模块到内核的两种方法
如果要编译进内核中, CONFIG_MYKEY 选项选择为 Y ,然后执行 make zImage,会发现生成的zImage镜像大小增加了一些,但是不会在 drivers/char/mykey/ 下生成 key.ko ,不过会生成 key.o。如果只有一两个源文件,则可以选择不新建文件夹,直接将 mykey.c 放入到 drivers/char/ 目录下,在 drivers/char/ 目录下的 Makefile 中添加如下指令即可。在 drivers/char/ 下的 Makefile 中添加一行。
2023-10-05 10:08:30
1400
原创 C语言编译与链接过程详解
局部变量,所以他们的默认值都为0 ,故为了节省.o文件的空间,无需存储,但是需要在符号表中记录,在最后执行可执行文件后,将bss段的符号存到虚拟地址空间中。标出了每个符号处于那个段,占多大内存,其中 a1 标记为 *COM* 表示它是弱符号(未初始化的非静态全局变量,可能其他文件里也定义了同名的)如上图所示,text段合并,data段合并,bss段合并的同时,需要将弱符号转化为强符号(或者弱符号被强符号替换),bss段大小增加。 为符号分配虚拟内存地址,符号的地址是根据段的地址加上自身的偏移计算的。
2023-10-02 15:10:56
808
原创 module_init 底层实现原理
【内核中__init 和module_init宏的作用】例如,如果initcall_levels被设置为2,则在系统启动的第三个阶段(即设备驱动初始化阶段)中
2023-09-13 11:36:45
885
原创 一文说清mmap内存映射底层原理(以LCD中的Framebuffer为例)
前几天的一场面试中,面试官问:为什么可以通过mmap直接操作LCD?当时回答的不大好,刚学习的时候没有在意底层的逻辑,所以这几天对于mmap内存映射机制进行了较为深入的学习,这里分享出来一些个人的学习记录,如果有不恰当的地方还请各位帮忙指出。
2023-09-11 02:41:41
1746
1
原创 【IMX6ULL驱动开发学习】24.关于mmap为什么能直接操作LCD显示
所以当我们操作mmap返回的指针时,实际上内核中虚拟内存的内容也会被修改。实际上我们在内核中使用malloc申请一个内存空间后,在用户态使用。Framebuffer实际上是一块保存了一帧图像数据的内存,那为什么可以直接操作到文件呢,其中的映射关系怎么实现的?记录今天面试过程中遇到的一个提问,当时没有答上来。返回一个指针,就可以通过这个指针来操作文件。MMU(内存管理单元)
2023-09-07 19:21:58
521
原创 【Linux之进程间通信】09.有名管道和无名管道(补充)
有名管道是真实存在的一个特殊文件,所以当进程退出后,管道文件还在,有名管道文件将继续保存在文件系统中以便以后使用,其他进程仍然可以读写管道数据。有名管道具有路径名与之关联,只要可以访问该路径,就能够彼此通过FIFO相互通信。
2023-09-07 12:10:30
221
原创 【IMX6ULL驱动开发学习】23.驱动模块开发之Makefile解析
编写完驱动代码后要编写Makefile,并使用make进行编译,这里举一个最经典的驱动模块的Makefile写法。执行 make 之后,会执行Makefile下的 all:后面的命令。
2023-08-24 10:33:44
626
原创 uboot通过NFS挂载根文件系统卡死解决办法(VFS: Unable to mount root fs via NFs, trying floppy)
uboot通过NFS挂载根文件系统时,加载完内核后,卡死在这里。setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs rw nfsroot=192.168.1.200:/home/me/imx6ull_nfs ip=192.168.1.100:192.168.1.200:192.168.1.1:255.255.255.0::eth0 off'
2023-08-14 13:02:08
1149
1
原创 Linux系统中的自旋锁(两幅图清晰说明)
多CPU下的自旋锁采取的是忙等待(原地打转)机制,虽然忙等待的线程占用了它所在的cpu,但其他线程仍可放到其他CPU上执行。所以自旋锁上锁和解锁之间的临界区代码要尽量的短,最好不要超过5行,否则采取忙等待的线程会浪费过多的cpu资源。单cpu下的自旋锁采用的是睡眠机制,因为忙等待会使仅有可怜的一个cpu被其占用,而拥有自旋锁的线程得不到执行无法释放锁,会引起死锁。
2023-08-10 00:07:41
378
原创 【IMX6ULL驱动开发学习】22.IMX6ULL开发板读取ADC(以MQ-135为例)
IMX6ULL一共有两个ADC,每个ADC都有八个通道,但他们共用一个ADC控制器
2023-08-02 11:02:04
2536
2
原创 【IMX6ULL驱动开发学习】21.Linux驱动之PWM子系统(以SG90舵机为例)
我们要在设备树(.dts)文件中引用和使能该节点,同时指定好pwm映射到的GPIO引脚(即pinctrl子系统,我这里映射到了GPIO1_9上)
2023-08-01 15:08:10
2422
2
转载 IMX6 GPIO设置为输出时gpiod_get_value结果一直为1
IMX6 GPIO设置为输出时gpiod_get_value结果一直为1。解决方法:配置SION位,使IO口在输出状态下可以正确获取状态。
2023-07-27 09:41:16
389
原创 FreeRTOS栈溢出检测机制_附源码分析
freertos 提供了栈溢出检测功能,可以通过 **FreeRTOSConfig.h**文件中定义 **configCHECK_FOR_STACK_OVERFLOW** 宏来开启, **在任务切换时会自动执行检测栈溢出操作**
2023-07-25 11:09:53
1292
原创 【IMX6ULL驱动开发学习】19.mmap内存映射
mmap将一个文件或者其它对象映射进内存,使得应用层可以直接读取到驱动层的数据,无需通过copy_to_user函数可以用于像LCD这样的外设, 需要读写大量数据的
2023-07-12 17:38:47
840
原创 【IMX6ULL驱动开发学习】18.中断下半部(tasklet、工作队列、中断线程化)
下图表述了Linux内核的中断处理机制,为了在中断执行时间尽量短和中断处理需完成的工作尽量大之间找到一个平衡点, Linux将中断处理程序分解为两个半部:(Top Half) 和用于完成尽量少的的功能, 它往往只是简单地读取寄存器中的中断状态, 并在清除中断标志后就进行“登记中断”的工作。意味着中去。这样, 顶半部执行的速度就会很快, 从而可以服务更多的中断请求。几乎做了中断处理程序所有的事情, 而且, 这也是底半部和顶半部的最大不同, 因为顶半部往往被设计成不可中断。
2023-07-12 15:43:35
736
原创 【IMX6ULL驱动开发学习】17.内核定时器(按键消抖)
内核定时器初始化 setup_timer(struct timer_list *timer, void (*function)(unsigned long), unsigned long data);
2023-07-12 10:42:17
706
原创 【IMX6ULL驱动开发学习】16.睡眠机制_poll机制_fasync异步通知(按键控制LED)
学完了休眠唤醒机制、poll机制、异步通知、定时器、tasklet、工作队列、mmap、input子系统后,该沉淀沉淀了
2023-07-11 21:50:29
647
原创 【IMX6ULL驱动开发学习】15.IMX6ULL驱动开发问题记录(sleep被kill_fasync打断)
sleep函数是可以被中断的,也就是说当进程在睡眠的过程中,如果被中断,那么当中断结束回来再执行该进程的时候,该进程会从sleep函数的下一条语句执行。学习异步通知的时候,自己实现一个功能:按键控制蜂鸣器,同时LED灯在闪烁。打断,所以sleep没有执行完就重新进入下一次循环了。说明kill_fasync这个函数中有中断发生。结果:LED好像也同时被按键控制了。修改代码后解决该问题。
2023-07-04 22:57:08
984
2
原创 【IMX6ULL驱动开发学习】14.Linux驱动开发 - GPIO中断(设备树 + GPIO子系统)
(根据GPIO子系统标号得到软件中断号)针对正点原子IMX6ULL阿尔法开发板。(根据软件中断号发起请求中断)(获取GPIO子系统标号)(获得GPIO的数量)
2023-06-30 15:23:00
1208
原创 【IMX6ULL驱动开发学习】13.Pinctrl子系统与GPIO子系统
驱动开发中,我们可以使用寄存器对外设进行操作,但是那样太麻烦了所以引入了 Pinctrl子系统与GPIO子系统。Pinctrl子系统:可以用它来复用引脚、配置引脚的电气属性等等。GPIO子系统:控制引脚,设置输入输出。
2023-06-27 21:23:37
573
原创 【IMX6ULL驱动开发学习】12.Linux驱动之设备树
(1)platform_driver 结构体添加 of_match_table 属性,添加 of_device_id 结构体,匹配设备树。(2)在 probe 函数中提取设备树中的引脚,提取设备树节点中的属性(of_property_read_u32等函数)后缀为 dtb 的是二进制的设备树文件,我们需要修改它,那么真正要操作的是其对应的 dts 文件,即。其他地方都不用修改,下次想添加外设时,直接修改设备树,然后修改 of_device_id 结构体即可。即可替换成新的设备树了,如何查看是否替换成功呢。
2023-06-27 00:50:14
1723
原创 【IMX6ULL驱动开发学习】11.驱动设计之面向对象_分层思想(学习设备树过渡部分)
经过分层之后,我们需要添加一个新的外设时,只需要做两个步骤:(1)在 xxx_board.c 中添加硬件引脚资源(2)在 xxx_chip_gpio.c 中添加具体的GPIO初始化、控制等操作驱动层的 xxx_drv.c 根本不需要怎么修改前几天自己总结了个图,也是帮助自己梳理思路看上去有些乱,不过只要学过韦东山老师视频的。
2023-06-25 17:36:58
580
原创 【IMX6ULL驱动开发学习】10.设置uboot,通过tftp服务器加载内核与设备树,通过nfs挂载根文件系统
这里设置console为ttymxc0,因为linux启动以后I.MX6ULL 的串口1在linux下的设备文件就是/dev/ttymxc0,115200是串口的波特率。用来设置根文件系统的位置,root=/dev/mmcblk1p2 用于指明根文件系统存放在mmcblk1 设备的分区 2 中。主要设置 TFTP_DIRECTORY=“/home/me/tftpboot”,设置tftp共享目录。/Linux内核文件/arch/arm/boot//Linux内核文件/arch/arm/boot/dts。
2023-06-24 21:01:49
2721
原创 【IMX6ULL驱动开发学习】09.Linux驱动之GPIO中断(附SR501人体红外感应驱动代码)
转到底,这样反应会灵敏些;跳线帽接到H上,即可重复模式,有人一直高电平,无人一直低电平。5V供电,输出引脚我接到了正点原子IMX6ULL阿尔法开发板的GPIO1_IO2上。(中断编程不需要设置GPIO输入输出,当然申请GPIO,设置输入也没问题)由于在中断函数中输出信息了,所以检测到有人无人时,中断会自动打印出信息。参数:int irq, void *dev_id。,因为既然已经进入中断函数了,那就是已经执行了。类型(见下图),一般选择。(上升沿、下降沿等)主要注意参数和返回值。再次查看中断发生次数。
2023-06-15 14:41:47
3126
原创 【IMX6ULL驱动开发学习】08.IMX6ULL通过GPIO子系统函数点亮LED
查看原理图,发现led接的引脚是 GPIO1_IO3,对应 /sys/kernel/debug/gpio 中的。在之前的hello驱动程序基础上修改,使用上面的GPIO子系统函数,添加一些逻辑性的代码即可。(可是实际操作中设置为4才能点亮LED,这里不知道是什么道理,懂得朋友麻烦评论区指点一下)记住这里传入的第二个参数 “user_led”,后面验证的时候会看到。1.1 确定 led 的GPIO标号,查看内核中的gpiochip。与之前的hello应用程序区别不大,直接贴代码。1.5 设置GPIO方向。
2023-06-13 22:35:25
1922
原创 【IMX6ULL驱动开发学习】07.cdev注册驱动设备_设置次设备号范围
如果我使用 mknod 创建一个 /dev/abc 设备,主设备号也是240,次设备号 设置为1,linux内核提供的主设备号是有限的,如果设备很多的情况下主设备号就可能不够用了。因为 register_chrdev 函数使得分配的主设备号下的所有次设备号。分配设备号的方式比较简单直接,但是会导致设备占用所有的次设备号。注册驱动设备时,采用cdev函数注册,分配两个次设备号0、1。比如我的hello驱动主设备号是240,次设备号是0,在之前的hello驱动中,注册驱动设备的方式如下。
2023-06-12 13:22:01
684
原创 【IMX6ULL驱动开发学习】06.APP与驱动程序传输数据+自动创建设备节点(hello驱动)
APP与驱动程序传输数据原理:1. APP调用**open函数**打开设备,使用**系统IO函数write**写入数据到设备; 2. 系统调用驱动程序的**写操作函数(通过file_operations结构体指定)**,将APP中传入的参数传入该**写操作函数**; 3. 驱动程序的写操作函数调用**copy_from_user**函数**从用户程序中拷贝数据**到驱动程序中; 4. APP调用**系统IO函数read**,读取驱动数据; 5. 系统调用驱动程序的**读操作函数(通过file_operat
2023-06-11 16:22:18
1216
1
原创 【IMX6ULL驱动开发学习】05.IMX6ULL驱动开发_编写第一个hello驱动【熬夜肝】
1、获取内核文件 获取Linux内核文件,可以从Linux Kernel官网下载,我这里为了跟开发板中的系统一致,避免出现其他问题,所以使用的韦东山老师提供的Linux-4.9.88内核文件,2、编译内核文件 为什么要编译内核文件,因为驱动代码的编译要基于
2023-06-09 00:01:34
2547
1
原创 【IMX6ULL驱动开发学习】04.IMX6ULL开发板与虚拟机互传文件(scp、SFTP、NFS)
这样就可以在开发板的 /mnt 目录下访问到虚拟机的 /home/me/Linux_ARM/IMX6ULL/hello_driver 目录下的文件了,无论在哪一边增改文件,另一边都能实时同步。表示 /home/me/Linux_ARM/IMX6ULL 目录下的文件都可以被挂载共享**(这一步必须做)**当然也可以将当前设备下的文件拷贝到远端,命令后面两个路径,前后位置调换一下即可。我们要做的是将虚拟机下的目录挂载到IMX6ULL开发板的/mnt目录下。这里便可以连接上我们的开发板,看到开发板下的文件了。
2023-06-08 14:45:44
1600
原创 【IMX6ULL驱动开发学习】03.设置IMX6ULL开发板与虚拟机在同一网段(设置开发板静态IP)
开发板ping虚拟机(如果ping不通,拔掉网线再插上,重启板子,重复几次还ping不通,检查Ubuntu的防火墙是否没有关闭),右键 “ 断开连接” ,再看看自己当前的网络连接,看看哪个ens设备没了,那那个ens设备就是你的桥接网卡了。按照上图步骤手动设置IP,根据window下有线网卡的网段来设置,网段是192.168.1,最后一个数从。如果只显示了一个lo设备,或者只有一个ens设备和lo设备,则说明桥接的网卡没有启动起来。好的,再右键小电脑图标,连接好桥接网卡,点击。
2023-06-08 14:33:50
2580
7
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人