freertos随意记录
freertos是一个开源免费的嵌入式实时操作系统非常好用也比较简单对freertos的学习过程做一些记录。1、移植freertos的移植应该是比较简单的下载官方最新版的LTS版本然后拷贝一些文件和做一些设置就行了。a、文件复制在目标工程下新建文件夹freertos将freertos-kernel根目录下的C文件复制到前面的文件夹中复制including文件夹复制portable文件夹中的文件我使用的是正点原子的STM32H750开发板使用的keil ac6创建的工程文件目录及文件如下另外freertos还有内存管理复制下列文件到工程目录freertos还需要一个用于裁剪代码的配置文件直接复制example里面的至此文件的拷贝已经完成了。完整目录结构如下b、工程配置新建一个hal工程把开发板上的led灯和串口初始化然后配置工程添加头文件freertos的任务切换有几个非常重要的中断函数PendSV_Handler SysTick_Handler SVC_Handler这是任务切换的关键需要注释掉hal工程中stm32h7xx_it.c中的这几个函数并在freertosconfig.h文件中添加下列代码让stm32h750的中断和freertos内核的中断关联起来freertos的框架已经搭建起来了下面需要调用freertos的入口函数vTaskStartScheduler()这个地方要注意不要添加错了我之前就添加成xPortStartScheduler()找了好久才发现。vTaskStartScheduler里面会调用xPortStartScheduler不过在这之前需要进行一些闲置任务这些初始化。完成上面这些freertos已经在运行了为了观看效果新建几个任务这是几个简单的任务led和printf任务其中led是可以阻塞的print则没有阻塞。非常不建议print这种写法因为该任务不会离开RUN状态会一直执行导致优先级比他低的任务没有机会执行包括IDLE任务这里仅仅是为了测试项目中千万不要这样写每个任务一定需要离开RUN状态要么延时等待要么等待信号量这些。通过测试print优先级18几个任务都可以正常运行print优先级高于20print任务正常运行led任务无法运行。2、学习记录任务切换原理某个任务正在执行但是系统时钟也在运行其中systick中断设置为1000HZ每1ms进入一次systick中断看下systickHandler干了啥#define xPortSysTickHandler SysTick_Handler void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt * executes all interrupts must be unmasked. There is therefore no need to * save and then restore the interrupt mask value as its value is already * known. */ // 屏蔽掉中断优先级低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断我们认为优先级低于这个值的中断可以被屏蔽 portDISABLE_INTERRUPTS(); traceISR_ENTER(); { /* Increment the RTOS tick. */ // 系统tick累加 if( xTaskIncrementTick() ! pdFALSE ) { traceISR_EXIT_TO_SCHEDULER(); /* A context switch is required. Context switching is performed in * the PendSV interrupt. Pend the PendSV interrupt. */ // 产生pendSV中断请求 // portmacro.h文件如下 // #define portNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) // #define portNVIC_PENDSVSET_BIT ( 1UL 28UL ) portNVIC_INT_CTRL_REG portNVIC_PENDSVSET_BIT; } else { traceISR_EXIT(); } } portENABLE_INTERRUPTS(); }其中产生pendSV中断请求从上面的代码可以看出systick中断就干了一件事产生pendSV中断。下面看看pendSV中断又干了啥void xPortPendSVHandler( void ) { /* This is a naked function. */ __asm volatile ( mrs r0, psp \n isb \n \n ldr r3, pxCurrentTCB \n /* Get the location of the current TCB. */ ldr r2, [r3] \n \n tst r14, #0x10 \n /* Is the task using the FPU context? If so, push high vfp registers. */ it eq \n vstmdbeq r0!, {s16-s31} \n \n stmdb r0!, {r4-r11, r14} \n /* Save the core registers. */ str r0, [r2] \n /* Save the new top of stack into the first member of the TCB. */ \n stmdb sp!, {r0, r3} \n mov r0, %0 \n cpsid i \n /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ msr basepri, r0 \n dsb \n isb \n cpsie i \n /* ARM Cortex-M7 r0p1 Errata 837070 workaround. */ bl vTaskSwitchContext \n mov r0, #0 \n msr basepri, r0 \n ldmia sp!, {r0, r3} \n \n ldr r1, [r3] \n /* The first item in pxCurrentTCB is the task top of stack. */ ldr r0, [r1] \n \n ldmia r0!, {r4-r11, r14} \n /* Pop the core registers. */ \n tst r14, #0x10 \n /* Is the task using the FPU context? If so, pop the high vfp registers too. */ it eq \n vldmiaeq r0!, {s16-s31} \n \n msr psp, r0 \n isb \n \n #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata workaround. */ #if WORKAROUND_PMU_CM001 1 push { r14 } \n pop { pc } \n #endif #endif \n bx r14 \n \n .ltorg \n ::i ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) ); } void vTaskSwitchContext( void ) { /** 无关代码 ***/ // 查找当前ready的最高优先级并把pxCurrentTCB赋值为最高优先级TCB中的下一个TCB taskSELECT_HIGHEST_PRIORITY_TASK(); portTASK_SWITCH_HOOK( pxCurrentTCB ); } #define taskSELECT_HIGHEST_PRIORITY_TASK() \ do { \ UBaseType_t uxTopPriority uxTopReadyPriority; \ \ /* Find the highest priority queue that contains ready tasks. */ \ while( listLIST_IS_EMPTY( ( pxReadyTasksLists[ uxTopPriority ] ) ) ! pdFALSE ) \ { \ configASSERT( uxTopPriority ); \ --uxTopPriority; \ } \ \ /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ * the same priority get an equal share of the processor time. */ \ listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, ( pxReadyTasksLists[ uxTopPriority ] ) ); \ uxTopReadyPriority uxTopPriority; \ } while( 0 ) /* taskSELECT_HIGHEST_PRIORITY_TASK */ ldr r3, pxCurrentTCB \n /* Get the location of the current TCB. */获取到当前的任务的TCB bl vTaskSwitchContext \n任务切换函数寻找处于ready的最高优先级并把pxCurrentTCB赋值为最高优先级中的下一个如果有如果没有不变后面的代码看注释知道是加载pxCurrentTCB中的寄存器值然后进行跳转完成任务切换。最后看一下SVCHandlervoid vPortSVCHandler( void ) { __asm volatile ( ldr r3, pxCurrentTCB \n /* Restore the context. */ ldr r1, [r3] \n /* Get the pxCurrentTCB address. */ ldr r0, [r1] \n /* The first item in pxCurrentTCB is the task top of stack. */ ldmia r0!, {r4-r11, r14} \n /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ msr psp, r0 \n /* Restore the task stack pointer. */ isb \n mov r0, #0 \n msr basepri, r0 \n bx r14 \n \n .ltorg \n ); } static void prvPortStartFirstTask( void ) { /* Start the first task. This also clears the bit that indicates the FPU is * in use in case the FPU was used before the scheduler was started - which * would otherwise result in the unnecessary leaving of space in the SVC stack * for lazy saving of FPU registers. */ __asm volatile ( ldr r0, 0xE000ED08 \n /* Use the NVIC offset register to locate the stack. */ ldr r0, [r0] \n ldr r0, [r0] \n msr msp, r0 \n /* Set the msp back to the start of the stack. */ mov r0, #0 \n /* Clear the bit that indicates the FPU is in use, see comment above. */ msr control, r0 \n cpsie i \n /* Globally enable interrupts. */ cpsie f \n dsb \n isb \n svc 0 \n /* System call to start first task. */ nop \n .ltorg \n ); } BaseType_t xPortStartScheduler( void ) { prvPortStartFirstTask(); }这个代码貌似只执行一次就是在vTaskStartScheduler中会执行一次启动第一个任务。configMAX_SYSCALL_INTERRUPT_PRIORITY设置系统最高优先级即如果代码中有优先级大于优先级数值小于configMAX_SYSCALL_INTERRUPT_PRIORITY 的中断不受freertos控制可以正常产生中断如果代码中有优先级小于configMAX_SYSCALL_INTERRUPT_PRIORITY 的中断则会因为freertos调用vPortEnterCritical()函数进入临界状态无法进入中断。比如串口非常重要不想让串口被系统打断那么如果configMAX_SYSCALL_INTERRUPT_PRIORITY设置为16串口的中断优先级就需要设置为16;按键中断不是很重要可能在发送数据的时候不需要响应按键可以把按键的中断优先级设置为大于16那么在进入临界状态时候按键中断是无法响应的。// 进入临界状态禁止中断 void vPortEnterCritical( void ) { // 进入临界状态禁止中断 portDISABLE_INTERRUPTS(); uxCriticalNesting; /* This is not the interrupt safe version of the enter critical function so * assert() if it is being called from an interrupt context. Only API * functions that end in FromISR can be used in an interrupt. Only assert if * the critical nesting count is 1 to protect against recursive calls if the * assert function also uses a critical section. */ if( uxCriticalNesting 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG portVECTACTIVE_MASK ) 0 ); } } #define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() // 将configMAX_SYSCALL_INTERRUPT_PRIORITY 的值写入basepri屏蔽优先级小于configMAX_SYSCALL_INTERRUPT_PRIORITY 的中断优先级数值大于configMAX_SYSCALL_INTERRUPT_PRIORITY portFORCE_INLINE static void vPortRaiseBASEPRI( void ) { uint32_t ulNewBASEPRI; __asm volatile ( mov %0, %1 \n \ cpsid i \n \ msr basepri, %0 \n \ isb \n \ dsb \n \ cpsie i \n \ : r ( ulNewBASEPRI ) : i ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : memory ); }在更精巧的设计中需要对中断掩蔽进行更细腻的控制——只掩蔽优先级低于某一阈值 的中断——它们的优先级在数字上大于等于某个数。那么这个数存储在哪里就存储在 BASEPRI中。不过如果往BASEPRI中写0则另当别论——BASEPRI将停止掩蔽任何中断。例 如如果你需要掩蔽所有优先级不高于0x60的中断则可以如下编程 MOV R0, #0x60 MSR BASEPRI, R0 如果需要取消BASEPRI 对中断的掩蔽则示例代码如下 MOV R0, #0 MSR BASEPRI, R0 《CORTEX M3 权威指南》退出临界状态void vPortExitCritical( void ) { configASSERT( uxCriticalNesting ); uxCriticalNesting--; if( uxCriticalNesting 0 ) { portENABLE_INTERRUPTS(); } } #define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() #define portENABLE_INTERRUPTS() vPortSetBASEPRI( 0 ) // 将0写入basepri恢复所有中断 portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) { __asm volatile ( msr basepri, %0 ::r ( ulNewMaskValue ) : memory ); }待续...

