| 作者 |
| 刘火良 杨森 |
| 丛书名 |
| 电子与嵌入式系统设计丛书 |
| 出版社 |
| 机械工业出版社 |
| ISBN |
| 9781909181455 |
| 简要 |
| 简介 |
| 内容简介书籍计算机书籍 ---------------------------LwIP应用开发实战指南:基于STM32--------------------------- 本书以LwIP源码为核心,讲解TCP/IP协议栈的实现,讲解常见的网络协议,讲解LwIP各层之间的数据传递,最终辅以实战案例,教你如何连接各大云平台,配套野火STM32 M4/M7系列开发板,提供完整源代码,极具操作性。 ---------------------------FreeRTOS内核实现与应用开发实战指南:基于STM32--------------------------- 本书基于野火STM32全系列开发板介绍FreeRTOS内核实现与应用开发,全书分为两部分:第一部分教你如何从0到1把FreeRTOS内核写出来,从底层的汇编开始,讲解任务如何定义、如何切换,还讲解了阻塞延时如何实现,如何支持多优先级,如何实现定时器以及时间片等FreeRTOS的核心知识点;第二部分则开始讲解FreeRTOS内核组件的应用以及如何使用FreeRTOS进行多任务编程。 本书内容翔实,案例丰富,配有大量示例代码,适合作为嵌入式领域工程师和爱好者的技术参考书,也适合相关专业的学生学习参考。 |
| 目录 |
---------------------------LwIP应用开发实战指南:基于STM32--------------------------- 前 言 第1章 网络协议概述 1 1.1 常用网络协议 1 1.2 网络协议的分层模型 2 1.3 协议层报文间的封装与拆封 3 第2章 LwIP概述 5 2.1 LwIP的优缺点 5 2.2 LwIP的文件说明 6 2.2.1 获取LwIP源码文件 6 2.2.2 LwIP文件说明 8 2.3 LwIP的说明文档 11 2.4 使用vs code查看源码 14 2.4.1 查看文件中的符号列表和函数列表 14 2.4.2 函数定义跳转 15 2.5 LwIP源码里的示例 16 2.6 LwIP的3种编程接口 17 2.6.1 RAW/Callback API 17 2.6.2 Netconn API 18 2.6.3 Socket API 19 第3章 开发平台 20 3.1 以太网概述 20 3.1.1 PHY层 20 3.1.2 MAC子层 21 3.2 STM32的ETH外设 23 3.3 MII和RMII接口 24 3.4 PHY:LAN8720A 25 3.5 硬件设计 27 3.6 软件设计 29 3.6.1 获取STM32的裸机工程模板 29 3.6.2 添加bsp_eth.c与bsp_eth.h 29 3.6.3 修改stm32f4xx_hal_conf.h文件 35 第4章 LwIP的网络接口管理 37 4.1 netif结构体 37 4.2 netif的使用 41 4.3 与netif相关的底层函数 45 4.4 ethernetif.c文件内容 46 4.4.1 ethernetif数据结构 46 4.4.2 ethernetif_init() 47 4.4.3 low_level_init() 48 第5章 LwIP的内存管理 50 5.1 几种内存分配策略 50 5.1.1 固定大小的内存块 50 5.1.2 可变长度分配 51 5.2 动态内存池 52 5.2.1 内存池的预处理 52 5.2.2 内存池的初始化 57 5.2.3 内存分配 58 5.2.4 内存释放 59 5.3 动态内存堆 61 5.3.1 内存堆的组织结构 61 5.3.2 内存堆初始化 62 5.3.3 内存分配 64 5.3.4 内存释放 67 5.4 使用C库的malloc和free函数来管理内存 71 5.5 LwIP中的配置 72 第6章 网络数据包 74 6.1 TCP/IP的分层思想 74 6.2 LwIP的线程模型 75 6.3 pbuf结构体说明 76 6.4 pbuf的类型 77 6.4.1 PBUF_RAM类型的pbuf 78 6.4.2 PBUF_POOL类型的pbuf 78 6.4.3 PBUF_ROM和PBUF_REF类型的pbuf 80 6.5 pbuf_alloc() 81 6.6 pbuf_free() 84 6.7 其他pbuf操作函数 88 6.7.1 pbuf_realloc() 88 6.7.2 pbuf_header() 88 6.7.3 pbuf_take()、pbuf_copy()、pbuf_chain()和pbuf_ref() 88 6.8 网卡中使用的pbuf 88 6.8.1 low_level_output() 88 6.8.2 low_level_input() 91 6.8.3 ethernetif_input() 93 第7章 无操作系统移植LwIP 94 7.1 将LwIP添加到裸机工程 94 7.2 移植头文件 97 7.3 移植网卡驱动 103 7.4 LwIP时基 111 7.5 协议栈初始化 112 7.6 获取数据包 114 7.6.1 查询方式 114 7.6.2 ping命令详解 115 7.6.3 中断方式 116 第8章 有操作系统移植LwIP 119 8.1 向LwIP中添加操作系统 119 8.1.1 复制FreeRTOS源码到工程文件夹 119 8.1.2 添加FreeRTOS源码到工程组文件夹 120 8.1.3 指定FreeRTOS头文件的路径 120 8.1.4 修改stm32f10x_it.c 121 8.2 lwipopts.h文件需要加入的配置 122 8.3 sys_arch.c/h文件的编写 126 8.4 网卡底层的编写 136 8.5 协议栈初始化 138 8.6 移植后使用ping命令测试基本响应 141 第9章 LwIP一探究竟 142 9.1 网卡数据传入LwIP内核的流程 142 9.2 内核超时处理 142 9.2.1 sys_timeo结构体与超时链表 144 9.2.2 注册超时事件 144 9.2.3 超时检查 147 9.3 tcpip_thread线程 149 9.4 LwIP中的消息 151 9.4.1 消息结构 151 9.4.2 数据包消息 153 9.4.3 API消息 154 9.5 揭开LwIP的神秘面纱 158 第10章 ARP 159 10.1 数据链路层概述 159 10.2 MAC地址的基本概念 159 10.3 初识ARP 160 10.4 以太网帧结构 160 10.5 IP地址映射为物理地址 161 10.6 ARP缓存表 162 10.7 ARP缓存表的超时处理 165 10.8 ARP报文 167 10.9 发送ARP请求包 170 10.10 数据包接收流程 172 10.10.1 以太网中数据包的接收 172 10.10.2 ARP数据包处理 176 10.10.3 更新ARP缓存表 178 10.11 数据包发送流程 182 10.11.1 etharp_output() 182 10.11.2 etharp_output_to_arp_index() 185 10.11.3 etharp_query() 186 第11章 IP 193 11.1 IP地址 193 11.1.1 概述 193 11.1.2 IP地址编址 193 11.1.3 特殊IP地址 195 11.2 局域网和广域网的概念 196 11.2.1 局域网 196 11.2.2 广域网 196 11.3 网络地址转换 197 11.4 IP数据报 198 11.5 IP数据报的数据结构 202 11.6 IP数据报分片 204 11.7 IP数据报发送 208 11.8 IP数据报接收 214 第12章 ICMP 222 12.1 ICMP功能简介 222 12.2 ICMP报文结构 223 12.3 ICMP报文类型 224 12.3.1 ICMP差错报告报文 224 12.3.2 ICMP查询报文 226 12.4 LwIP中的ICMP实现 227 12.4.1 ICMP报文数据结构 227 12.4.2 发送ICMP差错报文 229 12.4.3 处理ICMP报文 231 第13章 TCP 235 13.1 TCP服务概述 235 13.2 TCP的特性 235 13.2.1 连接机制 235 13.2.2 确认与重传 235 13.2.3 缓冲机制 236 13.2.4 全双工通信 236 13.2.5 流量控制 236 13.2.6 差错控制 237 13.2.7 拥塞控制 237 13.3 端口号的概念 237 13.4 TCP报文段结构 239 13.4.1 TCP报文段的封装 239 13.4.2 TCP报文段格式 239 13.5 TCP连接 243 13.5.1 “三次握手”建立连接 243 13.5.2 “四次挥手”终止连接 246 13.6 TCP状态 247 13.6.1 LwIP中定义的TCP状态 247 13.6.2 TCP状态转移 248 13.7 TCP中的数据结构 250 13.8 窗口的概念 253 13.8.1 接收窗口 254 13.8.2 发送窗口 254 13.9 TCP报文段处理 255 13.9.1 报文段缓冲队列 255 13.9.2 TCP报文段发送 256 13.9.3 TCP报文段接收 260 第14章 UDP 265 14.1 UDP概述 265 14.2 UDP常用端口号 266 14.3 UDP报文 266 14.4 UDP报文的数据结构 267 14.4.1 UDP报文首部结构体 267 14.4.2 UDP控制块 267 14.5 UDP报文发送 270 14.6 UDP报文接收 272 第15章 使用Netconn接口编程 277 15.1 netbuf结构体 277 15.2 netbuf相关函数说明 279 15.2.1 netbuf_new() 279 15.2.2 netbuf_delete() 279 15.2.3 netbuf_alloc() 280 15.2.4 netbuf_free() 280 15.2.5 netbuf_ref() 281 15.2.6 netbuf_chain() 282 15.2.7 netbuf_data() 282 15.2.8 netbuf_next()与netbuf_first() 282 15.2.9 netbuf_copy() 283 15.2.10 netbuf_take() 284 15.2.11 其他操作netbuf的宏定义 285 15.3 netconn结构体 285 15.4 netconn函数接口说明 287 15.4.1 netconn_new() 287 15.4.2 netconn_delete() 288 15.4.3 netconn_getaddr() 290 15.4.4 netconn_bind() 290 15.4.5 netconn_connect() 291 15.4.6 netconn_disconnect() 292 15.4.7 netconn_listen() 293 15.4.8 netconn_accept() 293 15.4.9 netconn_recv() 295 15.4.10 netconn_send() 296 15.4.11 netconn_sendto() 297 15.4.12 netconn_write() 298 15.4.13 netconn_close() 301 15.5 实验 302 15.5.1 TCP Client实验 302 15.5.2 TCP Client实验现象 307 15.5.3 TCP Server实验 308 15.5.4 TCP Server实验现象 314 15.5.5 UDP实验 315 15.5.6 UDP实验现象 319 第16章 使用Socket接口编程 321 16.1 什么是Socket 321 16.2 LwIP中的Socket 321 16.3 Socket API 322 16.3.1 socket() 322 16.3.2 bind() 323 16.3.3 connect() 324 16.3.4 listen() 325 16.3.5 accept() 325 16.3.6 read()、recv()、recvfrom() 325 16.3.7 sendto() 326 16.3.8 send() 327 16.3.9 write() 327 16.3.10 close() 327 16.3.11 ioctl()、ioctlsocket() 327 16.3.12 setsockopt() 328 16.3.13 getsockopt() 329 16.4 实验 329 16.4.1 TCP Client实验 329 16.4.2 TCP Server实验 331 16.4.3 UDP实验 333 第17章 使用RAW API接口编程 335 17.1 RAW API的UDP编程 335 17.1.1 新建控制块:udp_new() 335 17.1.2 绑定控制块:udp_bind() 336 17.1.3 建立会话:udp_connect() 337 17.1.4 断开会话:udp_disconnect() 338 17.1.5 接收数据:udp_recv() 339 17.1.6 发送数据:udp_send()与udp_sendto() 339 17.1.7 删除UDP控制块:udp_remove() 341 17.2 RAW API的TCP编程 341 17.2.1 新建控制块:tcp_new() 341 17.2.2 绑定控制块:tcp_bind() 342 17.2.3 控制块监听:tcp_listen() 343 17.2.4 处理连接:tcp_accept() 345 17.2.5 建立连接:tcp_connect() 346 17.2.6 终止连接:tcp_close() 348 17.2.7 接收数据:tcp_recv() 350 17.2.8 发送数据:tcp_sent() 350 17.2.9 异常处理:tcp_err() 351 17.2.10 周期性回调:tcp_poll() 351 17.2.11 构建报文段:tcp_write() 352 17.2.12 更新接收窗口:tcp_recved() 352 17.3 实验 353 17.3.1 TCP Client实验 353 17.3.2 TCP Server实验 358 17.3.3 UDP实验 360 第18章 使用JPerf工具测试网速 362 18.1 iPerf与JPerf 362 18.2 测试网络速度 362 18.2.1 获取JPerf网络测速工具 362 18.2.2 测试开发板接收速度(Netconn API) 363 18.2.3 测试开发板接收速度(Socket API) 366 18.2.4 测试开发板发送速度(Netconn API) 369 18.2.5 测试开发板发送速度(Socket API) 372 18.3 提高LwIP网络传输的速度 375 第19章 HTTP 377 19.1 什么是HTTP 377 19.2 URL与资源 378 19.3 HTTP报文 379 19.4 使用Postman获取论坛数据 380 19.5 使用开发板获取论坛数据 382 第20章 HTTP服务器 386 20.1 Hello World网页demo 386 20.2 提供网页控制LED开关的功能 389 第21章 MQTT协议 394 21.1 MQTT协议概述 394 21.2 MQTT通信模型 394 21.3 消息主题与服务质量 395 21.4 MQTT控制报文 396 21.4.1 固定报头 396 21.4.2 可变报头 397 21.4.3 有效载荷 400 21.5 移植MQTT协议 401 21.6 cJSON移植 407 第22章 连接到百度天工物接入 411 22.1 物接入概述 411 22.2 使用IoT Hub 411 22.2.1 创建计费套餐 411 22.2.2 创建项目 411 22.2.3 创建策略 413 22.2.4 创建身份与创建用户 413 22.2.5 MQTT软件测试连接 415 22.3 开发板连接IoT Hub 417 22.4 IoT Hub的规则引擎 422 22.4.1 什么是规则引擎 422 22.4.2 使用规则引擎 422 22.5 数据可视化 424 22.5.1 IoT Hub的时序数据库 424 22.5.2 IoT Hub的物可视 426 第23章 连接到阿里云物联 429 23.1 使用阿里云物联 429 23.2 MQTT软件测试连接 431 23.3 开发板连接阿里云物联 434 23.4 阿里云物联的规则引擎 435 第24章 连接到OneNET 437 24.1 使用OneNET 437 24.2 测试连接 438 24.3 开发板连接OneNET 439 24.4 添加数据流 441 24.5 系统主题的发布格式 442 24.6 使用开发板发布数据点 443 24.7 数据可视化 446 ---------------------------FreeRTOS内核实现与应用开发实战指南:基于STM32--------------------------- 前 言 引 言 第一部分 从0到1教你写FreeRTOS内核 第1章 初识FreeRTOS 2 1.1 FreeRTOS版权 2 1.2 FreeRTOS收费问题 2 1.2.1 FreeRTOS 2 1.2.2 OpenRTOS 2 1.2.3 SaveRTOS 3 1.3 FreeRTOS资料获取 3 1.3.1 获取源码 3 1.3.2 获取书籍 4 1.3.3 快速入门 4 1.4 FreeRTOS的编程风格 5 1.4.1 数据类型 5 1.4.2 变量名 6 1.4.3 函数名 6 1.4.4 宏 7 1.4.5 格式 7 第2章 新建FreeRTOS工程—软件仿真 8 2.1 新建本地工程文件夹 8 2.2 使用KEIL新建工程 8 2.2.1 New Project 9 2.2.2 Select Device for Target 9 2.2.3 Manage Run-Time Environment 10 2.3 在KEIL工程中新建文件组 11 2.4 在KEIL工程中添加文件 11 2.5 调试配置 13 2.5.1 设置软件仿真 13 2.5.2 修改时钟大小 13 2.5.3 添加头文件路径 13 第3章 裸机系统与多任务系统 15 3.1 裸机系统 15 3.1.1 轮询系统 15 3.1.2 前后台系统 16 3.2 多任务系统 17 第4章 数据结构—列表与列表项 20 4.1 C语言链表 20 4.1.1 单向链表 20 4.1.2 双向链表 22 4.1.3 链表与数组的对比 22 4.2 FreeRTOS中链表的实现 23 4.2.1 实现链表节点 23 4.2.2 实现链表根节点 25 4.3 链表节点插入实验 31 4.4 实验现象 34 第5章 任务的定义与任务切换 35 5.1 本章目标 35 5.2 什么是任务 36 5.3 创建任务 37 5.3.1 定义任务栈 37 5.3.2 定义任务函数 38 5.3.3 定义任务控制块 39 5.3.4 实现任务创建函数 40 5.4 实现就绪列表 45 5.4.1 定义就绪列表 45 5.4.2 就绪列表初始化 45 5.4.3 将任务插入就绪列表 46 5.5 实现调度器 49 5.5.1 启动调度器 49 5.5.2 任务切换 54 5.6 main()函数 58 5.7 实验现象 61 5.8 本章涉及的汇编指令 64 第6章 临界段的保护 65 6.1 什么是临界段 65 6.2 Cortex-M内核快速关中断指令 65 6.3 关中断 66 6.3.1 不带返回值的关中断函数 66 6.3.2 带返回值的关中断函数 67 6.4 开中断 67 6.5 进入/退出临界段的宏 68 6.5.1 进入临界段 68 6.5.2 退出临界段 69 6.6 临界段代码的应用 70 6.7 实验现象 71 第7章 空闲任务与阻塞延时 72 7.1 实现空闲任务 72 7.1.1 定义空闲任务的栈 72 7.1.2 定义空闲任务的任务控制块 73 7.1.3 创建空闲任务 73 7.2 实现阻塞延时 74 7.2.1 vTaskDelay()函数 74 7.2.2 修改vTaskSwitchContext()函数 75 7.3 SysTick中断服务函数 77 7.4 SysTick初始化函数 78 7.5 main()函数 80 7.6 实验现象 83 第8章 多优先级 84 8.1 支持多优先级的方法 84 8.2 查找最高优先级的就绪任务相关代码 85 8.2.1 通用方法 87 8.2.2 优化方法 87 8.3 修改代码以支持多优先级 89 8.3.1 修改任务控制块 89 8.3.2 修改xTaskCreateStatic()函数 89 8.3.3 修改vTaskStartScheduler()函数 93 8.3.4 修改vTaskDelay()函数 94 8.3.5 修改vTaskSwitchContext()函数 95 8.3.6 修改xTaskIncrementTick()函数 96 8.4 main()函数 97 8.5 实验现象 100 第9章 任务延时列表 102 9.1 任务延时列表的工作原理 102 9.2 实现任务延时列表 103 9.2.1 定义任务延时列表 103 9.2.2 任务延时列表初始化 103 9.2.3 定义xNextTaskUnblock-Time 103 9.2.4 初始化xNextTaskUnblock-Time 104 9.3 修改代码以支持任务延时列表 104 9.3.1 修改vTaskDelay()函数 105 9.3.2 修改xTaskIncrementTick()函数 107 9.3.3 修改taskRESET_READY_PRIORITY()函数 109 9.4 main()函数 110 9.5 实验现象 110 第10章 时间片 111 10.1 时间片测试实验 111 10.2 main.c文件 112 10.3 实验现象 115 10.4 原理分析 116 10.4.1 taskSELECT_HIGHEST_PRIORITY_TASK()函数 116 10.4.2 taskRESET_READY_PRIORITY()函数 117 10.5 修改代码以支持优先级 118 10.5.1 修改xPortSysTick-Handler()函数 118 10.5.2 修改xTaskIncrement-Tick()函数 119 第二部分 FreeRTOS内核应用开发 第11章 移植FreeRTOS到STM32 124 11.1 获取STM32的裸机工程模板 124 11.2 下载FreeRTOS V9.0.0源码 124 11.3 FreeRTOS文件夹内容 126 11.3.1 FreeRTOS文件夹 126 11.3.2 FreeRTOS-Plus文件夹 128 11.3.3 HTML文件 129 11.4 向裸机工程中添加FreeRTOS源码 129 11.4.1 提取FreeRTOS最简源码 129 11.4.2 复制FreeRTOS到裸机工程根 130 11.4.3 复制FreeRTOSConfig.h文件到User文件夹 131 11.4.4 添加FreeRTOS源码到工程组文件夹 131 11.5 修改FreeRTOSConfig.h文件 133 11.5.1 FreeRTOSConfig.h文件内容 133 11.5.2 修改FreeRTOSConfig.h文件 143 11.6 修改stm32f10x_it.c文件 147 11.7 修改main.c文件 151 11.8 下载验证 152 第12章 任务 153 12.1 硬件初始化 153 12.2 创建单任务—SRAM静态内存 155 12.2.1 定义任务函数 155 12.2.2 空闲任务与定时器任务栈函数实现 155 12.2.3 定义任务栈 157 12.2.4 定义任务控制块 157 12.2.5 静态创建任务 158 12.2.6 启动任务 159 12.2.7 main.c文件 159 12.3 下载验证SRAM静态内存单任务 164 12.4 创建单任务—SRAM动态内存 164 12.4.1 动态内存空间堆的来源 164 12.4.2 定义任务函数 165 12.4.3 定义任务栈 166 12.4.4 定义任务控制块指针 166 12.4.5 动态创建任务 166 12.4.6 启动任务 167 12.4.7 main.c文件 167 12.5 下载验证SRAM动态内存单任务 171 12.6 创建多任务—SRAM动态内存 171 12.7 下载验证SRAM动态内存多任务 175 第13章 FreeRTOS的启动流程 176 13.1 “万事俱备,只欠东风”法 176 13.2 “小心翼翼,十分谨慎”法 177 13.3 两种方法的适用情况 179 13.4 FreeRTOS的启动流程 179 13.4.1 创建任务函数xTaskCreate() 179 13.4.2 开启调度器函数vTask-StartScheduler() 181 13.4.3 main()函数 185 第14章 任务管理 188 14.1 任务的基本概念 188 14.2 任务调度器的基本概念 188 14.3 任务状态的概念 189 14.4 任务状态迁移 190 14.5 常用的任务函数 191 14.5.1 任务挂起函数 191 14.5.2 任务恢复函数 195 14.5.3 任务删除函数 203 14.5.4 任务延时函数 207 14.6 任务的设计要点 215 14.7 任务管理实验 216 14.8 实验现象 221 第15章 消息队列 222 15.1 消息队列的基本概念 222 15.2 消息队列的运作机制 222 15.3 消息队列的阻塞机制 223 15.4 消息队列的应用场景 224 15.5 消息队列控制块 224 15.6 常用的消息队列函数 226 15.6.1 消息队列动态创建函数 226 15.6.2 消息队列静态创建函数 232 15.6.3 消息队列删除函数 233 15.6.4 向消息队列发送消息函数 234 15.6.5 从消息队列读取消息函数 244 15.7 消息队列注意事项 251 15.8 消息队列实验 252 15.9 实验现象 256 第16章 信号量 258 16.1 信号量的基本概念 258 16.1.1 二值信号量 258 16.1.2 计数信号量 259 16.1.3 互斥信号量 259 16.1.4 递归信号量 259 16.2 二值信号量的应用场景 260 16.3 二值信号量的运作机制 260 16.4 计数信号量的运作机制 261 16.5 信号量控制块 262 16.6 常用的信号量函数 263 16.6.1 信号量创建函数 263 16.6.2 信号量删除函数 268 16.6.3 信号量释放函数 268 16.6.4 信号量获取函数 271 16.7 信号量实验 273 16.7.1 二值信号量同步实验 273 16.7.2 计数信号量实验 277 16.8 实验现象 282 16.8.1 二值信号量实验现象 282 16.8.2 计数信号量实验现象 283 第17章 互斥量 284 17.1 互斥量的基本概念 284 17.2 互斥量的优先级继承机制 284 17.3 互斥量的应用场景 287 17.4 互斥量的运作机制 287 17.5 互斥量控制块 288 17.6 互斥量函数 289 17.6.1 互斥量创建函数xSema-phoreCreateMutex() 289 17.6.2 递归互斥量创建函数xSemaphoreCreateRecur-siveMutex() 292 17.6.3 互斥量删除函数vSema-phoreDelete() 293 17.6.4 互斥量获取函数xSema-phoreTake() 293 17.6.5 递归互斥量获取函数xSemaphoreTakeRecur-sive() 299 17.6.6 互斥量释放函数xSema-phoreGive() 301 17.6.7 递归互斥量释放函数xSemaphoreGiveRecur-sive() 304 17.7 互斥量实验 307 17.7.1 模拟优先级翻转实验 307 17.7.2 互斥量降低优先级翻转危害实验 312 17.8 实验现象 318 17.8.1 模拟优先级翻转实验现象 318 17.8.2 互斥量降低优先级翻转危害实验现象 318 第18章 事件 320 18.1 事件的基本概念 320 18.2 事件的应用场景 321 18.3 事件的运作机制 321 18.4 事件控制块 323 18.5 事件函数 323 18.5.1 事件创建函数xEvent-GroupCreate() 323 18.5.2 事件删除函数vEvent-GroupDelete() 325 18.5.3 事件组置位函数xEvent-GroupSetBits()(任务) 326 18.5.4 事件组置位函数xEvent-GroupSetBitsFromISR()(中断) 330 18.5.5 等待事件函数xEvent-GroupWaitBits() 332 18.5.6 清除事件组指定位函数xEventGroupClearBits()与xEventGroupClearBits-FromISR() 337 18.6 事件实验 338 18.7 实验现象 343 第19章 软件定时器 344 19.1 软件定时器的基本概念 344 19.2 软件定时器的应用场景 345 19.3 软件定时器的精度 345 19.4 软件定时器的运作机制 346 19.5 软件定时器控制块 348 19.6 软件定时器函数 349 19.6.1 软件定时器创建函数 349 19.6.2 软件定时器启动函数 352 19.6.3 软件定时器停止函数 356 19.6.4 软件定时器任务 358 19.6.5 软件定时器删除函数 365 19.7 软件定时器实验 366 19.8 实验现象 371 第20章 任务通知 372 20.1 任务通知的基本概念 372 20.2 任务通知的运作机制 372 20.3 任务通知的数据结构 373 20.4 任务通知函数 374 20.4.1 发送任务通知函数 374 20.4.2 获取任务通知函数 391 20.5 任务通知实验 398 20.5.1 任务通知代替消息队列 398 20.5.2 任务通知代替二值信号量 404 20.5.3 任务通知代替计数信号量 409 20.5.4 任务通知代替事件组 414 20.6 实验现象 419 20.6.1 任务通知代替消息队列实验现象 419 20.6.2 任务通知代替二值信号量实验现象 420 20.6.3 任务通知代替计数信号量实验现象 420 20.6.4 任务通知代替事件组实验现象 421 第21章 内存管理 422 21.1 内存管理的基本概念 422 21.2 内存管理的应用场景 423 21.3 内存管理方案详解 424 21.3.1 heap_1.c 424 21.3.2 heap_2.c 428 21.3.3 heap_3.c 436 21.3.4 heap_4.c 438 21.3.5 heap_5.c 448 21.4 内存管理实验 451 21.5 实验现象 455 第22章 中断管理 456 22.1 异常与中断的基本概念 456 22.1.1 中断的介绍 457 22.1.2 和中断相关的术语 457 22.2 中断管理的运作机制 458 22.3 中断延迟的概念 459 22.4 中断管理的应用场景 460 22.5 ARM Cortex-M的中断管理 460 22.6 中断管理实验 462 22.7 实验现象 470 第23章 CPU利用率统计 471 23.1 CPU利用率的基本概念 471 23.2 CPU利用率的作用 471 23.3 CPU利用率统计 472 23.4 CPU利用率统计实验 473 23.5 实验现象 478 附录 479 |