STM32项目中,可通用的源文件


参考资料:

本博客的内容和程序主要参考正点原点 hal 库开发手册
以下实例使用stm32l4中的内部时钟进行工作,可直接使用STM32cube图形化配置:

sys文件夹代码介绍

  sys 文件夹内包含了 sys.c 和 sys.h 两个文件。在 sys.h 里面定义了 STM32 的时钟配置函数(不可缺少)和汇编函数。

sys.h

#ifndef _SYS_H
#define _SYS_H
#include "stm32l4xx.h"

//0,不支持os
//1,支持os
#define SYSTEM_SUPPORT_OS		0		//定义系统文件夹是否支持OS
///
//定义一些常用的数据类型短关键字 
typedef int32_t  s32;
typedef int16_t s16;
typedef int8_t  s8;

typedef const int32_t sc32;  
typedef const int16_t sc16;  
typedef const int8_t sc8;  

typedef __IO int32_t  vs32;
typedef __IO int16_t  vs16;
typedef __IO int8_t   vs8;

typedef __I int32_t vsc32;  
typedef __I int16_t vsc16; 
typedef __I int8_t vsc8;   

typedef uint32_t  u32;
typedef uint16_t u16;
typedef uint8_t  u8;

typedef const uint32_t uc32;  
typedef const uint16_t uc16;  
typedef const uint8_t uc8; 

typedef __IO uint32_t  vu32;
typedef __IO uint16_t vu16;
typedef __IO uint8_t  vu8;

typedef __I uint32_t vuc32;  
typedef __I uint16_t vuc16; 
typedef __I uint8_t vuc8;  
	 


void _Error_Handler(char *, int);
#define Error_Handler() _Error_Handler(__FILE__, __LINE__)
/* Configure the System clock to have a frequency of 80 MHz */
void SystemClock_Config(void);
//以下为汇编函数
void WFI_SET(void);		//执行WFI指令
void INTX_DISABLE(void);//关闭所有中断
void INTX_ENABLE(void);	//开启所有中断
void MSR_MSP(u32 addr);	//设置堆栈地址 
#endif

sys.c

#include "sys.h"

/**
  * @brief  System Clock Configuration
  *         The system Clock is configured as follow : 
  *            System Clock source            = PLL (HSI16)
  *            SYSCLK(Hz)                     = 80000000
  *            HCLK(Hz)                       = 80000000
  *            AHB Prescaler                  = 1
  *            APB1 Prescaler                 = 1
  *            APB2 Prescaler                 = 1
  *            HSI16 Frequency(Hz)            = 16000000
  *            PLL_M                          = 4
  *            PLL_N                          = 40
  *            PLL_R                          = 2
  *            PLL_P                          = 7
  *            PLL_Q                          = 4
  *            Flash Latency(WS)              = 4
  * @param  None
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  /* HSI16 is enabled after System reset, activate PLL with HSI16 as source */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 40;
  RCC_OscInitStruct.PLL.PLLR = 2;
  RCC_OscInitStruct.PLL.PLLP = 7;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    /* Initialization Error */
		Error_Handler();
    while(1);
  }
  
  /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
     clocks dividers */
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;  
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;  
  if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    /* Initialization Error */
		Error_Handler();
    while(1);
  }
}



/************************ Debug Handle Functions  ***********************/
/**
  * @brief  This function is executed in case of error occurrence.
  * @param  file: The file name as string.
  * @param  line: The line in file as a number.
  * @retval None
  */
void _Error_Handler(char *file, int line)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
//	printf("Occur to error: file %s on line %d\r\n", file, line);
  while(0)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}


