如题,在使用malloc申请内存是地址会出现非法地址,程序处理完后有做free释放。堆栈设置
调试如图
灰小子:
奇怪的问题。方便把代码上传一下吗?
Susan Yang:
您在编译的时候是没有错误的?
PS:好久没有用IAR了,现在一直用CCS
yue feng1:
回复 灰小子:
您好,感谢回复。
测试发现使用malloc free就会出现非法地址, 如果使用固定数组申请则正常。请帮忙分析,TSK。
功能实现:IO口模拟SMBUS 功能code如下:
swi2c.c–>
#include "swi2c.h"#include "check.h"#include <stdlib.h>#include <string.h>
#define buff_size (64)
void SWI2CMST_init(void){ PxOUT &= ~(SCL | SDA); // Output settings always LOW PxSEL &= ~(SCL | SDA); // Set GPIO functions}
static void delay_us(uint16_t t){ while(t–);}
static bool SCL_Timeout(void){ uint16_t ucErrTime=0; while(SCL_READ == 0) { if(ucErrTime++>=10000)//10ms return false; } return true;}static bool SDA_Timeout(void){ uint16_t ucErrTime=0; while(SDA_READ != 0) { if(ucErrTime++>=1000)//1ms return false; } return true;}
void SWI2CMST_start(void){ SDA_1; // SDA = 1 //delay_us(I2CDELAYUSEC); // Quick delay SCL_1; // SCL = 1 delay_us(I2CDELAYUSEC); // Quick delay SDA_0; // SDA = 0 delay_us(I2CDELAYUSEC); // Quick delay SCL_0; // SCL = 0 delay_us(I2CDELAYUSEC); // Quick delay }
static void SWI2CMST_stop(void){ SDA_0; // SDA = 0 delay_us(I2CDELAYUSEC); // Quick delay SCL_1; // SCL = 1 SCL_Timeout(); delay_us(I2CDELAYUSEC); // Quick delay SDA_1; // SDA = 1 delay_us(I2CDELAYUSEC); // Quick delay }//成功返回0,失败返回1static bool SWI2CMST_txByte(uint8_t data){ uint8_t bits, temp; bool ack; SCL_0; // SCL = 0 temp = data; // Initialize temp variable bits = 0x08; // Load I2C bit counter while (bits > 0) // Loop until all bits are shifted { if (temp & BIT7) // Test data bit SDA_1; // SDA = 1 else SDA_0; // SDA = 0 delay_us(I2CDELAYUSEC); // Quick delay SCL_1; // SCL = 1 SCL_Timeout(); delay_us(I2CDELAYUSEC); // Quick delay temp <<= 1; // Shift bits 1 place to the left SCL_0; // SCL = 0 bits–; // Loop until 8 bits are sent } delay_us(I2CDELAYUSEC); //SDA_1; // SDA = 1 SCL_1; // SCL = 1 SCL_Timeout(); delay_us(I2CDELAYUSEC); // Quick delay ack = SDA_Timeout(); // Read ACK state from Slave SCL_0; // SCL = 0 return ack;}
static uint8_t SWI2CMST_rxByte(uint8_t ack){ uint8_t bits, data = 0;
SDA_1; // SDA = 1 bits = 0x08; // Load I2C bit counter while (bits > 0) // Loop until all bits are read { SCL_1; // SCL = 1 SCL_Timeout(); delay_us(I2CDELAYUSEC); // Quick delay data <<= 1; // Shift bits 1 place to the left if (SDA_READ) // Check digital input data++; // If input is high, store a '1' SCL_0; // SCL = 0 delay_us(I2CDELAYUSEC); // Quick delay bits–; // Decrement I2C bit counter } if (ack) // Need to send ACK to Slave? SDA_0; // Yes, so pull SDA low else SDA_1; // No, so keep SDA high SCL_1; // SCL = 1 delay_us(I2CDELAYUSEC); // Equivalent to sending N(ACK) SCL_0; // SCL = 0 SDA_1; // SDA = 1
return (data); // Return 8-bit data byte}
uint16_t p=0;bool SWI2CMST_ReadReg(uint8_t SlaveAddress, uint8_t Cmd, void *Data, uint16_t Datalen){ uint16_t totallen; uint8_t *buff; //uint8_t buff[buff_size]; bool status; if(Datalen>32) return false; #if (SWI2C_PEC_SUPPORTED == 1) if(Datalen>2) { totallen = Datalen + 5;//stt + addrw + cmd + stt + addrr + datalen + data0 … +datan + pec + stp } else { totallen = Datalen + 4;//stt + addrw + cmd + stt + addrr + data0 + data1 + pec + stp }#else if(Data>2) { totallen = Datalen + 4;//stt + addrw + cmd + stt + addrr + datalen + data0 … +datan + stp } else { totallen = Datalen + 3;//stt + addrw + cmd + stt + addrr + data0 + data1 + stp }#endif buff = (uint8_t *)malloc(buff_size); p=(uint16_t)buff; if(buff == NULL) return false; buff[0] = (SlaveAddress<<1); buff[1] = Cmd; buff[2] = (SlaveAddress<<1)+1; SWI2CMST_start(); // Send Start condition for (uint16_t i = 0; i < 2; i++) { status = SWI2CMST_txByte(buff[i]); // Send data and ack if(!status) break; } SWI2CMST_start(); // Send Start condition status = SWI2CMST_txByte(buff[2]); // Send data and ack for (uint16_t j = 0; j < (totallen-3); j++) { if(j == (totallen-4)) { buff[3+j] = SWI2CMST_rxByte(NACK); } else { buff[3+j] = SWI2CMST_rxByte(ACK); } } SWI2CMST_stop(); // Yes, send STOP condition#if (SWI2C_PEC_SUPPORTED == 1) if(buff[totallen-1] != Check_CRC8(buff, totallen-1)) { status = false; } else { if(Datalen>2) { buff += 4; totallen -= 5; //memcpy(Data, &buff[4], totallen-5); } else { buff += 3; totallen -= 4; //memcpy(Data, &buff[3], totallen-4); } memcpy(Data, buff, totallen); status = true; }#endif free(buff); return status;}
uint8_t Check_CRC8(uint8_t *Pmsg, uint16_t Msg_Size){ uint16_t i, j, carry; uint8_t CRCData, msg;
CRCData = *Pmsg++; // first byte loaded in "crc" for(i = 0 ; i < Msg_Size-1 ; i ++) { msg = *Pmsg++; // next byte loaded in "msg" for(j = 0 ; j < 8 ; j++) { carry = CRCData & 0x80; // check if MSB=1 CRCData = (CRCData << 1) | (msg >> 7); // Shift 1 bit of next byte into crc if(carry) CRCData ^= 7; // If MSB = 1, perform XOR msg <<= 1; // Shift left msg byte by 1 } } for(j = 0 ; j < 8 ; j++) { carry = CRCData & 0x80; CRCData <<= 1; if(carry) CRCData ^= 7; } return(CRCData);}
swi2c.h –>
#ifndef __SWI2C_H__#define __SWI2C_H__
#include "io430.h"#include <stdint.h>#include <stdbool.h>
#define PxSEL P4SEL // Port selection#define PxDIR P4DIR // Port direction#define PxOUT P4OUT // Port output#define PxIN P4IN // Port input
#define SDA BIT4 // Controls SDA line#define SCL BIT5 // Controls SCL line
#define I2CDELAYUSEC 3
#define SDA_1 PxDIR&=~(SDA) // Set to input [SDA = 1 via pullup]#define SDA_0 PxDIR|=(SDA) // Set to output [SDA = 0]#define SCL_1 PxDIR&=~(SCL) // Set to input [SCL = 1 via pullup]#define SCL_0 PxDIR|=(SCL) // Set to output [SCL = 0]
#define SDA_READ (PxIN & SDA)#define SCL_READ (PxIN & SCL)
#define NACK 0#define ACK 1
#define SWI2C_PEC_SUPPORTED (1)#define SWI2C_MAX_DATALEN (32)
typedef struct{ union { struct { uint8_t SCLTo : 1;//SCL拉低超时 uint8_t WaitACKErr : 1;//等待应答超时 uint8_t RSVD : 6; } bits; uint8_t Status; }byte;} I2CDrv_Status;
void SWI2CMST_init(void);
bool SWI2CMST_ReadReg(uint8_t SlaveAddress, uint8_t Cmd, void *Data, uint16_t Datalen);
#endif
main.c –>
int main( void ){ uint8_t txdata[32]={0}; // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD;
SysClock_Init(); SWI2CMST_init(); while(1) { delay_ms(50); SWI2CMST_ReadReg(0x0B, 0x09, txdata, 2); }}
yue feng1:
回复 Susan Yang:
您好,编译结果无错误。测试发现使用malloc free就会出现非法地址, 如果使用固定数组申请则正常,code详见1楼答复
灰小子:
回复 yue feng1:
感谢分享经验。这个是程序的逻辑问题。
Susan Yang:
回复 yue feng1:
很高兴您能解决问题。谢谢分享!