引言
YTM32B1ME0x作为汽车级微控制器,除了常见的通用外设外,还集成了多个专用外设和系统监控模块,这些模块为汽车电子系统提供了额外的功能和安全保障。本篇将详细介绍这些专用外设,包括硬件加密单元(HCU)、真随机数生成器(TRNG)、时钟监控单元(CMU)、外部看门狗(EWDG)、外设保护单元(PPU)、中断监控器(INTM)、ECC管理单元(EMU)等。
硬件加密单元(HCU)
HCU功能特性
硬件加密单元(Hardware Cryptography Unit)提供硬件级的加密和解密功能:
支持的算法:
-
AES: 高级加密标准,支持128/192/256位密钥
-
SM4: 中国国家密码算法,128位分组密码
-
SHA: 安全哈希算法,支持SHA-1/SHA-224/SHA-256
主要特性:
-
硬件加速,性能优于软件实现
-
支持多种工作模式(ECB、CBC、CTR等)
-
密钥管理和保护
-
DMA支持,减少CPU负载
HCU配置与使用
// HCU配置结构
typedef struct {
hcu_algorithm_t algorithm; // 加密算法
hcu_mode_t mode; // 工作模式
hcu_key_size_t key_size; // 密钥长度
bool dma_enable; // DMA使能
bool interrupt_enable; // 中断使能
hcu_callback_t callback; // 完成回调
} hcu_config_t;
// HCU算法类型
typedef enum {
HCU_ALGORITHM_AES, // AES算法
HCU_ALGORITHM_SM4, // SM4算法
HCU_ALGORITHM_SHA // SHA算法
} hcu_algorithm_t;
// HCU工作模式
typedef enum {
HCU_MODE_ECB, // 电子密码本模式
HCU_MODE_CBC, // 密码分组链接模式
HCU_MODE_CTR, // 计数器模式
HCU_MODE_GCM // 伽罗瓦计数器模式
} hcu_mode_t;
// HCU初始化
void hcu_init(hcu_config_t *config) {
// 使能HCU时钟
RCC->AHB2ENR |= RCC_AHB2ENR_HCUEN;
// 配置HCU控制寄存器
HCU->CR = 0;
HCU->CR |= (config->algorithm << HCU_CR_ALGO_Pos);
HCU->CR |= (config->mode << HCU_CR_MODE_Pos);
HCU->CR |= (config->key_size << HCU_CR_KEYSIZE_Pos);
if (config->dma_enable) {
HCU->CR |= HCU_CR_DMAEN;
}
if (config->interrupt_enable) {
HCU->IER |= HCU_IER_CCIE;
NVIC_EnableIRQ(HCU_IRQn);
}
// 使能HCU
HCU->CR |= HCU_CR_EN;
}
// AES加密
void hcu_aes_encrypt(const uint8_t *key, const uint8_t *input, uint8_t *output, uint32_t length) {
// 设置密钥
for (int i = 0; i < 4; i++) {
HCU->KEYR[i] = ((uint32_t*)key)[i];
}
// 处理数据块
for (uint32_t i = 0; i < length; i += 16) {
// 输入数据
for (int j = 0; j < 4; j++) {
HCU->DINR = ((uint32_t*)&input[i])[j];
}
// 等待处理完成
while (!(HCU->SR & HCU_SR_CCF));
// 读取输出
for (int j = 0; j < 4; j++) {
((uint32_t*)&output[i])[j] = HCU->DOUTR;
}
// 清除完成标志
HCU->CR |= HCU_CR_CCFC;
}
}
真随机数生成器(TRNG)
TRNG配置
// TRNG初始化
void trng_init(void) {
// 使能TRNG时钟
RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN;
// 使能TRNG
RNG->CR |= RNG_CR_RNGEN;
// 等待就绪
while (!(RNG->SR & RNG_SR_DRDY));
}
// 获取随机数
uint32_t trng_get_random(void) {
// 等待数据就绪
while (!(RNG->SR & RNG_SR_DRDY));
// 检查错误
if (RNG->SR & (RNG_SR_SECS | RNG_SR_CECS)) {
// 清除错误
RNG->SR &= ~(RNG_SR_SECS | RNG_SR_CECS);
return 0;
}
return RNG->DR;
}
看门狗定时器(IWDG/WWDG)
独立看门狗(IWDG)
// IWDG配置
void iwdg_init(uint32_t timeout_ms) {
// 启动LSI时钟
RCC->CSR |= RCC_CSR_LSION;
while (!(RCC->CSR & RCC_CSR_LSIRDY));
// 解锁IWDG
IWDG->KR = 0x5555;
// 设置预分频器(32kHz/64 = 512Hz)
IWDG->PR = IWDG_PR_PR_2;
// 设置重载值
uint32_t reload = (timeout_ms * 512) / 1000;
IWDG->RLR = reload & 0xFFF;
// 启动看门狗
IWDG->KR = 0xCCCC;
}
// 喂狗
void iwdg_refresh(void) {
IWDG->KR = 0xAAAA;
}
窗口看门狗(WWDG)
// WWDG配置
void wwdg_init(uint32_t timeout_ms, uint32_t window_ms) {
// 使能WWDG时钟
RCC->APB1ENR |= RCC_APB1ENR_WWDGEN;
// 计算配置值
uint32_t prescaler = WWDG_PRESCALER_8;
uint32_t counter = 127 - (timeout_ms * (PCLK1_FREQ / 4096) / 1000);
uint32_t window = 127 - (window_ms * (PCLK1_FREQ / 4096) / 1000);
// 配置窗口值
WWDG->CFR = prescaler | (window & 0x7F);
// 使能早期唤醒中断
WWDG->CFR |= WWDG_CFR_EWI;
NVIC_EnableIRQ(WWDG_IRQn);
// 启动WWDG
WWDG->CR = WWDG_CR_WDGA | (counter & 0x7F);
}
// WWDG中断处理
void WWDG_IRQHandler(void) {
if (WWDG->SR & WWDG_SR_EWIF) {
// 清除中断标志
WWDG->SR = 0;
// 执行紧急操作
emergency_save_data();
// 刷新看门狗
WWDG->CR = WWDG_CR_WDGA | 0x7F;
}
}
系统监控
时钟监控(CSS)
// 时钟安全系统配置
void css_init(void) {
// 使能时钟安全系统
RCC->CR |= RCC_CR_CSSON;
// 使能CSS中断
RCC->CIR |= RCC_CIR_CSSC;
NVIC_EnableIRQ(RCC_IRQn);
}
// RCC中断处理
void RCC_IRQHandler(void) {
if (RCC->CIR & RCC_CIR_CSSF) {
// HSE时钟失效
RCC->CIR |= RCC_CIR_CSSC;
// 切换到HSI
handle_hse_failure();
}
}
void handle_hse_failure(void) {
// 自动切换到HSI已由硬件完成
// 记录事件并通知应用
log_clock_failure_event();
notify_application_clock_switch();
}
电压监控(PVD)
// PVD配置
void pvd_init(void) {
// 使能PWR时钟
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
// 配置PVD阈值
PWR->CR &= ~PWR_CR_PLS;
PWR->CR |= PWR_CR_PLS_LEV6; // 2.9V
// 使能PVD
PWR->CR |= PWR_CR_PVDE;
// 配置EXTI线16
EXTI->IMR |= EXTI_IMR_MR16;
EXTI->RTSR |= EXTI_RTSR_TR16;
EXTI->FTSR |= EXTI_FTSR_TR16;
NVIC_EnableIRQ(PVD_IRQn);
}
// PVD中断处理
void PVD_IRQHandler(void) {
if (EXTI->PR & EXTI_PR_PR16) {
EXTI->PR = EXTI_PR_PR16;
if (PWR->CSR & PWR_CSR_PVDO) {
// 电压低于阈值
handle_low_voltage();
} else {
// 电压恢复
handle_voltage_recovery();
}
}
}
总结
YTM32B1ME0x的专用外设为汽车电子应用提供了重要的安全和监控功能:
关键特性:
-
硬件加密: AES/SM4硬件加速
-
随机数生成: 真随机数支持
-
双重看门狗: IWDG和WWDG保护
-
时钟监控: 自动故障切换
-
电压监控: PVD低电压检测
-
系统保护: 多层安全机制
这些专用外设确保了系统在恶劣环境下的可靠运行,满足汽车电子的严格要求。
在下一篇文章中,我们将探讨YTM32B1ME0x的应用实例与最佳实践。
// HCU初始化 void hcu_init(hcu_config_t *config) { // 使能HCU时钟 RCC->APB1ENR |= RCC_APB1ENR_HCUEN;
// 复位HCU
HCU->CR |= HCU_CR_RESET;
while (HCU->CR & HCU_CR_RESET);
// 配置算法和模式
HCU->CR = (HCU->CR & ~HCU_CR_ALGO_MASK) |
(config->algorithm << HCU_CR_ALGO_POS);
HCU->CR = (HCU->CR & ~HCU_CR_MODE_MASK) |
(config->mode << HCU_CR_MODE_POS);
// 配置密钥长度
if (config->algorithm == HCU_ALGORITHM_AES) {
HCU->CR = (HCU->CR & ~HCU_CR_KEYSIZE_MASK) |
(config->key_size << HCU_CR_KEYSIZE_POS);
}
// 配置DMA
if (config->dma_enable) {
HCU->CR |= HCU_CR_DMAEN;
}
// 配置中断
if (config->interrupt_enable) {
HCU->IER |= HCU_IER_CCFIE; // 计算完成中断
NVIC_EnableIRQ(HCU_IRQn);
}
// 使能HCU
HCU->CR |= HCU_CR_EN;
}
// AES加密 hcu_status_t hcu_aes_encrypt(const uint8_t *key, const uint8_t *plaintext, uint8_t ciphertext, uint32_t length) { // 设置密钥 for (int i = 0; i < 4; i++) { HCU->KEYR[i] = ((uint32_t)key)[i]; }
// 设置加密模式
HCU->CR |= HCU_CR_ENCRYPT;
// 处理数据块
uint32_t blocks = length / 16; // AES块大小为16字节
for (uint32_t i = 0; i < blocks; i++) {
// 输入数据
for (int j = 0; j < 4; j++) {
HCU->DINR = ((uint32_t*)plaintext)[i * 4 + j];
}
// 等待计算完成
while (!(HCU->SR & HCU_SR_CCF));
// 读取输出
for (int j = 0; j < 4; j++) {
((uint32_t*)ciphertext)[i * 4 + j] = HCU->DOUTR;
}
// 清除完成标志
HCU->SR |= HCU_SR_CCF;
}
return HCU_STATUS_OK;
}
// SM4加密 hcu_status_t hcu_sm4_encrypt(const uint8_t *key, const uint8_t *plaintext, uint8_t *ciphertext, uint32_t length) { // 配置SM4算法 HCU->CR = (HCU->CR & ~HCU_CR_ALGO_MASK) | HCU_ALGORITHM_SM4;
// 设置密钥
for (int i = 0; i < 4; i++) {
HCU->KEYR[i] = ((uint32_t*)key)[i];
}
// 设置加密模式
HCU->CR |= HCU_CR_ENCRYPT;
// 处理数据(SM4也是16字节块)
uint32_t blocks = length / 16;
for (uint32_t i = 0; i < blocks; i++) {
// 输入数据
for (int j = 0; j < 4; j++) {
HCU->DINR = ((uint32_t*)plaintext)[i * 4 + j];
}
// 等待计算完成
while (!(HCU->SR & HCU_SR_CCF));
// 读取输出
for (int j = 0; j < 4; j++) {
((uint32_t*)ciphertext)[i * 4 + j] = HCU->DOUTR;
}
// 清除完成标志
HCU->SR |= HCU_SR_CCF;
}
return HCU_STATUS_OK;
}
// SHA哈希计算 hcu_status_t hcu_sha256_hash(const uint8_t *data, uint32_t length, uint8_t *hash) { // 配置SHA-256算法 HCU->CR = (HCU->CR & ~HCU_CR_ALGO_MASK) | HCU_ALGORITHM_SHA; HCU->CR = (HCU->CR & ~HCU_CR_SHA_TYPE_MASK) | HCU_SHA_TYPE_256;
// 初始化SHA
HCU->CR |= HCU_CR_INIT;
// 处理数据
uint32_t remaining = length;
const uint8_t *ptr = data;
while (remaining > 0) {
uint32_t chunk_size = (remaining >= 64) ? 64 : remaining;
// 输入数据
for (uint32_t i = 0; i < chunk_size; i += 4) {
uint32_t word = 0;
for (int j = 0; j < 4 && (i + j) < chunk_size; j++) {
word |= (ptr[i + j] << (j * 8));
}
HCU->DINR = word;
}
// 如果是最后一块,设置最终标志
if (remaining <= 64) {
HCU->CR |= HCU_CR_DCAL;
}
// 等待处理完成
while (!(HCU->SR & HCU_SR_DCIS));
ptr += chunk_size;
remaining -= chunk_size;
}
// 等待哈希计算完成
while (!(HCU->SR & HCU_SR_DCIS));
// 读取哈希值
for (int i = 0; i < 8; i++) {
((uint32_t*)hash)[i] = HCU->HR[i];
}
return HCU_STATUS_OK;
}
// HCU中断处理 void HCU_IRQHandler(void) { if (HCU->SR & HCU_SR_CCF) { // 计算完成 HCU->SR |= H
:专用外设与系统监控&spm=1001.2101.3001.5002&articleId=149654775&d=1&t=3&u=6a11b7bae8374144ac446e82a68ebe05)
70

被折叠的 条评论
为什么被折叠?



