嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读 > Stm32_hal库IIC时钟拉伸的漏洞

Stm32_hal库IIC时钟拉伸的漏洞

iic可以开启时钟拉伸功能,这种功能可以让主机决定什么时候继续发送时钟,此功能作用时会将从机SCL拉低。

针对主机多读或者多写的情况(比如主机收10个字节,从机发送5个字节),hal库并未作处理,会导致从机一直拉低SCLHal库原来的程序是这样:

static voidI2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c){ if(hi2c->XferCount != 0U) {/* Write data to DR */hi2c->Instance->DR = *hi2c->pBuffPtr;/* Increment Buffer pointer */hi2c->pBuffPtr++;/* Update counter */hi2c->XferCount--; }}static voidI2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c){ if(hi2c->XferCount != 0U) {/* Read data from DR */*hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR;/* Increment Buffer pointer */hi2c->pBuffPtr++;/* Update counter */hi2c->XferCount--; }}

这个是原来的库函数,多读或者多写后,会触发btf中断进入这个函数,同时hi2c->XferCount0(原计划的数据量读写已经完成),导致btf中断函数什么也没做,SCL持续拉低.

可以做如下修改解决此问题

static void I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c){   if (hi2c->XferCount != 0U)    { /* Write data to DR */ hi2c->Instance->DR = *hi2c->pBuffPtr; /* Increment Buffer pointer */ hi2c->pBuffPtr++; /* Update counter */ hi2c->XferCount--; } else {  hi2c->Instance->CR1&= ~(1<<0);  hi2c->Instance->CR1|= (1<<0); }}static void I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c){   if (hi2c->XferCount != 0U) { /* Read data from DR */ *hi2c->pBuffPtr = (uint8_t)hi2c->Instance->DR; /* Increment Buffer pointer */ hi2c->pBuffPtr++; /* Update counter */ hi2c->XferCount--; } else {       hi2c->Instance->CR1&= ~(1<<0);       hi2c->Instance->CR1|= (1<<0); }}

这样清除btf标志位,结束此次通信。