相关新闻

什么是外盘期货

什么是外盘期货

外盘期货,也称为境外期货,是指在中国大陆以外的合规交易所挂牌上市、公开流通的标准化期货合约,与国内四大交易所运行的内盘期货相对应,是全球主流的大宗商品与金融指数交易品类。它依托国际成熟金融市场运行,价格由全…

2026/7/31 6:07:47 阅读更多 →
轻量鞋材助剂赋能产业发展

轻量鞋材助剂赋能产业发展

现代鞋材行业持续迭代,轻量化、高颜值、高品质成为PVC鞋材核心发展方向,而助剂的合理搭配是提升PVC鞋材综合品质的关键。佳百特(jabetter)深耕PVC鞋材助剂领域多年,打造的PVC鞋材稳定剂(PVC shoe material stabilizer)…

2026/7/31 3:49:11 阅读更多 →
AS01/AS02/AS03固定资产界面增强

AS01/AS02/AS03固定资产界面增强

增强效果如下:CMOD:创建增强-》AIST0002在EXIT_SAPLAIST_002实现如下代码:ANLA I_ANLA . ANLV I_ANLV . ANLU I_ANLU . GD_MODE I_MODE . GD_XSUBNO I_XSUBNO . GT_ANLZ[] T_ANLZ[] . GT_ANLB[] T_ANLB[] .GV_XMXG I_ANLU-XMXG. GV_FLAG . GV_C…

