- 博客(48)
- 收藏
- 关注
原创 CMSIS_DAP函数库的介绍
可以发现DAP.c中的函数都是静态函数,只有DAP_ProcessCommand可以外部使用,具体的使用流程就是通过这个函数来调用其他函数。
2024-04-23 10:59:01
551
原创 JTAG引脚定义的学习
是用于与设备中新加入的寄存器交互数据,以此来实现这个测试方法。定义中的TRST引脚,用来复位TAP控制器的。在STM32系列单片机中,并没有TRST引脚,名字为NJTRST。J-link是德国SEGGER公司的。ST-link是ST意法半导体公司的。,可以访问芯片内部的信号逻辑状态,还有芯片引脚的状态等等。德国SEGGER公司的Jlink的JTAG接口。多核的芯片,其芯片内部已经接成了菊花链的形式。,跟医生的听诊器似的,可探听芯片内部小心思。接口中,最常用的信号有四个,分别是。的使用,也可以组成菊花链的。
2024-04-23 10:54:43
543
原创 在STM32中给固定的地址写入一个值,并通过memory窗口进行查看
一个是FLASH,一个是RAMRAM是易失存储器,FLASH是非易失存储器,这是最直观的解释。其次对stm32中FLASH和RAM的内存地址的认识stm32中的RAM一般是SRAM(静态随机存储器),起始地址为0x20000000Flash的起始地址为0x80000000.也可以在设置里边看到。
2024-04-16 11:04:26
1117
原创 GPIO端口的BSRR的使用
接着看这个类型的定义可以看到BSRR为无符号的32位的整形可以看到为无符号的16位置的整形。//给高16位写1 对寄存器高 16bit 写1 对应管脚为低电平 写 0。
2024-03-27 20:27:51
798
原创 30-CPU利用率
用户想要使用 CPU 利用率统计的话,需要自定义配置一下,首先在FreeRTOSConfig.h 配置与系统运行时间和任务状态收集有关的配置选项,并且实现portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() 与portGET_RUN_TIME_COUNTER_VALUE()这两个宏定义利用一个高精度的定时器vTaskGetRunTimeStats()和 vTaskList()函数获得任务的相关信息与 CPU 使用率的相关信息。
2024-03-23 10:34:21
206
原创 29-中断管理
屏蔽的,也就是说即使在系统进入临界段的时候,这些中断也能被触发而不是等到退出临界段的时候才被触发,当然,这些中断服务函数中也不能调用。临界段代码也叫做临界区,是指那些必须完整运行,不能被打断的代码段,比如有的外设的初始化需要严格的时序,初始化过程中不能被打断。的,当 basepri 设置为某个值的时候,NVIC 不会响应比该优先级低的中断,而优先级比之更高的中断则不受影响。这个宏设置的值高(带等于)的中断都被关闭,比这值小的中断没有被关闭(优先级号越大,优先级越低)。细看一下下边的寄存器的配置的含义。
2024-03-22 15:07:10
370
原创 28-内存管理
标准 C 库中的 malloc()和 free()也可以实现动态内存管理,但是如下原因限制了其使用:● 这些函数在小型嵌入式系统中并不总是可用的,小型嵌入式设备中的 RAM 不足。● 它们的实现可能非常的大,占据了相当大的一块代码空间。● 他们几乎都不是安全的。● 它们并不是确定的,每次调用这些函数执行的时间可能都不一样。● 它们有可能产生碎片。● 这两个函数会使得链接器配置得复杂。来替代malloc()函数来替代free()。
2024-03-22 15:06:56
891
原创 27-任务通知
FreeRTOS 从 V8.2.0 版本开始提供任务通知这个功能,每个任务都有一个 32 位的通知值,在大多数情况下,任务通知可以替代二值信号量、计数信号量、事件组,也可以替代长度为 1 的队列(可以保存一个 32位整数或指针值)。xTaskNotifyWait() 用于通用型得全功能得获取任务通知(消息队列,二值信号量、计数信号量、事件组)xTaskGenericNotify() 发送任务通知函数(这是通用的在任务中发送任务通知的API函数)这个任务控制块的结构体与任务创建的结构是一样的。
2024-03-21 20:19:23
484
原创 26-软件定时器
自带的定时器是硬件定时器。硬件定时器是芯片自身提供的一个功能。一般是通过外部晶振提供给芯片输入时钟,芯片向软件模块提供一组配置的寄存器,通过对寄存器的设置,能够实现定时的功能,当到达指定的时候后,芯片中断控制器会产生一个时钟中断。然后在中断函数中触发。定时器,是指从指定的时刻开始,经过一个指定时间,然后触发一个超时事件,用户可以自定义定时器的周期与频率。软件定时器相当于是一个任务,但这个任务触发然后去调用一个函数(回调函数),在回调函数中不能设置任何阻塞的API函数。
2024-03-21 20:17:04
996
原创 25-事件
EventBits_t uxEventBits 这个的含义是事件组有几位,在config.h的宏定义中,configUSE_16_BIT_TICKS 定义为 0,那么 uxEventBits 是 32 位的,有 24 个位用来实现事件标志组。configUSE_16_BIT_TICKS 定义为 1,那么 uxEventBits 是 16 位的,有 8 个位用来实现事件标志组。事件组置位函数 xEventGroupSetBits() 事件组置位函数 xEventGroupSetBitsFromISR()
2024-03-20 14:31:03
898
原创 24-互斥量
在互斥访问中互斥信号量相当于一个钥匙,当任务想要使用资源的时候就必须先获得这个钥匙,当使用完资源以后就必须归还这个钥匙,这样其他的任务就可以拿着这个钥匙去使用资源。优先级翻转的意思就是高优先级的任务也得等待低优先级的任务执行完成后,再去执行 (正常高优先级任务应该比低优先级任务能抢占资源)将低优先级任务的优先级 提高到 与所有等待资源的任务中 优先级最高的任务的优先级 相同。●任务可能会多次获取互斥量的情况下。因此优先级翻转的算法:将正在占用某个资源的任务的优先级提高到与所有等待资源的任务中。
2024-03-20 14:30:41
593
原创 23-二值信号量和计数信号量
在某个任务使用信号量后,互斥信号量就会变空,此时其他任务想要获取信号量,就会进入阻塞状态,保证了临界资源。每当某个事件发生的时候,任务或中断就会释放一个信号量,此时信号量的数值就会加1,当处理事件的时候,任务就会取走一个信号量,此时信号量的数值就会减去=1,信号量的数值就表示还有多少个事件没有被处理。xSemaphoreTake(),信号量获取函数(可用于二值信号量,计数信号量,互斥信号量,不能用于递归信号量的获取)在中断函数中释放信号量的时候,任务一仍然可以获得信号量,此时就是任务一和中断函数的同步。
2024-03-19 09:47:08
683
原创 21-消息队列控制块
(6)、(入队阻塞)用于发送消息阻塞的一个列表,用于保存阻塞在队列的任务(入队阻塞的时候,记录任务,任务按照优先级在列表中排序,由于消息队列已经满了,想要发送消息的任务就无法发送消息)(7)、(出队阻塞)获取消息阻塞的一个列表,用来保存阻塞在队列的任务,任务按照优先级进行排序,由于队列是空的,想要获取消息是无法获取消息的。(12) (入队)队列上锁之后,存储从队列发送的一个列表项的数目,即入队的数量,如果队列没有上锁,就会设置为一个具体的宏。(2)、指向队列消息存储区的结束位置的地址(即队尾)
2024-03-19 09:46:15
369
原创 20-消息队列
当任务将一个数据发送到队列时,此时这个数据是拷贝进入队列的,在任务中,这个数据还可以发生改变,这并不会影响队列内已经存进去的值,数据改变后,可以重新传入队列。队列又称消息队列,是一种常用于任务间通信的数据结构,队列可以在任务与任务间、中断和任务间传递信息,实现了任务接收来自其他任务或中断的不固定长度的消息。数据发送到队列中会导致数据拷贝,也就是将要发送的数据拷贝到队列中,这就意味着在队列中存储的是数据的原始值,而不是原数据的。通过消息队列符,任务和任务之间,任务与中断之间可以进行数据的通信。
2024-03-18 09:10:57
834
原创 发现一个关于按键的上拉电阻和下拉电阻的问题
将程序烧录发现,一上电,LED1不亮,LED2亮,这是正常的,此时按下按钮1,LED1亮,松开按键1,LED1灭,但是,按下PA1按键,LED2没反应。开始给pin引脚一个1的值,当按下按键时,pin的值变为0,这是灯也会跟着按键变亮和变灭。开始给PIn引脚一个0的值,当按键按下时,pin的值变为1,这是灯也会跟着按键变亮和变灭。当我给一个按键设置为上拉电阻输入,用这个按键去控制LED灯,LED灯可以正常的被控制。当我给一个按键设置为下拉电阻输入,用这个按键去控制LED灯,按键并不能控制LED灯。
2024-03-18 09:08:22
573
原创 19-任务设计要点
中断服务函数是一种特别需要注意上下文的环境,运行在非任务的执行环境下,在这个执行环境中,不能使用挂起当前任务的操作(1、在在运行任务A的时候,被阻塞,会执行任务B,任务B执行完后,已经超过了任务A的响应时间,就会影响到实时性。任务的优先级,任务的中断处理,任务的运行时间、逻辑、状态都需要清楚的知道,才能对程序的运行了如指掌。(一般在中断服务函数中只做标记事件的发生,然后通知任务,让相关任务执行相关处理)),这样低优先级的任务就会无法运行,因此需要在合适的位置,添加阻塞状态。保证CPU每时每刻都有事情做。
2024-03-11 20:22:06
141
原创 18-任务管理常用API函数
恢复的任务会保留挂起前的信息,在恢复的时候根据挂起时的状态继续运行。注意:任务删除函数并不会释放对应的内存,因此,在使用任务删除函数之前,需要先将对应的内存释放掉,然后再进行删除任务。当调度器被挂起的时候,如果有中断需要进行上下文切换,那么这个任务就会被挂起,再调度器恢复之后,才能执行任务的切换。其实就是将调度器锁定,直白点挂起所有的任务,就是挂起任务调度器,调度器被挂起后,就不可以进行上下文的切换,如果删除自己的话,传入NULL就可以,如果删除其他任务的话,传入其他任务的句柄。这个函数延时的时间精确。
2024-03-11 20:21:24
219
原创 17-任务状态
阻塞:如果当前任务在等待某个时序或外部中断时,就说这个任务处于阻塞态(任务被挂起,任务被延时、任务正在等待信号量、读写队列、读写事件等等)总之:任务处于挂起态,系统就不会去管这个任务,任务处于阻塞态,系统还需要时不时去看一下这个阻塞是否可以解除。任务处于阻塞的时候,系统还需要判读处于阻塞态的这个任务是否超时,是否可以解除阻塞。6、7、8、任务从就绪态、运行态、阻塞态进入挂起态就必须通过挂起函数来进入挂起态。9、任务从挂起态进入就绪态,只能通过恢复函数来进入就绪态。从挂起态恢复的唯一方法就是。
2024-03-10 13:14:47
397
原创 16逻辑代码的执行流程
首先创建开始任务,然后开启任务调度器,开始任务优先级大于空闲任务优先级,执行开始任务函数,开始任务函数内部创建应用任务一,应用任务一的优先级与开始任务优先级相同,然后去执行应用任务一,执行一个时间片,然后跳到开始任务,开始任务也执行一个时间片,然后再跳到应用程序一执行一个时间片,以此来循环执行。当开启任务调度器,由于开始任务优先级比空闲任务优先级高,所以会执行开始任务,然后再开始任务内,创建任务一,任务一的优先级比开始任务优先级高,所以会执行任务一函数,当任务一函数内有阻塞的时候,会暂停任务一,
2024-03-10 13:14:29
384
原创 15-单片机烧录FreeTOS操作系统后,程序的执行流程
通过复位函数来初始化系统的时钟,然后再执行__main,初始化系统的堆和栈,然后跳转到main函数。因为创建只是把任务添加到系统中,还。因为在FreeRTOS中会自动帮助我们做一些初始化的工作,比如。,在FreeRTOS中创建任务的时候,系统会自动帮助我们完成。1、在系统上电后,第一个执行的是启动文件由汇编语言编写的。SVC(系统服务调用,亦简称系统调用)用于任务启动。没有去实现调度,并且没有实现空闲任务和定时器任务。,这些都是在开启任务调度函数的时候实现的。例如,动态创建任务的函数中就有。
2024-03-09 09:30:14
395
原创 14动态内存创建任务与静态内存创建任务的区别
而动态方法FreeRTOS会在开启任务调度函数(vTaskStartScheduler();静态任务需要自己手动分配内存:宏定义的时候需要设置。,静态使用xTaskCreateStatic()动态使用xTaskCreate()而动态方法不需要定义这两个宏。静态任务需要自己手动添加 空。创建任务使用的函数不同。
2024-03-09 09:29:52
106
原创 11-列表删除函数和列表遍历函数
FreeRTOS提供了一个函数,每调用一次这个函数,pxIndex就会指向下一个列表项,并返回这个列表项中的pxOwner(设置列表项属于那个任务控制块)函数的参数pxTCB是用来保存pxIndex所指向的列表项中的pxOwner(是列表项归哪一个所拥有,通常是任务控制块)列表项删除函数只会将列表项从列表中移除,并不会将列表项的内存释放掉。如果列表项是动态内存分布的,删除列表项是由下方这个函数来实现。函数的返回值是删除列表项后,列表中列表项的数量。这个函数传递的参数是要删除的列表项。这是一个函数的宏定义。
2024-03-08 09:39:05
132
原创 10-列表项插入函数
这个图是列表初始状态下列表项的位置(注意pxIndex的指向listItem1)这是插入后的,可以发现ListItem3是插入到ListItem1的前边。列表项插入的原理与双向链表(环形链表)类似(理解起来很重要)先获取pxIndex的值,确定pxIndex指向的列表项。列表是一个双向的链表(环形的链表),尾就是头,头就是尾。(列表项是按照升序的方式进行插入的)继续插入一个列表项,值为60。继续插入一个列表项,值为50。函数的名称,以及变量的定义。在空列表中插入一个列表项。
2024-03-08 09:37:47
482
原创 9-列表和列表项的初始化
(记住一个概念——里边中的最后一个列表项是不计入列表中的列表项的数量的值的)pvContainer是用来记录列表项归那一个列表拥有。列表的初始化(对比列表和列表项的创建来看)(6)和(7)是用来检查列表的完整性。下边两条是检查列表项的完整性。
2024-03-08 09:37:28
118
原创 8-列表和列表项
列表用来跟踪FreeRTOS的任务。与列表有关的代码都定义在list.h和list.c中。因为有的地方用不到列表项那么全的参数,会造成内存浪费。列表项有两种,一种是列表项,一种是Mini列表项。列表项是存放在列表中的项目。列表项(类似双向链表)为什么有迷你列表项?
2024-03-07 09:13:27
250
原创 7-任务创建
在裸机实验中,系统的主体就是一个main函数,所有的功能都是在main函数中的循环实现的,在这个循环中,CPU是按照顺序的执行来完成各种事情的。任务控制块相当于这个任务的身份,里边存储的任务的所有信息(任务的栈指针,任务名称,任务的形参)栈空间通常是预定义的全局数组,也可以是动态分配的一段内存空间,最后存储在栈中。在多任务系统中,每个任务都是独立的,互不干扰的,需要为每一个任务分配栈空间。在多任务系统中,任务的执行是由系统的调度来实现各个任务之间的切换。任务函数的主体是一个无限循环,不能返回的。
2024-03-06 21:31:03
204
原创 6-FreeRTOS将ZE板子改为C8t6需要修改的地方
此时,去以前的C8T6的项目中寻找md.s的启动文件,并复制粘贴到这个项目中。注意ZE项目中的启动文件是hd,然而c8t6的启动文件应该是md.s。查看lED.h中的对LED引脚的定义,与自己开发板上的引脚进行对应。将此处的STM32F103ZE修改为STM32F103C8。然后更改C/C++,,把此处的HD修改为MD。此处系统总的堆栈的大小不能超过RAM的大小。然后,编译,发现会有14个错误。因此需要修改为12*2024。双击文件夹,进行添加文件。具体如何区分看解释;右击将这个文件移除掉。
2024-03-06 09:55:09
234
1
原创 5-FreeRTOS移植操作步骤
第二步,在新项目中添加FreeRTOS文件夹,并从FreeRTOS的源码项目中,将需要的文件(Source文件夹下方的所有文件)复制到新项目中。在RVDS文件夹中的ARM_CM3(我用的是stm32F103c8t6板子)文件夹中的port.c源文件。为FreeRTOS_core文件夹中添加文件,将FreeRTOS文件夹中的第一层目录下的源文件添加进来。为FreeRTOS_port文件夹中添加文件,在portable文件中的源文件。去寻找这两个文件(一个已经建好的项目中),然后复制过来进行替换。
2024-03-05 09:20:41
287
原创 4-FreeRTOS移植-文件介绍
本次学习FreeRTOS采用的是V9.0.0版本,因为FreeRTOS被亚马逊收购后,出来的是V10.0版本,它里边添加了一些基于云端的物联网的组件,学习的话,用不到,所以选择V9.0.0版本。Heap文件必须使用一个,因为FreeRTOS创建内核对象的时候使用的是动态内存分布,而动态内存分配的函数就是在这几个文件中实现的。FreeRTOS是一个软件,单片机是一个硬件,FreeRTOS想要运行在一个硬件上的时候,是需要将两者关联在一起的。接口文件是与硬件相关的,不同的接口适配不同的硬件。
2024-03-04 08:50:39
669
原创 3-FreeRTOS编程风格
如果一个变量是无符号型的那么会有一个前缀 u,如果是一个指针变量则会有一个前缀 p。因此,当我们定义一个无符号的 char 型变量的时候会加一个 uc 前缀,当定义一个char型的指针变量的时候会有一个pc前缀。②xQueueReceive()函数的返回值为 portBASE_TYPE 型,在 queue.c 这个文件中定义。还有其他的数据类型,比如数据结构,任务句柄,队列句柄等定义的变量名的前缀也是 x。如果是私有的函数则会加一个prv(private)的前缀。,short型变量的前缀是。
2024-03-03 21:27:32
241
原创 1-实时操作系统的选型
简单的小系统通常是前后台系统,这样的程序包括一个死循环和若干个中断服务程序 :应用程序是一个无限循环,循环中调用API函数完成所需的操作,这个大循环就叫做后台系统。• 在实时操作系统 中,我们可以把要实现的功能划分为多个任务,每个任务负责实现其中的一部 分,每个任务都是一个很简单的程序,通常是一个死循环。• RTOS操作系统: • FreeRTOS,UCOS,RTX,RT-Thread,DJYOS等。• RTOS操作系统: • FreeRTOS,UCOS,RTX,RT-Thread,DJYOS等。
2024-03-03 10:40:40
379
原创 自制串口调试助手第四步(测试串口)
此时需要另外一个串口工具来进行测试。(如果自己有现成的,可以直接用,没有的话,可以在文末进行下载)注意,添加的串口是两两一组的,相当于是COM1与COM2是相互连接的。打开串口(设置串口号为COM2和波特率为115200)至此,串口调试助手制作完成。
2024-03-02 13:56:18
348
原创 自制串口调试助手第三步
鼠标点击click的名字,按F12,即可跳转。首先将方法引用进来,声明两个属性。在XMAL中,为三个按钮添加事件。至此,串口调试助手制作完成。综上,方法建立完毕。
2024-03-01 20:20:45
438
1
原创 虚拟串口VSPD工具使用方法
链接:https://pan.baidu.com/s/1MLaEOoWOieIz_Il0eoWv_w提取码:sgt1解压压缩包,进行安装。解压后安装完成后,将解压文件中dll复制,在安装路径中进行替换。
2024-02-29 17:06:52
291
原创 自制串口调试助手第一步,搭建xmal界面
Grid类具有ColumnDefinitions和RowDefinitions两个属性,分别是ColumnDefinition和RowDefinition的集合,表示Grid定义了多少列、多少行。其次,将整个Grid分成四块,即定义两行两列,对于列,分为3份,第一个占2份,第二个占1份。接下来,添加Lable文本控件和ComboBox下拉列表控件。至此,整个串口调试助手的界面就搭建成功了。其次,添加接收数据的textBox。我这里选择的是.net8.0。先了解一下Grid布局元素。最后,添加三个按钮即可。
2024-02-29 16:26:19
1010
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人