#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{ 
 /* User can add his own implementation to report the file name and line number,
  tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  printf("Wrong parameters value: file %s on line %d\r\n", file, line);

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

//THUMB指令不支持汇编内联
//采用如下方法实现执行汇编指令WFI  
__asm void WFI_SET(void)
{
	WFI;		  
}
//关闭所有中断(但是不包括fault和NMI中断)
__asm void INTX_DISABLE(void)
{
	CPSID   I
	BX      LR	  
}
//开启所有中断
__asm void INTX_ENABLE(void)
{
	CPSIE   I
	BX      LR  
}
//设置栈顶地址
//addr:栈顶地址
__asm void MSR_MSP(u32 addr) 
{
	MSR MSP, r0 			//set Main Stack value
	BX r14
}


delay文件夹代码介绍

  delay 文件夹内包含了 delay.c 和 delay.h 两个文件,这两个文件用来实现系统的延时功能。使用 systick 时钟的中断与非中断两种方法进行延迟,而不使用低效率的程序延迟等待。以下使用非中断的方式:
delay.h

#ifndef _DELAY_H
#define _DELAY_H
#include <sys.h>	  


/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
void delay_init(u8 SYSCLK);
void delay_ms(u16 nms);
void delay_us(u32 nus);

#endif

delay.c

#include "delay.h"
#include "sys.h"


static u8  fac_us=0;							//us delay frequency times.			   
 
 
/***************************************************************************//**
 * @brief Delay init function
 *
 * @param SYSCLK - System clock frequency select,and unit MHz.
 *
 * @return none.
*******************************************************************************/   
void delay_init(u8 SYSCLK)
{
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//SysTick频率为HCLK
	fac_us=SYSCLK;		
}								    
 
 
//Delay nus function (note the range of nms)		
//SysTick->LOAD为24bit寄存器,其范围: nms < 16777215/fac_us = 209000
void delay_us(u32 nus)
{		
	u32 temp;	    	 
	SysTick->LOAD=nus*fac_us; 					//时间加载  		 
	SysTick->VAL=0x00;        					//清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;	//开始倒数  
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));		//等待时间到达  
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;	//关闭计数器
	SysTick->VAL =0X00;      					//清空计数器 
}
 
//Delay nms function	
void delay_ms(u16 nms)
{	 		  	  
	u32 i;
	for(i=0;i<nms;i++) delay_us(1000);    
} 


usart文件夹代码介绍

  usart 文件夹内包含了 usart.c 和 usart.h 两个文件。这两个文件用于串口的初始化和中断接收。
usart.h

#ifndef _USART_H
#define _USART_H
#include "stm32l431xx.h"
#include "sys.h"
#include "stdio.h"	


/******************************************************************************/
/********************************  usart  *************************************/
/******************************************************************************/
#define USART_REC_LEN  			200  	//定义最大接收字节数 200
#define EN_USART1_RX 			  1		  //使能(1)/禁止(0)串口1接收
#define RXBUFFERSIZE 			  1	 		//缓存大小


/******************************************************************************/
/************************ Variables Definitions *******************************/
/******************************************************************************/
extern u8  USART_RX_BUF[USART_REC_LEN];  //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u8  USART_RX_Flag;							 	 //接收完成标志
extern u16 USART_RX_Count;						 	 //接收数据计数器 
extern u8  aRxBuffer[RXBUFFERSIZE];			 //HAL库USART接收Buffer
extern UART_HandleTypeDef UART1_Handler; //UART句柄

