嵌入式系统
灵哎惹,凌沃敏
“任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀的程序员。”
展开
-
Free-RTOS高阶使用手册
FreeRTOS 是市场领先的面向微控制器和小型微处理器的实时操作系统 (RTOS),与世界领先的芯片公司合作开发,现在每 170 秒下载一次。FreeRTOS 通过 MIT 开源许可免费分发,包括一个内核和一组不断丰富的 IoT 库,适用于所有行业领域。FreeRTOS 的构建突出可靠性和易用性。原创 2024-05-15 17:31:25 · 232 阅读 · 0 评论 -
MDK/keil高阶使用手册
MDK/keil的一些高阶使用技巧,很有用原创 2024-05-10 15:49:24 · 672 阅读 · 0 评论 -
记录一个GD32E230的ADC+DMA的重大问题
经过各种研究都没发现问题:正常和不正常情况下ADC和DMA的寄存器值都是一样的,内存也没有越界访问;确认flash读写函数无问题;而且最离谱的是,有的时候开机是正常的,有的时候是异常的,也就说是同一个程序有的时候启动正常,有的时候异常;虽然最后发现了问题,但是也没发现问题,因为还是没搞懂为啥会跟flash读写有关,更没有搞懂为啥同一个程序有时启动就没问题有时就有问题!,即7个通道的数据位置错了,原本1通道的数据到了5通道,5通道的到了3通道!把这一句注释掉了就再也不会出问题了~原创 2024-04-26 11:37:46 · 532 阅读 · 3 评论 -
C/C++提高代码稳定性/健壮性的一些小细节
对于C/C++编程本来就是要摸透两大块,一个是编译器,另一个是相应处理器的内核和外设的知识和特性,这其中编译器是比较容易被忽视的原创 2024-03-29 10:07:58 · 577 阅读 · 0 评论 -
记录一个Cortex-M23的一个重要问题
对于Cortex-M23,它要求按照字访问的内存,其访问地址必须是字(4字节)对齐的,否则就进入Hard_fault原创 2023-09-22 16:36:01 · 528 阅读 · 0 评论 -
关于SVC和PendSV
实时操作系统(Real Time Operating System,简称RTOS)是指当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统做出快速响应,调度一切可利用的资源完成实时任务,并控制所有实时任务协调一致运行的操作系统。提供及时响应和高可靠性是其主要特点。原创 2023-07-21 14:10:11 · 907 阅读 · 0 评论 -
实测STM32 DMA的数据传输速率不如CPU
用CPU和DMA同样搬运32KB的数据(内存到内存),对比搬运耗时。实测下来DMA搬运数据并没有CPU快,使用DMA只是省CPU并不省时间原创 2022-12-29 09:43:18 · 3885 阅读 · 5 评论 -
STM32F4 DMA的关键要点分析
STM32F4 DMA详解,有些比较难理解的概念讲的比较清楚原创 2022-12-14 19:03:56 · 1843 阅读 · 0 评论 -
关于CM3/CM4位带操作的总结
位带操作定义、优越性和使用原创 2022-12-13 15:34:49 · 1103 阅读 · 0 评论 -
关于强制转换数据类型后再存储或发送是否会影响数据字节顺序不一致问题
强制类型转换与数据大小端问题原创 2022-12-07 17:59:33 · 263 阅读 · 0 评论 -
内联函数简介与作用
简介 在计算机科学中,内联函数(有时称作在线函数或编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),从而节省了每次调用函数带来的额外时间开支。但在选择使用内联函数时,必须在程序占用空间和程序执行效率之间进行权衡,因为过多的比较复杂的函数进行内联扩展将带来很大的存储资源开支。另外还需要特别注意的是对递归函数的内联扩展可能引起部分编译器的无穷编译。设计内联函数的动机 ...转载 2022-03-08 15:59:43 · 566 阅读 · 0 评论 -
文件系统类型总结/简介
ext2 早期linux中常用的文件系统 ext3 ext2的升级版,带日志功能 RAMFS 内存文件系统,速度很快 NFS 网络文件系统,由SUN发明,主要用于远程文件共享 MS-DOS MS-DOS文件系统 VFAT Windows 95/98 操作系统采用的文件系统 FAT Windows XP 操作系统采用的文件系统 NTFS Windows NT/XP 操作系统采用的文件系统 HPFS OS/2 操作系统采用的文原创 2022-01-10 14:23:49 · 304 阅读 · 0 评论 -
关于C/C++宏定义/预编译
1.宏定义在函数内部和外部是一样的(都视为在外部),所以一般不把宏定义放在函数内部以免造成误导;如果一个函数里面只有宏定义 那么该函数相当于不存在。2.在一个文件或者多个文件中重复定义一个标志编译不会报错,有的编译器会出警告。3.预编译时对宏定义的处理就是简单的替换,如果说涉及标志重定义的,那么替换时就以最新宏定义为准,关于这点下面作详细说明:假设现在有a.c,a.h,b.c,b.h四个文件:1.先在a.h中定义testdef为20,再在b.h中定义testdef为30,然后在a.c中先包含原创 2022-01-07 18:14:07 · 1386 阅读 · 0 评论 -
关于音频EQ、DRC、等响度、3D环绕音、虚拟低音、变音、AEC、AGC、ANS等解释
1.EQ:EQ是均衡器的缩写。它的基本作用是通过对声音某一个或多个频段进行增益或衰减,达到调整音色的目的。当然,EQ还有一个显著的功能,降噪。EQ通常包括如下参数:F(requency),频率――这是用于设定你要进行调整的频率点用的参数;G(ain),增益――用于调整在你设定好的F值上进行增益或衰减的参数;Q(uantize)――用于设定你要进行增益或衰减的频段 “宽度”。2.DRC(动态压缩)当输出的音频信号不是很大的时候,系统会按照原来的设定输出,但是当输出的音频信号过大的时候,为了保护喇叭原创 2021-12-30 15:06:20 · 13842 阅读 · 0 评论 -
记录:程序跳转前一定要先禁止所有中断
之前在做程序更新时,有发现程序跳转后莫名出现执行异常或卡死问题,后面百般调试发现如果跳转前禁止所有中断的话就好了,但是不知道具体为什么; 今天看到个大神写的文章才知道,原来是在程序跳转后,并且在新程序的__main函数执行之后(该函数负责初始化新程序的内存)并在新程序的SCB->VTOR执行之前刚好发生中断了,而中断中用到的变量的地址刚好和新程序的内存使用空间重合,这样就导致新程序的内存被篡改,导致程序运行不正常或卡死。...原创 2021-12-23 10:30:28 · 437 阅读 · 0 评论 -
记录:HAL释义
HAL:Hardware Abstraction Layer,硬件抽象层硬件抽象层技术最初是由Microsoft公司为确保WindowsNT的稳定性和兼容性而提出的。针对过去Windows系列操作系统经常出现的系统死机或崩溃等现象,Microsoft总结发现,程序设计直接与硬件通信,是造成系统不稳定的主要原因。在得出这个结论的基础上,微软公司在WindowsNT上取消了对硬件的直接访问,首先提出了硬件抽象层(Hardware Abstraction Layer,简称HAL)的概念,硬件抽象层就是:“将硬原创 2021-12-23 10:21:53 · 1909 阅读 · 0 评论 -
按键硬件去抖电路
如图,主要利用了电容的充放电时间来实现去抖;电容越大、电阻越大,充放电时间越长,去抖效果越好,不过太长了按键响应会太长;相反则反之;一般而言用上图的阻容值效果刚好。...原创 2021-08-24 21:38:11 · 3899 阅读 · 1 评论 -
FreeRTOS任务调度
1.FreeRTOS内核支持抢占式调度和时间片轮转调度,默认情况下时间片轮转调度是使能了的,抢占式调度需要用户在FreeRTOSConfig.h中自己使能(configUSE_PREEMPTION)2.抢占式调度用于不同优先级的任务之间,时间片轮转调度用于同优先级任务之间3.有且只有以下5种情况会触发任务切换: 1.有比当前运行任务更高优先级的任务进入了就绪态 2.当前运行任务调用了阻塞函数(如vTaskDelay、等待任务通知、等待信号量等)使自己进入了阻塞态,...原创 2021-07-19 16:52:20 · 961 阅读 · 0 评论 -
Free-RTOS删除当前任务/自己删除自己
使用:vTaskDelete(NULL),但是要注意调用vTaskDelete(NULL)之后任务就在当前语句停止了,其后面的代码不会再被执行。原创 2021-07-19 15:34:04 · 1679 阅读 · 0 评论 -
C/C++ 在宏定义字符串中引用宏定义
需求:现有字符串A,B,C都包含字符串D,如:#define stra "123/456/789"#define strb "111/222/789"#define strc "333/444/789"#define strd "789"以上是对这种情况的最简单粗暴的实现方式,这种方式的缺点就是每次strd改变的时候(如从"789"变成"abc")就需要替换所有的"789",那么有没有其他方式可以不用重复写"789"呢:方式1:#define stra原创 2021-04-06 16:32:20 · 2809 阅读 · 0 评论 -
关于cJSON_Delete导致程序各处free都失败的原因
原因:如果程序中有删除父级的cJSON,则不用在删除父级的cJSON之前删除子级的cJSON了,否则会导致内存分配紊乱(大量free的入口地址找不到),从而导致后续所有的free都失败。 比如,json2是json1的子级,则如果有删除json1的代码就不用了再删除json2了,否则内存紊乱。...原创 2021-03-31 18:51:51 · 2637 阅读 · 2 评论 -
fatfs如何判断一个文件的打开关闭状态
为了防止重复关闭一个文件,我们在关闭之前需要判断该文件是否已经打开:1.在f_close函数中加入对文件指针fp中的文件大小成员清零的代码:2.然后就可以通过判断此成员是否为0来获知该文件是否打开了:...原创 2021-02-03 10:47:44 · 1325 阅读 · 0 评论 -
Free_RTOS错误:Error:..\FreeRTOS\portable\MemMang\heap_4.c,321
意思是某一个任务的堆设置得太小了;本次经查是START_STK_SIZE 设置得太小了(32),改成64或128即可。原创 2020-10-05 00:11:40 · 1788 阅读 · 0 评论 -
关于汇编 BX 和 BLX 跳转指令
BX:跳转到寄存器reg给出的目的地址处,如:BX R2BLX:跳转到寄存区reg给出的目的地址处并将返回地址存储到LR(R14)使用这两个指令时有一点特别需要注意:跳转的目的地址必须是奇数,若不是奇数则在后面加1,如某函数的起始地址是0x80000f00,则要跳转到此函数则应该跳转到0x80000f01处!否则会进入硬件错误中断!...原创 2020-09-22 13:50:39 · 5549 阅读 · 0 评论 -
C/C++ 往指定地址读写的三种方式
嵌入式编程中免不了要往指定地址读/写数据,如配置各种外设时需要写外设的寄存器,下面我总结了三种读写指定地址的方式:我们这次准备使用的是STM32F4的串口3的数据寄存器:USART3->DR,地址0x40004804;1.使用强制转换: 写:*(u16*)0x40004804=0x55; 读:u16 k=0; k=*(u16*)0x40004804;C/C++的强制转换是一个非常重要的知识点,学好了可以为你的编程带来很大的方便,以上就是使用强制转换将数字0x40...原创 2020-09-14 14:50:12 · 8233 阅读 · 1 评论 -
KEA128 CAN问题记录
问题是这样的,我手上有两个CAN的工程,都是间隔一秒往外发送4字节数据,其中一个没问题,但是有一个却总是有时会变成“扩展帧”、“远程帧”之类的(我发送的都是“标准帧-数据帧”),两个工程的CAN初始化、发送接收函数等都是一样的,后面把主函数都改成一样的了,还是不行,最后把两个工程的“SKEAZ1284.h”文件拿来对比了一下,果然发现CAN的初始化结构体“MSCAN_MemMapPtr”有一些些不一样:以下是正常的:typedef struct { __IO uint8_t CANCT...原创 2020-09-10 16:00:27 · 945 阅读 · 0 评论 -
C/C++位处理总结
1.判断变量A的第“x”位是否为1(读取第x位) if(A&(1<<x))2.将变量A的第"x"位置1,而不影响其他位 A|=(1<<x)3.将变量A的第"x"位置0,而不影响其他位 A&=~(1<<x)4.将变量A的第"x"和"x+1"位置1,而不影响其他位 A|=(3<<x)5.将变量A的第"x"和"x+1"位置0,而不影响其他位 A&=~(3<<x)...原创 2020-09-07 11:33:29 · 415 阅读 · 0 评论 -
如何将一个函数编译定位到指定的地址
工程环境:Keil MDK5.31,STM32F407步骤:1.在分散加载(.sct)文件里面新增一个Flash段,段的起始地址就是你想要将该函数定位到的地址,段的大小就是该函数占用的flash大小,当然也可以大于实际大小:2.用宏定义+__attribute__((section))指令在代码中定义这个段:#define MY_FLASH __attribute__((section("my_ro")))3.用刚定义的“MY_FLASH”字段定义函数:MY_FLASH原创 2020-09-04 10:42:48 · 5611 阅读 · 0 评论 -
STM32 CAN滤波器配置注意事项
1.最重要的一点,先看下图:图中显示滤波器可以配置为32位和16位两种模式,当处于32位模式时高11位是标准标识符、中间18位是扩展标识符、低三位为其它;而在16位模式时,高11位才是标准标识符;因此,在配置标准/扩展标识符时要注意左移;如在16位标识符列表模式时,要配置滤波器允许接收标准标识符为0x1234的帧:CAN_FilterInitStructure.CAN_FilterIdHigh=0x1234<<5,左移5位是因为高11位才是标准标识符。2.标准标识符只有11位,因此最原创 2020-08-31 11:05:18 · 3413 阅读 · 0 评论 -
Keil 工程管理中移动分组(group)的位置
当工程比较大时,我们会在工程管理中新建很多分组(group),在新建分组的时候可能会没太考虑分组的排序位置,后续想要移动分组怎么办呢?我们会发现直接鼠标左键长按移动是移动不了的,此时可以在任意分组或工程管理处右键->Manage Components然后出现如下界面:然后就可以用鼠标左键长按移动或者点击上下移动键移动了。...原创 2020-08-27 16:51:36 · 2754 阅读 · 0 评论 -
CPU内核部件之:MMU、MPU、ITCM、DTCM、CCM、Cache
最近了解到了很多关于CPU内核架构中的组件的相关知识,感觉受益颇丰,在这里总结分享下:1.MMU:即内存管理单元,主要工作就是进行虚拟内存地址和物理内存地址的映射,而进行映射的目的有两个:一个是解决物理内存不足以提供给程序运行时的问题,另一个是可以给操作系统的每一个进程提供一个单独独立的虚拟空间。2.MPU:即内存保护单元,主要负责检查将要执行的内存访问操作是否存在违法/违规嫌行为,如堆栈溢出、数组访问越界、内存访问越界等,对于Cortex-M系列处理器来说,当MPU检测到违规操作时将...原创 2020-09-02 10:27:39 · 8190 阅读 · 2 评论 -
Vmware 新建虚拟机点启动时出现“......无法连接到虚拟机”错误
最近用VMware 15.5 安装Ubuntu虚拟机,首先安装VMware时提示了某个错误(具体错误内容忘记了)导致安装不上,百度了一下说是缺少VC++ 2015驱动库,于是网上下载安装了个VC++ 2015,然后成功将VMware装上。 然后新建一个Ubuntu虚拟机,新建完成之后点击“启动”,就出现“......无法连接到虚拟机”错误,然后网上查找解决办法,花了一整天试了好多种办法,还重装了一次系统...结果都没有解决;最后也不知道咋想的我把之前安装的VC++ 2015给卸载了,然后....原创 2020-08-09 20:39:08 · 755 阅读 · 0 评论 -
Error:..\FreeRTOS\portable\RVDS\ARM_CM4F\port.c,768
出现这个报错的时候说明:刚刚发生的中断中调用了系统的API函数,但是该中断的优先级超出了系统可管理的优先级范围;降低该中断的优先级或扩大系统可管理优先级范围即可解决。原创 2020-07-24 11:24:56 · 2784 阅读 · 1 评论 -
KEA128 移植/嵌入Free_RTOS
话不多说,直接上步骤:1.准备一个KEA128的空工程,如LED闪烁工程2.去除工程中的PendSV_Handler和SVC_Handler,以免报错重定义3.将Free_RTOS相关文件复制入系统,这里我是从原子的工程里面复制来的4.将RTOS系统文件加入工程,KEA128是CM0+内核的,所以port.c应该选择 portable\RVDS\ARM_CM0中的5.修改FreeRTOSConfig.h中的各项宏定义: 1.configUSE_PORT_OPTIMISED_...原创 2020-06-19 17:47:07 · 471 阅读 · 0 评论