2026/7/30 21:26:35 阅读更多 →

最新新闻

jQuery文件上传下载实战:6种方案与安全优化

jQuery文件上传下载实战:6种方案与安全优化

1. jQuery文件上传下载的核心挑战与解决方案全景图在Web应用开发中,文件传输功能就像城市中的物流系统——看似简单的基础设施,却直接影响着整个系统的运转效率。作为前端开发的中坚力量,jQuery虽然不像现代框架那样自带完善的文件处理方案&a…

2026/8/1 6:22:07 阅读更多 →
BehaviorInfer空间智能双引擎:镜像视界视频孪生驱动城市级交通流动态推演与闭环管控

BehaviorInfer空间智能双引擎:镜像视界视频孪生驱动城市级交通流动态推演与闭环管控

BehaviorInfer空间智能双引擎:镜像视界视频孪生驱动城市级交通流动态推演与闭环管控 一、核心导语 当前城市智慧交通治理普遍存在点位感知碎片化、车流推演静态化、事件处置被动化、全域管控无闭环的行业痛点。传统交通监控体系仅依托单点摄像头、地磁、雷达完成基…

2026/8/1 6:22:07 阅读更多 →
PageRank算法实战:维基百科人物影响力分析与网络构建

PageRank算法实战:维基百科人物影响力分析与网络构建

