task12 总结

                                STM32的应用(大概)

目录

                                STM32的应用(大概)

一、什么是STM32?

(1)来源:

(2)简介:

二.STM32的实际应用

三.做项目需要的流程

1.需求文档

2.方案评估

3.原理图设计

4.PCB设计

5.PCB打板

6.硬件调试:

7.软件测试

8.整机测试

9.生成文档


一、什么是STM32?

(1)来源:

STM32单片机主要是由意法半导体公司设计的微控制器,其具有低功耗、低成本和高性能的特点,适用于嵌入式应用。其采用ARM Cortex-O内核,根据其内核架构的不同,可以将其分成一系列产品,当前主流的产品包括STM32F0、STM32F1、STM32F3,具有超低功耗的产品包括STM32L0、STM32L1、STM32L4等。由于STM32单片机中应用的内核具有先进的架构,使其在实施性能以及功耗控制等方面都具有较强表现,因此在整合和集成方面就有较大的优势,开发起来较为方便,该类型的单片机能非常迅速地实现开发和投入市场,当前市场中这种类型的单片机十分常见,类型多样,包括基础型、智能型和高级型等,应用都比较广泛。

其中,ST公司即意法半导体公司,STM32单片机即是ST(意法半导体)公司使用arm公司的cortex-M3为核心生产的32bit系列的单片机。

(2)简介:

STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARM Cortex-M3内核。按内核架构分为不同产品:其中STM32F系列有:STM32F103“增强型”系列STM32F101“基本型”系列STM32F105、STM32F107“互联型”系列增强型系列时钟频率达到72MHz,是同类产品中性能最高的产品;基本型时钟频率为36MHz,以16位产品的价格得到比16位产品大幅提升的性 能,是32位产品用户的最佳选择。两个系列都内置32K到128K的闪存,不同的是SRAM的最大容量和外设接口的组合。时钟频率72MHz时,从闪存执行代码,STM32功耗36mA,相当于0.5mA/MHz。

二.STM32的实际应用

preview

STM32基于arm cortex核,目前在工业控制、通讯、物联网、车联网等行业应用很火,在功能丰富的同时拥有超高的性价比,大有打败和取缔ARM7的趋势。

三.做项目需要的流程

1.需求文档

2.方案评估

3.原理图设计

例如:STLINK烧录器原理图:

 电路图:

 等....

4.PCB设计

PCB的概念:PCB的英文全称Printed CircuitBoard,PCB的中文名称为印制电路板,又称印刷电路板、印刷线路板,是重要的电子部件,是电子元器件的支撑体,是电子元器件电气连接的提供者。由于它是采用电子印刷术制作的,故被称为“印刷”电路板。

 以上为PCB设计流程

5.PCB打板

PCB打板就是指印制电路板在批量生产前的试产,主要应用为电子工程师在设计好电路,并完成PCB之后,向工厂进行小批量试产的过程,即为PCB打板。而PCB打板的生产数量一般没有具体界线,一般是工程师在产品设计未完成确认和测试之前,都称之为PCB打板。

6.硬件调试:

硬件调试设置步骤:

  1. 安装对应Jlink驱动,将Jlink连接到电脑和开发板JTAG口,并且开发板需要供电(否则,在后面的Setting里无法搜索到cpu)。
  2. 定位到Option – Debug选项卡,右侧选择Use:J-LINK / J-Trace Cortex,然后选择其后的Setting。
  3. 选择Port为SW模式,利用Auto Clk来设置Max Clock。完成后确定。
  4. 定位到Option - Utilities选项卡,上侧同样选择J-LINK / J-Trace Cortex,然后选择其后的Setting。
  5. 这里需要根据不同的mcu选择FLASH的大小。开发板使用的是FLASH=512KB的STM32F103ZET6,所以点击Add后选择512KB型号的STM32。然后选中Reset and Run。完成后确定。
  6. 回到IDE界面,进入debug模式,此时会自动通过Jlink下载程序。然后就可以进行硬件调试了。

7.软件测试

1、点击设置

2、修改晶振为“8.0”

3、点击“Debug”

4、点击“确定”

5、点击“调试”图标

6、对调试内容进行设置,根据个人要求习惯设置,此处只留下“逻辑分析窗口”,可观察端口输出的高低电平转换。

7、对端口进行设置,对显示图形进行调节

8、选择进入外设端口窗口

9、查看端口电平

10、在外设窗口更改GPIOE.5端口为高电平,图形随之改变

8.整机测试

9.生成文档

