
1. 项目概述与核心价值在嵌入式系统开发中数据安全是一个绕不开的话题。无论是物联网设备间的通信还是本地存储的敏感信息都需要可靠的加密保护。高级加密标准AES作为当前最主流的对称加密算法其软件实现虽然可行但在资源受限、实时性要求高的微控制器上往往会成为性能瓶颈大量消耗宝贵的CPU周期。这正是硬件AES加速器大显身手的地方。德州仪器的Tiva™ TM4C129LNCZAD微控制器作为Cortex-M4内核的明星产品其内置的AES加密加速模块为开发者提供了一个高效、省电的硬件加密解决方案。它不仅能支持基本的ECB、CBC模式更集成了CCM、GCM等带认证的加密模式以及XTS、F8/F9等专用模式功能相当全面。然而功能强大也意味着配置复杂。官方数据手册虽然提供了寄存器列表和位域描述但如何将这些零散的寄存器配置串联成一个可工作的、高效的驱动中间隔着不少“坑”。比如全局初始化的顺序有何讲究CCM模式和GCM模式在配置上关键区别在哪轮询、中断和DMA三种操作模式又该如何根据实际数据流量选择这些实战中的细节手册往往一笔带过却直接决定了项目的成败与性能。本文将基于Tiva™ TM4C129LNCZAD的AES模块为你彻底拆解从寄存器配置到工作模式实现的完整路径。我不会只复述手册内容而是结合我多年在嵌入式安全开发中的经验重点讲解那些手册里没写、但实际编程中一定会遇到的“为什么”和“怎么办”。目标是让你读完本文后不仅能理解每个寄存器位的含义更能独立编写出稳定、高效的AES硬件驱动代码真正把这块硬件的潜力发挥出来。2. AES模块架构与核心寄存器深度解析要驾驭TM4C129的AES模块不能只停留在调用库函数的层面必须深入其硬件架构。这个模块本质上是一个高度可配置的协处理器它独立于CPU运行我们通过配置一系列寄存器来设定其工作模式、输入密钥和初始向量IV然后通过数据寄存器喂入数据并取出结果。理解几个核心寄存器组是编程的基础。2.1 控制中枢AES_CTRL寄存器详解AES_CTRL寄存器是整个模块的大脑其复位值为0x8000.0000。这个值很有意思最高位bit 31CTXTRDY在上电后默认为1表示上下文数据寄存器如密钥、IV就绪可以写入。我们编程的第一步通常就是根据需要的加密模式对这个寄存器的各个位域进行精确配置。关键位域解析与配置逻辑操作模式选择位域 (Bits 18, 17:16, 15, 14, 13, 12:11, 10, 9, 6, 5)MODE(Bit 5): 这是最基础的选择。0为ECB模式1为CBC模式。ECB模式简单但相同明文块会产生相同密文块安全性较低CBC模式引入了链式操作安全性更好是更常用的选择。CTR(Bit 6): 计数器模式使能位。这里有一个极易混淆的关键点不仅纯CTR模式需要设置此位GCM和CCM这两种认证加密模式在需要执行加密/解密操作时也必须将此位置1。因为GCM和CCM的内部加密部分使用的是CTR模式。如果你只做认证如GCM的GHASH则不需要开启。GCM(Bits 17:16): 这2位不仅用于使能GCM模式还定义了其子模式。0x0: 无操作GCM未启用。0x1:GHASH模式且H哈希子密钥已预计算并加载Y0初始计数器块强制为零。这种模式下认证结果TAG不会被加密。适用于你已经预先计算好H的场景。0x2:GHASH模式H已加载但Y0由模块内部计算。这是更常见的“完整GCM”认证模式。0x3:自主GHASH模式H和Y0均由模块内部计算。这是最省事的模式但性能开销稍大手册中提到的周期数翻倍即指此情况。CCM(Bit 18): 使能CCM模式。这是一个组合模式使能后模块会自动处理认证和加密的流程。CCM_L(Bits 21:19) 和CCM_M(Bits 24:22): 这是CCM模式独有的配置。L定义了长度字段的宽度字节数 L 1支持的值有0, 2, 4, 8分别对应不同的CCM_L编码。M定义了认证字段TAG的长度有效字节数 2*(M1)。必须根据你的通信协议或安全规范来正确设置这两个值设置错误会导致通信双方无法验证。CBCMAC,F9,F8,XTS,CFB,ICM: 这些是其他专用模式的使能位。例如F8和F9主要用于3GPP通信安全XTS用于磁盘加密。启用它们时通常有额外的约束比如F8和F9模式强制要求密钥大小为128位即KEY_SIZE必须设为0x1。方向与密钥配置 (Bits 4:3, 2)DIRECTION(Bit 2): 0为解密1为加密。特别注意在CBCMAC仅认证模式下此位必须设置为1加密方向。KEY_SIZE(Bits 4:3): 选择密钥长度。0x1对应128位0x2对应192位0x3对应256位。务必与你加载的密钥长度匹配。状态与上下文位 (Bits 1, 0, 31, 30, 29)INPUT_READY(Bit 1) 和OUTPUT_READY(Bit 0): 这两个是只读状态位在轮询模式下至关重要。INPUT_READY为1表示16字节的输入缓冲区AES_DATA_IN_n为空可以写入下一块数据。OUTPUT_READY为1表示一个输出块加密/解密结果或TAG已就绪可以读取。编程时必须严格查询这些位以避免数据覆盖或读取无效数据。CTXTRDY(Bit 31): 只读指示上下文寄存器AES_KEYn_n,AES_IV_IN_n是否就绪可写入新上下文。SAVE_CONTEXT(Bit 29): 这是一个关键配置位。如果你希望在一次操作结束后例如完成一个GCM数据包的加密模块能自动将产生的认证标签TAG或最终的IV在CBC模式下保存到上下文输出寄存器以便你读取必须将此位置1。同时你需要使能CONTEXT_OUT中断或DMA请求来获知数据就绪。如果此位为0模块不会自动保存这些结果。配置心得在编写初始化函数时我习惯先定义一个局部变量如ui32Config从复位值0x80000000开始根据所需模式按位或|上相应的值。例如配置一个256位密钥、CBC加密模式ui32Config 0x80000000 | AES_CTRL_KEY_SIZE_256 | AES_CTRL_MODE_CBC | AES_CTRL_DIRECTION_ENCRYPT;。这样做逻辑清晰不易出错。切记不要直接写入一个写死的十六进制数应使用芯片厂商提供的驱动库中的宏定义或者自己明确定义以保证代码可读性和可维护性。2.2 数据与密钥寄存器组这部分寄存器是模块与CPU交换数据的桥梁。密钥寄存器 (AES_KEY1_n和AES_KEY2_n) 位于偏移0x020-0x03C和0x000-0x01C。每组有8个32位寄存器共可存储256位密钥。AES_KEY1_n用于存储主密钥。AES_KEY2_n的用途取决于模式XTS模式用于存储第二个密钥tweak key。CCM/CBC-MAC模式可能用于存储第二个或第三个密钥根据具体配置。其他模式通常不使用。加载要点密钥必须按照小端格式Little-Endian加载。即密钥的最低有效字节LSB应写入AES_KEY1_0的最低字节bit 7-0。对于256位密钥你需要连续写入AES_KEY1_0到AES_KEY1_7。初始化向量寄存器 (AES_IV_IN_n) 位于偏移0x040-0x04C共4个寄存器128位用于加载CBC、CTR、GCM等模式所需的初始向量。同样需要小端格式。对于GCM模式这里加载的是96位的IV通常12字节剩余32位由模块内部构造为计数器。数据输入/输出寄存器 (AES_DATA_IN_n) 位于偏移0x060-0x06C。这组寄存器扮演着“FIFO入口”的角色。一个非常重要的硬件特性你只需要向AES_DATA_IN_0偏移0x060连续写入4个32位字共16字节硬件会自动将这128位数据移入内部处理流水线。读取结果时也需要从AES_DATA_IN_0开始连续读取4个字。AES_DATA_IN_1到AES_DATA_IN_3更像是内部的缓冲区直接读写它们的行为是未定义的或低效的。最佳实践是永远只通过AES_DATA_IN_0的地址进行块数据的写入和读取。认证标签输出寄存器 (AES_TAG_OUT_n) 位于偏移0x070-0x07C。当使能了认证模式如GCM、CCM且SAVE_CONTEXT位为1时计算得到的128位认证标签TAG会出现在这里。同样从AES_TAG_OUT_0开始读取。2.3 长度与系统配置寄存器数据长度寄存器 (AES_C_LENGTH_0/1) 位于偏移0x054和0x058。这是一个64位寄存器用于设置需要加密/解密的明文/密文数据的字节长度。对于GCM和CCM模式这个长度不包括附加认证数据AAD。AAD的长度由另一个寄存器设置。关键行为向此寄存器写入长度值会触发AES引擎开始使用当前已加载的上下文密钥、IV等进行处理。对于ECB/CBC等基础模式可以写入0表示处理无限长度的流直到你停止喂数据。对于GCM模式数据长度有理论上限2^36 - 32字节因为内部使用32位计数器。认证数据长度寄存器 (AES_AUTH_LENGTH) 位于偏移0x05C。专用于GCM和CCM模式设置附加认证数据AAD的字节长度。写入此寄存器也会触发上下文生效。对于XTS模式这个寄存器有复用功能当XTS模式配置为需要加载参数j块在数据单元内的序号时j值需要写入这个寄存器的bits [31:4]。系统配置寄存器 (AES_SYSCONFIG) 位于偏移0x084。这个寄存器控制DMA和软复位。SOFTRESET(Bit 1): 写入1启动软件复位。在模块状态异常或切换不同配置模式前执行一次软复位是良好的习惯。DMA_REQ_*_EN(Bits 8,7,6,5): 分别使能上下文输入、上下文输出、数据输入、数据输出的DMA请求。如果你想使用DMA模式必须在此使能相应的通道。MAP_CONTEXT_OUT_ON_DATA_OUT(Bit 9): 这是一个有用的位。当置1时上下文输出请求比如TAG就绪会被映射到数据输出请求信号上。这在某些DMA控制器配置下可以简化处理。一个至关重要的警告数据手册提到在一次操作完成后必须清除并重新配置AES_SYSCONFIG寄存器才能进行下一次操作。这意味着你不能简单地重复使用之前的DMA配置。我的做法是在每次AES操作序列的初始化阶段完整地配置一次该寄存器在操作完成后如果需要新的DMA传输则重新配置。3. 实战编程从初始化到多模式配置理解了寄存器我们开始动手编程。AES模块的驱动编程遵循一个清晰的流程全局初始化 - 模式特定初始化 - 选择操作模式轮询/中断/DMA并处理数据。3.1 全局初始化序列这是使用AES模块前的必经之路确保硬件处于已知的、就绪的状态。使能时钟任何外设使用前必须先给其供电和提供时钟。通过设置系统控制模块中的RCGCCCM寄存器偏移0x674的相应位来使能AES时钟。然后查询PRCCCM寄存器偏移0xA74确认AES模块已就绪。// 假设使用TI的驱动库 SysCtlPeripheralEnable(SYSCTL_PERIPH_AES); while(!SysCtlPeripheralReady(SYSCTL_PERIPH_AES)) {}配置µDMA通道如果使用DMA如果计划使用DMA来搬运数据需要在µDMA模块中将特定的DMA通道映射到AES的上下文输入、输出、数据输入、输出请求上。这通过配置DMACHMAPn寄存器偏移0x510完成。这一步必须在AES模块初始化前完成。执行软件复位向AES_SYSCONFIG寄存器的SOFTRESET位写1然后轮询AES_SYSSTATUS寄存器的RESETDONE位直到其变为1。这确保了模块从一个干净的状态开始。HWREG(AES_BASE AES_O_SYSCONFIG) AES_SYSCONFIG_SOFTRESET; while(!(HWREG(AES_BASE AES_O_SYSSTATUS) AES_SYSSTATUS_RESETDONE)) {}配置DMA与中断如果使用如果使用DMA配置AES_SYSCONFIG中的DMA_REQ_*_EN位来使能所需的DMA请求。同时如果需要DMA传输完成中断配置AES_DMAIM寄存器。如果使用普通中断模式则配置AES_IRQENABLE寄存器。配置密钥与模式根据算法需求在AES_CTRL寄存器中设置KEY_SIZE。将密钥数据写入AES_KEY1_n和AES_KEY2_n如果需要寄存器。在AES_CTRL寄存器中设置加密/解密方向DIRECTION和基本模式如MODE位选择CBC。3.2 各加密模式初始化子序列详解全局初始化后需要根据你选用的具体加密模式进行针对性配置。以下是几个常用且易错模式的配置要点3.2.1 CCM模式初始化CCM是“Counter with CBC-MAC”的缩写结合了CTR加密和CBC-MAC认证。其初始化步骤是其他模式的一个典型代表。配置CCM参数在AES_CTRL寄存器中设置CCM_L和CCM_M位域。这定义了协议中的长度字段宽度和认证标签长度必须与通信对端严格一致。例如CCM_L2对应长度字段3字节CCM_M3对应认证标签8字节。使能计数器模式必须设置CTR位为1因为CCM的加密部分使用CTR模式。设置认证数据长度将附加认证数据AAD的字节长度写入AES_AUTH_LENGTH寄存器。如果没有AAD则写0。设置计数器宽度通过CTR_WIDTH选择计数器宽度。CCM通常使用固定的格式计数器宽度由CCM_L和IV长度决定常见的是64位或104位。需要根据标准选择。加载初始化向量将IV写入AES_IV_IN_n寄存器。避坑指南CCM模式对数据的格式有严格要求包括B0块Flags、Nonce、消息长度的构造。TM4C129的硬件不负责构造B0块它期望你直接提供作为计数器起点的IV。因此在软件层你需要根据CCM标准自己构造出正确的IV即B0的计数器部分加载到AES_IV_IN_n。这是一个常见的错误来源。3.2.2 GCM模式初始化GCMGalois/Counter Mode是另一种广泛使用的认证加密模式性能通常优于CCM。使能计数器模式同样必须设置CTR位为1。设置认证数据长度将AAD的字节长度写入AES_AUTH_LENGTH。设置计数器宽度GCM标准规定使用32位计数器。因此CTR_WIDTH通常设置为0x032位。加载初始化向量GCM通常使用96位IV12字节。将其写入AES_IV_IN_0到AES_IV_IN_2AES_IV_IN_3写0。配置GCM子模式通过GCM位域选择。如果你有预计算的H哈希子密钥选择0x1或0x2否则选择0x3自主模式。注意手册提到在“完整GCM模式”即H需要核心计算下首个数据块的周期开销会翻倍。在性能敏感的场合可以考虑在初始化阶段预先计算好H并加载以提升流式加密的效率。3.2.3 CBC模式初始化CBC模式相对简单。使能CBC模式设置AES_CTRL寄存器的MODE位为1。加载初始化向量将IV写入AES_IV_IN_n寄存器。注意方向设置DIRECTION位选择加密或解密。3.2.4 CTR模式初始化CTR模式将分组密码转换为流密码。使能计数器模式设置CTR位为1。选择计数器宽度通过CTR_WIDTH设置可以是32、64、96或128位。加载初始计数器值将初始的计数器值Counter Nonce写入AES_IV_IN_n寄存器。硬件会自动递增计数器。操作心得对于所有模式在加载IV和可选的AAD长度后向AES_C_LENGTH寄存器写入加密数据长度是触发AES引擎开始处理当前上下文的最终信号。在写入长度之前你可以安全地修改密钥、IV等上下文信息。写入长度后上下文就被“锁定”用于接下来的数据块处理。4. 三大操作模式实现与选择策略配置好加密模式和上下文后就需要向模块输送数据并取回结果。TM4C129的AES模块提供了三种数据交互模式轮询、中断和DMA。选择哪种模式取决于你的数据量、系统实时性要求和CPU负载考量。4.1 轮询模式这是最简单、最直接的模式适用于数据量小、或对处理时机有绝对控制权的场景。工作流程检查AES_CTRL.INPUT_READY位是否为1。为1表示输入缓冲区空。如果为空将16字节128位的明文/密文数据通过4次32位写操作写入AES_DATA_IN_0寄存器地址。记住始终写入AES_DATA_IN_0硬件负责内部移位。等待AES_CTRL.OUTPUT_READY位变为1。这表示一个128位的结果块已就绪。从AES_DATA_IN_0寄存器地址连续读取4个32位字得到加密/解密后的数据。如果使能了认证模式且SAVE_CONTEXT为1当整个数据流处理完毕OUTPUT_READY会再次置1或通过CONTEXT_OUT事件此时需要从AES_TAG_OUT_0读取认证标签。代码示例片段CBC加密void AESPollingEncrypt(uint32_t *pPlaintext, uint32_t *pCiphertext, uint32_t blockCount) { uint32_t i, j; for(i 0; i blockCount; i) { // 等待输入缓冲区就绪 while(!(HWREG(AES_BASE AES_O_CTRL) AES_CTRL_INPUT_READY)) {} // 写入一个数据块128位到 DATA_IN_0 for(j 0; j 4; j) { HWREG(AES_BASE AES_O_DATA_IN_0) pPlaintext[i*4 j]; } // 等待输出就绪 while(!(HWREG(AES_BASE AES_O_CTRL) AES_CTRL_OUTPUT_READY)) {} // 从 DATA_IN_0 读取结果块 for(j 0; j 4; j) { pCiphertext[i*4 j] HWREG(AES_BASE AES_O_DATA_IN_0); } } }轮询模式优缺点优点实现简单无需配置中断或DMA代码直观。缺点CPU被完全占用在等待状态上效率极低。在处理大量数据时会严重阻塞其他任务。4.2 中断模式中断模式允许CPU在AES模块处理数据时去执行其他任务当数据块处理完成时通过中断通知CPU。配置与流程在全局初始化阶段使能AES_IRQENABLE寄存器中相应的中断位。例如使能数据输入中断(DATA_IN)和数据输出中断(DATA_OUT)。在中断服务程序ISR中读取AES_IRQSTATUS寄存器判断中断源。如果是DATA_IN中断表示模块准备好接收新数据ISR中写入下一块数据。如果是DATA_OUT中断表示一个结果块已就绪ISR中读取数据。如果是CONTEXT_OUT中断且SAVE_CONTEXT1表示认证标签等上下文数据就绪ISR中读取AES_TAG_OUT_n。操作完成后清除AES_IRQSTATUS中相应的中断状态位。启动流程先写入第一块数据到AES_DATA_IN_n然后后续的数据交换由中断驱动。中断模式注意事项中断风暴风险每个128位数据块处理完都会产生一次中断。对于高速连续的数据流例如加解密一个几KB的文件中断频率会非常高可能导致系统中断负载过重反而降低整体性能。手册中特别提到“为了支持更大的数据流应使用AES µDMA模式并清除AES_IRQENABLE寄存器中的位。”这明确指出了中断模式更适合低频率、非连续的数据块处理场景。4.3 DMA模式这是处理大量数据时的推荐方式能最大程度解放CPU。DMA控制器负责在AES模块的数据寄存器与系统内存之间自动搬运数据。配置步骤详解µDMA通道配置这是第一步也是最容易出错的一步。你需要通过DMACHMAPn寄存器将µDMA的某个通道分配给AES的特定请求如AES_DATA_IN请求。这需要仔细查阅芯片的µDMA章节确定正确的通道映射编码。AES DMA使能在AES_SYSCONFIG寄存器中设置DMA_REQ_DATA_IN_EN和/或DMA_REQ_DATA_OUT_EN位根据传输方向使能AES模块的DMA请求输出。µDMA通道描述符配置这是DMA编程的核心。你需要设置一个或多个DMA通道描述符通常在SRAM中描述符中定义了源地址对于数据输入到AES源地址是你的明文数据数组对于数据输出从AES源地址是AES_DATA_IN_0的固定地址。目的地址对于数据输入目的地址是AES_DATA_IN_0的固定地址对于数据输出目的地址是你的密文数据数组。传输数量要传输的数据项数量。注意AES数据寄存器是32位宽所以如果你要传输N个128位块即16*N字节那么需要设置传输数量为4 * N每个块4个32位字。传输宽度设置为32位字。仲裁大小DMA在一次请求中传输的数据项数。为了匹配AES模块的128位块处理节奏通常设置为4一次传输一个完整块。启动DMA配置好描述符并启用µDMA通道后向AES_C_LENGTH寄存器写入总数据长度字节数这将触发AES模块开始工作并发出DMA请求。完成处理DMA传输完成后会产生dma_done中断通过AES_DMAMIS寄存器状态位判断。在中断服务程序中你可以进行后续操作比如读取认证标签如果使能了SAVE_CONTEXT和CONTEXT_OUTDMA。DMA模式核心技巧双缓冲区Ping-Pong Buffer为了达到最高吞吐率务必使用µDMA的Ping-Pong模式。这样可以在一个缓冲区被DMA搬运数据给AES处理的同时CPU准备下一个缓冲区的数据实现流水线操作几乎可以吃满AES模块的带宽。描述符链对于非常大的数据可以配置多个描述符链接起来DMA会自动依次执行。内存对齐确保你的源和目的数据缓冲区在内存中是32位对齐的这能提升DMA效率有时甚至是硬件要求。模式选择总结轮询用于测试、调试或极少量数据。中断用于非连续的、低速的数据块处理CPU需要及时响应但数据量不大。DMA绝大多数实际应用场景的首选尤其是需要加密/解密数据流如通信报文、文件存储时。它能实现最高的吞吐率和最低的CPU占用。5. 常见问题排查与实战经验即使按照手册一步步配置在实际开发中依然会遇到各种问题。下面是我在多项目中总结出的典型问题及其解决方法。5.1 数据错误或模块无响应症状写入数据后OUTPUT_READY标志永远不置位或者读出的数据全是0或乱码。排查步骤时钟与复位确认SYSCTL中已使能AES外设时钟并且通过PRCCCM确认其已就绪。检查是否执行了软复位SOFTRESET并等待RESETDONE。操作顺序严格遵循初始化序列时钟使能 - (DMA通道映射) - 软复位 - 配置密钥/模式 - 加载IV -最后写入数据长度。写入AES_C_LENGTH是启动信号在此之前的配置才有效。寄存器位锁定有些配置位在模块启动后是只读或锁定的。确保在写入AES_C_LENGTH之前完成所有AES_CTRL寄存器的配置。数据对齐与FIFO操作确认你总是以32位字为单位向AES_DATA_IN_0偏移0x060的同一个地址连续写入4次来输入一个块。读取结果时亦然。误操作其他DATA_IN寄存器地址是常见错误。密钥与IV格式确认密钥和IV数据是按照小端字节序加载到寄存器中的。如果你的源数据是大端格式需要进行转换。5.2 认证模式GCM/CCM失败症状加密解密过程正常但对方无法验证认证标签TAG。排查步骤模式配置确认GCM或CCM位已正确使能。对于GCMCTR位也必须置1。长度寄存器确认AES_C_LENGTH设置的是加密数据的长度AES_AUTH_LENGTH设置的是**附加认证数据AAD**的长度。两者混淆是致命错误。TAG获取确认AES_CTRL寄存器中的SAVE_CONTEXT位已设置为1。否则模块不会将计算出的TAG保存到AES_TAG_OUT_n寄存器中。TAG读取时机TAG只有在整个数据段和AAD处理完毕后才会生成并可用。在DMA或中断模式下你需要等待CONTEXT_OUT事件中断或DMA请求触发后再去读取AES_TAG_OUT_n。在轮询模式下需要在所有数据块处理完成后检查OUTPUT_READY或CTXTRDY标志。IV构造CCM特有如之前所述硬件不构造CCM的B0块。你需要根据RFC 3610等标准在软件中构造出正确的计数器初始值IV然后将其加载到AES_IV_IN_n。一个字节顺序错误就会导致整个认证失败。5.3 DMA传输异常症状DMA启动后数据传输不完整、错位或触发总线错误。排查步骤通道映射反复检查DMACHMAPn寄存器的配置值确保将正确的DMA通道分配给了正确的AES请求DATA_IN,DATA_OUT等。映射错误是DMA无法工作的首要原因。AES DMA使能确认AES_SYSCONFIG寄存器中对应的DMA_REQ_*_EN位已经置1。描述符配置地址源和目的地址必须是物理地址并且是32位对齐的。传输数量这是最容易算错的地方。牢记AES每次处理128位16字节4个字。如果你的数据总字节数是totalBytes那么需要传输的32位字数量是(totalBytes 3) / 4向上取整。而DMA的传输项数xferSize就设置成这个字数量。仲裁大小设置为4让DMA一次传输一个完整的AES块。数据长度触发DMA配置好后必须通过写入AES_C_LENGTH来触发AES开始工作并发出DMA请求。如果忘记写入DMA会一直等待请求而超时。缓冲区溢出确保DMA的目的缓冲区足够大。特别是在输出方向AES模块产生数据的速度可能很快。5.4 性能优化要点使用DMA并启用Ping-Pong模式这是提升吞吐量的不二法门。对于TM4C129AES模块的最高性能只有在DMA持续喂料时才能达到。预计算与上下文保存对于GCM模式如果可能预计算哈希子密钥H并加载使用GCM0x1或0x2模式可以避免每个数据包都重复计算H的开销。避免频繁的模式切换每次切换加密模式如从CBC切换到GCM或密钥都需要重新初始化上下文带来额外开销。在协议设计上尽量让一次通信会话使用相同的模式和密钥。关注数据手册中的周期数手册中的Table 13-4提供了不同模式下处理第一个/最后一个数据块所需的周期数。这对于评估实时性、设置超时时间很有帮助。例如“New Context”一列下的数字就是初始化一个新上下文如新IV带来的固定开销。最后一个非常实用的调试建议在开发初期务必先使用轮询模式实现基本功能。轮询模式代码简单易于设置断点和观察寄存器状态。在确认密钥加载、IV设置、数据通路都正确无误后再逐步迁移到更高效但更复杂的中断或DMA模式。同时充分利用芯片的ROM中可能存在的加密库如TivaWare中的Crypto库但理解其底层的寄存器操作能让你在库函数无法满足定制需求时依然可以游刃有余。