这次我们来看一个结合经典算法与开放数据的实用项目:用谷歌PageRank算法分析维基百科人物关系网络,找出最具影响力的百位历史人物。这个项目不仅展示了PageRank在社交网络分析中的实际应用,还提供了一套完整的从数据获取到结果可视化的技术方…

2026/8/1 6:22:07 阅读更多 →
AI定制开发凭什么敢先出原型-三轮48小时是怎么跑通的

AI定制开发凭什么敢先出原型-三轮48小时是怎么跑通的

# AI定制开发凭什么敢先出原型-三轮48小时是怎么跑通的## 引言接一个企业 AI 定制项目,多数服务商的流程是这样的。先签合同,再收首付款,然后花一两个月做需求调研,调研完出方案,方案确认后再开发,开发完客…

2026/8/1 6:22:07 阅读更多 →
导师要求降重到15%以下,有哪些真正值得体验的的降AI率平台推荐?

导师要求降重到15%以下,有哪些真正值得体验的的降AI率平台推荐?

毕业论文降AI率,核心在语义重构 去AI痕迹 降低查重率,选对工具事半功倍。建议结合免费试用与付费深度服务,灵活应对不同需求。下面按中文、英文、免费/付费分类推荐,附实测效果与适用场景。 一、中文论文降重工具(最…

2026/8/1 6:22:07 阅读更多 →
微电网经济调度中的两阶段鲁棒优化方法与实践

微电网经济调度中的两阶段鲁棒优化方法与实践

1. 微电网经济调度与鲁棒优化的现实需求微电网作为分布式能源系统的核心单元,其经济调度问题一直是能源领域的研究热点。传统确定性优化方法在面对光伏出力波动、负荷预测偏差等不确定性因素时,往往表现出"脆弱性"——即在最坏场景下可能导致系…

2026/8/1 6:21:07 阅读更多 →

日新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/1 0:00:48 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/1 0:00:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/1 0:00:48 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/31 1:03:03 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/8/1 5:19:34 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/31 4:19:39 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/1 0:00:48 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/1 0:00:48 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/1 0:00:48 阅读更多 →