/******************************************************************************/
/************************ Functions Declarations ******************************/
/******************************************************************************/
//如果想串口中断接收,请不要注释以下宏定义
void uart_init(USART_TypeDef * uart, u32 bound);
void Usart1Send(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

#endif

usart.c

#include "usart.h"

#if EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误   	
u8 USART_RX_BUF[USART_REC_LEN] = {0};     //接收缓冲,最大USART_REC_LEN个字节.
u8 USART_RX_Flag = 0;										  //接收完成标志
u16 USART_RX_Count = 0;								 		//接收数据计数器 
u8 aRxBuffer[RXBUFFERSIZE];								//HAL库使用的串口接收缓冲


UART_HandleTypeDef UART1_Handler; //UART句柄

/***************************************************************************//**
 * @brief USART init function
 *
 * @param uart - uart channel to select.
 * @param bound - uart baudrate to transmit.
 *
 * @return none.
*******************************************************************************/
void uart_init(USART_TypeDef * uart, u32 bound)
{	
	UART1_Handler.Instance=uart;					    			  	
	UART1_Handler.Init.BaudRate=bound;				  		    
	UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   
	UART1_Handler.Init.StopBits=UART_STOPBITS_1;	    	
	UART1_Handler.Init.Parity=UART_PARITY_NONE;		   	  
	UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   
	UART1_Handler.Init.Mode=UART_MODE_TX_RX;		  		  
	if (HAL_UART_Init(&UART1_Handler) != HAL_OK)					   				  //HAL_UART_Init() function including enable uart
	{
		_Error_Handler(__FILE__, __LINE__);
	}
	
	HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
}

//UART底层初始化,时钟使能,引脚配置,中断配置
//此函数会被HAL_UART_Init()调用
//huart:串口句柄

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    //GPIO端口设置
	GPIO_InitTypeDef GPIO_Initure;
	
	if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
	{
		__HAL_RCC_GPIOA_CLK_ENABLE();			  //使能GPIOA时钟
		__HAL_RCC_USART1_CLK_ENABLE();			//使能USART1时钟
	
		GPIO_Initure.Pin=GPIO_PIN_9 | GPIO_PIN_10;			//PA9 和 PA10
		GPIO_Initure.Mode=GPIO_MODE_AF_PP;		//复用推挽输出
		GPIO_Initure.Pull=GPIO_PULLUP;			//上拉
		GPIO_Initure.Speed=GPIO_SPEED_FAST;		//高速
		GPIO_Initure.Alternate=GPIO_AF7_USART1;	//复用为USART1
		HAL_GPIO_Init(GPIOA,&GPIO_Initure);	   	//初始化PA9 和 PA10
		
#if EN_USART1_RX
		HAL_NVIC_EnableIRQ(USART1_IRQn);				    //使能USART1中断通道
		HAL_NVIC_SetPriority(USART1_IRQn,3,3);			//抢占优先级3,子优先级3
#endif	
	}

}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART1)//如果是串口1
	{
		USART_RX_BUF[USART_RX_Count] = aRxBuffer[0];
		USART_RX_Count++;
		if(aRxBuffer[0] == '\n') {
			USART_RX_Flag = 1;
//			printf("yes");
		}
		if(USART_RX_Count > 10) {
			Usart1Send(&UART1_Handler, USART_RX_BUF, USART_RX_Count);
			USART_RX_Count = 0;
			USART_RX_Flag = 0;
		}			
	}
}