在实时操作系统(RTOS)中,**Task Context(任务上下文)** 是指一个任务在运行时所依赖的全部“状态信息”。当 RTOS 进行任务切换(Task Switching)时,必须保存当前任务的上下文,并恢复下一个任务的上下文,以确保每个任务都能从中断处继续执行。 --- ### 一、什么是 Task Context? > ✅ **Task Context = CPU 寄存器状态 + 程序执行位置 + 堆栈数据** 它包括: - CPU 通用寄存器(R0-R12 在 ARM Cortex-M) - 程序计数器(PC) - 链接寄存器(LR,返回地址) - 程序状态寄存器(PSR,如 APSR) - 主堆栈指针(MSP)或进程堆栈指针(PSP) - 浮点寄存器(如果启用 FPU) 这些信息被保存在任务的 **堆栈空间** 中。 --- ### 二、为什么需要保存和恢复任务上下文? RTOS 是抢占式或多任务系统,多个任务“并发”运行。但实际上只有一个 CPU 核心,所以通过时间片轮转或优先级调度实现并发。 ```text +------------------+ +------------------+ | Task A | | Task B | | Running | ---> | Running | | R0=1, R1=5 | | R0=3, R1=8 | | PC=0x08001234 | | PC=0x08005678 | +------------------+ +------------------+ ``` 当从 Task A 切换到 Task B 时: 1. 保存 Task A 的所有寄存器值到它的堆栈(`Save Context`) 2. 恢复 Task B 的寄存器值从它的堆栈(`Restore Context`) 3. 跳转到 Task B 上次停止的位置继续执行 这就是 **上下文切换(Context Switch)**。 --- ### 三、FreeRTOS 中的任务上下文示例(ARM Cortex-M) #### 1. 任务创建时初始化上下文 ```c void vTaskStartScheduler(void) { // 创建任务时,手动构造初始上下文 pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0x01000000UL; /* xPSR */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxCode; /* PC = 任务函数入口 */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) prvTaskExit; /* LR = 退出函数(不应到达) */ for( ;; ) { pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 0; /* R12, R3, R2, R1 */ } pxTopOfStack -= 4; *pxTopOfStack = ( StackType_t ) pvParameters; /* R0 = 参数 */ pxTopOfStack -= 8; /* R11 ~ R4 = 初始化为 0 */ memset(pxTopOfStack, 0, 8 * sizeof(StackType_t)); } ``` > ⚙️ 这段代码模拟了任务第一次运行前的“假返回”状态:一旦调度器启动,就会从堆栈中弹出 PC 和寄存器,开始执行任务函数。 --- #### 2. 上下文切换发生时机 - SysTick 中断触发调度 - 当前任务调用 `vTaskDelay()` - 高优先级任务就绪(如信号量释放) - 执行 `taskYIELD()` #### 3. 汇编层上下文切换(Cortex-M PendSV Handler) ```armasm PendSV_Handler: CPSID I ; 关中断(防止嵌套) MRS R0, PSP ; 获取当前任务堆栈指针 ISB LDR R1, =pxCurrentTCB ; 获取当前 TCB 地址 LDR R1, [R1] STR R0, [R1] ; 将 PSP 存入当前 TCB -> pxTopOfStack ; 调用用户函数选择下一个任务 BL vTaskSwitchContext LDR R1, =pxCurrentTCB LDR R1, [R1] LDR R0, [R1] ; 获取新任务的 pxTopOfStack MSR PSP, R0 ; 设置 PSP ISB ORR LR, LR, #0x04 ; 设置 EXC_RETURN 为使用 PSP CPSIE I ; 开中断 BX LR ; 返回线程模式,自动出栈 ``` > 🧠 此汇编代码完成两个核心操作: > - 保存旧任务上下文(通过 PSP 压栈) > - 恢复新任务上下文(通过 PSP 弹栈) --- ### 四、上下文切换过程详解(图文分解) ```text [Before Switch] Task A 运行中: R0=1, R1=2, ..., PC=0x08001000 PSP → [R0][R1][R2]...[PC][xPSR] ← 保存在 Task A 的堆栈 [Tick Interrupt → PendSV] 1. 触发 PendSV 2. CPU 自动压入基本上下文(R0-R3, R12, LR, PC, xPSR) 3. PendSV Handler 手动压入剩余寄存器(R4-R11) [Save Task A Context] PendSV 把 Task A 的完整上下文保存到其堆栈 [Load Task B Context] PendSV 从 Task B 的堆栈恢复所有寄存器(R4-R11, R0-R3, R12, LR, PC, xPSR) 设置 PSP 指向 Task B 堆栈顶部 [Return from PendSV] BX LR 自动触发出栈,CPU 跳转到 Task B 的 PC 继续执行 ``` --- ### 五、如何查看任务上下文?(调试技巧) #### 方法 1:使用调试器查看堆栈内容 在断点暂停后: - 查看 `pxTopOfStack` 字段(在 `TCB_t` 结构体中) - 展开堆栈内存,观察是否包含 PC、LR、R0-R12 等 #### 方法 2:打印任务状态快照 ```c void print_task_context(TaskHandle_t task) { TaskStatus_t status; vTaskGetInfo(task, &status, pdTRUE, eInvalid); printf("Task: %s\n", status.pcTaskName); printf("State: %d\n", status.eCurrentState); printf("Priority: %d\n", status.uxCurrentPriority); printf("Stack High Water Mark: %u\n", status.usStackHighWaterMark); printf("Stack Ptr: 0x%08X\n", (unsigned int)status.pxStackBase); } ``` --- ### 六、常见问题与优化建议 | 问题 | 解决方案 | |------|----------| | 上下文切换太慢 | 减少保存/恢复的寄存器数量(如关闭 FPU) | | 堆栈溢出导致上下文损坏 | 启用 `configCHECK_FOR_STACK_OVERFLOW` | | 中断中频繁触发调度 | 使用 `xHigherPriorityTaskWoken` 延迟调度 | | 多个任务共享同一堆栈 | ❌ 错误!每个任务必须有独立堆栈 | --- ### 七、总结 | 项目 | 内容 | |------|------| | **Task Context 定义** | 任务运行所需的全部 CPU 状态 | | **包含内容** | R0-R12, PC, LR, PSR, PSP, FPU 寄存器等 | | **存储位置** | 每个任务私有的堆栈空间 | | **切换机制** | PendSV + 汇编保存/恢复寄存器 | | **性能影响** | 上下文切换时间 ≈ 几百纳秒 ~ 几微秒(取决于架构) | | **调试工具** | 调试器、SystemView、Tracealyzer | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值