//串口1中断服务程序
void USART1_IRQHandler(void)                	
{ 
	u32 timeout=0;
	
	HAL_UART_IRQHandler(&UART1_Handler);	//调用HAL库中断处理公用函数
	
	timeout=0;
  while (HAL_UART_GetState(&UART1_Handler) != HAL_UART_STATE_READY)//等待就绪
	{
	   timeout++;超时处理
     if(timeout>HAL_MAX_DELAY) break;		
	
	}
     
	timeout=0;
	while(HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1
	{
		 timeout++; //超时处理
		 if(timeout>HAL_MAX_DELAY) break;	
	}
} 
#endif	


/* uart interrupt send data */
void Usart1Send(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
	   HAL_UART_Transmit(&UART1_Handler, pData, Size, 10);  //10ms
}


 #ifdef __GNUC__
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */

PUTCHAR_PROTOTYPE
{
  HAL_UART_Transmit(&UART1_Handler, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}


malloc文件夹代码介绍

STM32内存管理

  1. 由于malloc和free是标准的库函数,使用时容易造成内存碎片,盲目使用会造成内存溢出
  2. 单片机的内存都比较小,而且没有MMU,可能会因为空间不足而分配失败,导致系统崩溃
  3. 单片机中如果是大的内存分配,而且malloc和free的次数不是特别频繁,可以直接调用库函数
  4. 如果对内存频繁操作,最好自己实现一个内存管理

malloc.h

#ifndef _MALLOC_H
#define _MALLOC_H
#include "sys.h" 

#ifndef NULL
#define NULL 0
#endif

//定义三个内存池
#define SRAMIN 	0  //内部内存池
#define SRAMEX 	1  //外部内存池
#define SRAMCCM 2  //CCM内存池(此部分SRAM仅仅CPU可以访问!!!)

#define SRAMBANK  3 //定义支持的SRAM块数


//mem1内存参数设定,mem1完全处于内部SRAM里面
#define MEM1_BLOCK_SIZE	32  			//内存块大小为32字节
#define MEM1_MAX_SIZE		100*1024 	//最大管理内存 110k
#define MEM1_ALLOC_TABLE_SIZE MEM1_MAX_SIZE/MEM1_BLOCK_SIZE  //内存表大小

//mem2内存参数设定,mem2处于外部SRAM里面
#define MEM2_BLOCK_SIZE	32  			//内存块大小为32字节
#define MEM2_MAX_SIZE		200*1024 	//最大管理内存 200k
#define MEM2_ALLOC_TABLE_SIZE MEM2_MAX_SIZE/MEM2_BLOCK_SIZE  //内存表大小

//mem3内存参数设定,mem3处于CCM,用于管理CCM(特别注意,这部分SRAM,近CPU可以访问)
#define MEM3_BLOCK_SIZE	32  			//内存块大小为32字节
#define MEM3_MAX_SIZE		60*1024 	//最大管理内存 60k
#define MEM3_ALLOC_TABLE_SIZE MEM3_MAX_SIZE/MEM3_BLOCK_SIZE  //内存表大小

//内存管理控制器
struct _m_mallco_dev
{
	void (*init)(u8);  		//初始化
	u8 (*perused)(u8); 		//内存使用率
	u8 *membase[SRAMBANK]; //内存池,管理SRAMBANK个区域的内存
	u16 *memmap[SRAMBANK];  //内存状态表
	u8 memrdy[SRAMBANK];   //内存管理是否就绪
};
extern struct _m_mallco_dev mallco_dev;  //在malloc.c里面定义

void mymemset(void *s,u8 c,u32 count);	 //设置内存
void mymemcpy(void *des,void *src,u32 n);//复制内存     
void mymem_init(u8 memx);					 //内存管理初始化函数(外/内部调用)
u32 mymem_malloc(u8 memx,u32 size);		 //内存分配(内部调用)
u8 mymem_free(u8 memx,u32 offset);		 //内存释放(内部调用)
u8 mem_perused(u8 memx);				 //获得内存使用率(外/内部调用) 

//用户调用函数
void myfree(u8 memx,void *ptr);  			//内存释放(外部调用)
void *mymalloc(u8 memx,u32 size);			//内存分配(外部调用)
void *myrealloc(u8 memx,void *ptr,u32 size);//重新分配内存(外部调用)
#endif

malloc.c

#include "malloc.h"

//内存池(4字节对齐)
__align(4) u8 mem1base[MEM1_MAX_SIZE];
__align(4) u8 mem2base[MEM2_MAX_SIZE] __attribute__((at(0x68000000))); //外部SRAM内存池
__align(4) u8 mem3base[MEM3_MAX_SIZE] __attribute__((at(0x10000000))); //内部CMM内存池
//内存管理表
u16 mem1mapbase[MEM1_ALLOC_TABLE_SIZE];													//内部SRAM内存池MAP
u16 mem2mapbase[MEM2_ALLOC_TABLE_SIZE] __attribute__((at(0X68000000+MEM2_MAX_SIZE)));	//外部SRAM内存池MAP
u16 mem3mapbase[MEM3_ALLOC_TABLE_SIZE] __attribute__((at(0X10000000+MEM3_MAX_SIZE)));	//内部CCM内存池MAP
//内存管理参数	   
const u32 memtblsize[SRAMBANK]={MEM1_ALLOC_TABLE_SIZE,MEM2_ALLOC_TABLE_SIZE,MEM3_ALLOC_TABLE_SIZE};	//内存表大小
const u32 memblksize[SRAMBANK]={MEM1_BLOCK_SIZE,MEM2_BLOCK_SIZE,MEM3_BLOCK_SIZE};					//内存分块大小
const u32 memsize[SRAMBANK]={MEM1_MAX_SIZE,MEM2_MAX_SIZE,MEM3_MAX_SIZE};							//内存总大小

//内存管理控制器
struct _m_mallco_dev mallco_dev=
{
	mymem_init,							//内存初始化
	mem_perused,						//内存使用率
	mem1base,mem2base,mem3base,			//内存池
	mem1mapbase,mem2mapbase,mem3mapbase,//内存管理状态表
	0,0,0,  		 					//内存管理未就绪
};

//复制内存
//*des:目的地址
//*src:源地址
//n:需要复制的内存长度(字节为单位)
void mymemcpy(void *des,void *src,u32 n)
{
	u8 *xdes = des;
	u8 *xsrc = src;
	while(n--) *xdes++ = *xsrc++;
}

//设置内存
//*s:内存首地址
//c :要设置的值
//count:需要设置的内存大小(字节为单位)
void mymemset(void*s,u8 c,u32 count)
{
	u8 *xs = s;
	while(count--) *xs++=c;
}

//内存管理初始化  
//memx:所属内存块
void mymem_init(u8 memx)
{
	mymemset(mallco_dev.memmap[memx],0,memtblsize[memx]*2); //内存状态表清零
	mymemset(mallco_dev.membase[memx], 0,memsize[memx]);	//内存池所有数据清零  
	mallco_dev.memrdy[memx]=1;								//内存管理初始化OK  
}

//获取内存使用率
//memx:所属内存块
//返回值:使用率(0~100)
u8 mem_perused(u8 memx)  
{  
    u32 used=0;  
    u32 i;  
    for(i=0;i<memtblsize[memx];i++)  
    {  
        if(mallco_dev.memmap[memx][i])used++; 
    } 
    return (used*100)/(memtblsize[memx]);  
} 

//内存分配(内部调用)
//memx:所属内存块
//size:要分配的内存大小(字节)
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址 
u32 mymem_malloc(u8 memx,u32 size)  
{  
    signed long offset=0;  
    u16 nmemb;	//需要的内存块数  
		u16 cmemb=0;//连续空内存块数
    u32 i;  
    if(!mallco_dev.memrdy[memx])mallco_dev.init(memx);//未初始化,先执行初始化 
    if(size==0)return 0XFFFFFFFF;//不需要分配
    nmemb=size/memblksize[memx];  	//获取需要分配的连续内存块数
    if(size%memblksize[memx])nmemb++;  
    for(offset=memtblsize[memx]-1;offset>=0;offset--)//搜索整个内存控制区  
    {     
		if(!mallco_dev.memmap[memx][offset])cmemb++;//连续空内存块数增加
		else cmemb=0;								//连续内存块清零
		if(cmemb==nmemb)							//找到了连续nmemb个空内存块
		{
            for(i=0;i<nmemb;i++)  					//标注内存块非空 
            {  
                mallco_dev.memmap[memx][offset+i]=nmemb;  
            }  
            return (offset*memblksize[memx]);//返回偏移地址  
		}
    }  
    return 0XFFFFFFFF;//未找到符合分配条件的内存块  
}  

//释放内存(内部调用) 
//memx:所属内存块
//offset:内存地址偏移
//返回值:0,释放成功;1,释放失败;  
u8 mymem_free(u8 memx,u32 offset)  
{  
	int i;  
  if(!mallco_dev.memrdy[memx])//未初始化,先执行初始化
	{
		mallco_dev.init(memx);    
    return 1;//未初始化  
  }  
  if(offset<memsize[memx])//偏移在内存池内. 
  {  
		int index=offset/memblksize[memx];			//偏移所在内存块号码  
    int nmemb=mallco_dev.memmap[memx][index];	//内存块数量
    for(i=0;i<nmemb;i++)  						//内存块清零
    {  
			mallco_dev.memmap[memx][index+i]=0;  
    }  
    return 0;  
  }else return 2;//偏移超区了.  
}  

//释放内存(外部调用) 
//memx:所属内存块
//ptr:内存首地址 
void myfree(u8 memx,void *ptr)  
{  
	u32 offset;  
    if(ptr==NULL)return;//地址为0.  
 	offset=(u32)ptr-(u32)mallco_dev.membase[memx];  
    mymem_free(memx,offset);//释放内存     
}  

//分配内存(外部调用)
//memx:所属内存块
//size:内存大小(字节)
//返回值:分配到的内存首地址.
void *mymalloc(u8 memx,u32 size)  
{  
  u32 offset;  									      
	offset=mymem_malloc(memx,size);  	   				   
  if(offset==0XFFFFFFFF)return NULL;  
  else return (void*)((u32)mallco_dev.membase[memx]+offset);  
}  

//重新分配内存(外部调用)
//memx:所属内存块
//*ptr:旧内存首地址
//size:要分配的内存大小(字节)
//返回值:新分配到的内存首地址.
void *myrealloc(u8 memx,void *ptr,u32 size)  
{  
    u32 offset;  
    offset=mymem_malloc(memx,size);  
    if(offset==0XFFFFFFFF)return NULL;     
    else  
    {  									   
	    mymemcpy((void*)((u32)mallco_dev.membase[memx]+offset),ptr,size);	//拷贝旧内存内容到新内存   
        myfree(memx,ptr);  											  		//释放旧内存
        return (void*)((u32)mallco_dev.membase[memx]+offset);  				//返回新内存首地址
    }  
}

  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将Google Test移植到STM32项目,可以按照以下步骤进行操作: 1. 下载Google Test库:首先,从Google Test的官方仓库(https://github.com/google/googletest)下载最新的Google Test库。 2. 配置STM32项目:打开您的STM32项目,并确保已经配置好了适当的编译器和开发环境。确保您已经在项目包含了适当的STM32库文件和头文件。 3. 添加Google Test到项目:将下载的Google Test库解压缩,并将其添加到您的STM32项目的源代码目录。 4. 配置Google Test:进入Google Test库的目录,找到"CMakeLists.txt"文件并打开它。根据您的STM32项目配置,对"CMakeLists.txt"文件进行必要的修改。例如,您可能需要更改编译器设置、链接器脚本等。 5. 生成Google Test库:使用CMake工具生成适用于您的STM32项目的Google Test库。可以使用命令行或图形界面工具来运行CMake。 6. 配置测试代码:在STM32项目创建一个新的文件夹,用于存放测试代码。在该文件夹创建一个新的C++源文件,例如"test.cpp"。 7. 编写测试代码:在"test.cpp"文件编写您的测试代码。使用Google Test提供的宏来定义测试用例和断言。确保包含Google Test头文件,并链接Google Test库。 8. 配置测试构建选项:打开您的STM32项目的构建选项,并确保已经配置了适当的编译器和链接器设置。将Google Test库的头文件目录添加到“Include Paths”,并将Google Test库的库文件目录添加到“Libraries Paths”。然后,在“链接器”设置,将Google Test库添加到链接的库文件列表。 9. 构建并下载项目:构建并下载您的STM32项目到目标设备。确保测试代码在项目正确编译和链接。 10. 执行测试:在目标设备上运行您的STM32项目,并执行测试代码以执行Google Test测试。 这样,您就成功将Google Test移植到您的STM32项目。您可以根据需要编写更多的测试用例,并在每次构建时执行这些测试来验证项目的正确性。请注意,移植Google Test到STM32项目可能需要进行一些额外的配置和调整,以适应特定的硬件和编译环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值