大家好,欢迎来到IT知识分享网。
一、开发环境
硬件:stm32f407 野火开发板
系统:rt-thread V4.1.1
原理图:


8Mbits 即 1MByte
二、工程配置
工程基于单片机 基于 rt-thread 系统 多内存管理 memheap算法,CCM内存或外部SDRAM的使用
网址:https://mp.weixin..com/s/3wAJu8_ipilY9mM0-MrpJA
使用的是 memheap 管理算法。
工程开启SRAM

生成工程




static void HAL_FSMC_MspInit(void){
/* USER CODE BEGIN FSMC_MspInit 0 */
/* USER CODE END FSMC_MspInit 0 */
GPIO_InitTypeDef GPIO_InitStruct ={0};
if (FSMC_Initialized) {
return;
}
FSMC_Initialized = 1;
/* Peripheral clock enable */
__HAL_RCC_FSMC_CLK_ENABLE();
/ FSMC GPIO Configuration
PF0 ——> FSMC_A0
PF1 ——> FSMC_A1
PF2 ——> FSMC_A2
PF3 ——> FSMC_A3
PF4 ——> FSMC_A4
PF5 ——> FSMC_A5
PF12 ——> FSMC_A6
PF13 ——> FSMC_A7
PF14 ——> FSMC_A8
PF15 ——> FSMC_A9
PG0 ——> FSMC_A10
PG1 ——> FSMC_A11
PE7 ——> FSMC_D4
PE8 ——> FSMC_D5
PE9 ——> FSMC_D6
PE10 ——> FSMC_D7
PE11 ——> FSMC_D8
PE12 ——> FSMC_D9
PE13 ——> FSMC_D10
PE14 ——> FSMC_D11
PE15 ——> FSMC_D12
PD8 ——> FSMC_D13
PD9 ——> FSMC_D14
PD10 ——> FSMC_D15
PD11 ——> FSMC_A16
PD12 ——> FSMC_A17
PD13 ——> FSMC_A18
PD14 ——> FSMC_D0
PD15 ——> FSMC_D1
PG2 ——> FSMC_A12
PG3 ——> FSMC_A13
PG4 ——> FSMC_A14
PG5 ——> FSMC_A15
PD0 ——> FSMC_D2
PD1 ——> FSMC_D3
PD4 ——> FSMC_NOE
PD5 ——> FSMC_NWE
PG10 ——> FSMC_NE3 //sram zhengdian ; yehuo : 液晶接口-FSMC模式
PG12 ——> FSMC_NE4 //lcd zhengdian ; yehuo : sram
PE0 ——> FSMC_NBL0
PE1 ——> FSMC_NBL1
*/
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_12|GPIO_PIN_13
|GPIO_PIN_14|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15
|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USER CODE BEGIN FSMC_MspInit 1 */
/* USER CODE END FSMC_MspInit 1 */
}
void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram){
/* USER CODE BEGIN SRAM_MspInit 0 */
/* USER CODE END SRAM_MspInit 0 */
HAL_FSMC_MspInit();
/* USER CODE BEGIN SRAM_MspInit 1 */
/* USER CODE END SRAM_MspInit 1 */
}
static uint32_t FSMC_DeInitialized = 0;
static void HAL_FSMC_MspDeInit(void){
/* USER CODE BEGIN FSMC_MspDeInit 0 */
/* USER CODE END FSMC_MspDeInit 0 */
if (FSMC_DeInitialized) {
return;
}
FSMC_DeInitialized = 1;
/* Peripheral clock enable */
__HAL_RCC_FSMC_CLK_DISABLE();
/ FSMC GPIO Configuration
PF0 ——> FSMC_A0
PF1 ——> FSMC_A1
PF2 ——> FSMC_A2
PF3 ——> FSMC_A3
PF4 ——> FSMC_A4
PF5 ——> FSMC_A5
PF12 ——> FSMC_A6
PF13 ——> FSMC_A7
PF14 ——> FSMC_A8
PF15 ——> FSMC_A9
PG0 ——> FSMC_A10
PG1 ——> FSMC_A11
PE7 ——> FSMC_D4
PE8 ——> FSMC_D5
PE9 ——> FSMC_D6
PE10 ——> FSMC_D7
PE11 ——> FSMC_D8
PE12 ——> FSMC_D9
PE13 ——> FSMC_D10
PE14 ——> FSMC_D11
PE15 ——> FSMC_D12
PD8 ——> FSMC_D13
PD9 ——> FSMC_D14
PD10 ——> FSMC_D15
PD11 ——> FSMC_A16
PD12 ——> FSMC_A17
PD13 ——> FSMC_A18
PD14 ——> FSMC_D0
PD15 ——> FSMC_D1
PG2 ——> FSMC_A12
PG3 ——> FSMC_A13
PG4 ——> FSMC_A14
PG5 ——> FSMC_A15
PD0 ——> FSMC_D2
PD1 ——> FSMC_D3
PD4 ——> FSMC_NOE
PD5 ——> FSMC_NWE
PG10 ——> FSMC_NE3
PG12 ——> FSMC_NE4
PE0 ——> FSMC_NBL0
PE1 ——> FSMC_NBL1
*/
HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_12|GPIO_PIN_13
|GPIO_PIN_14|GPIO_PIN_15);
HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_10|GPIO_PIN_12);
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1);
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15
|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5);
/* USER CODE BEGIN FSMC_MspDeInit 1 */
/* USER CODE END FSMC_MspDeInit 1 */
}
void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram){
/* USER CODE BEGIN SRAM_MspDeInit 0 */
/* USER CODE END SRAM_MspDeInit 0 */
HAL_FSMC_MspDeInit();
/* USER CODE BEGIN SRAM_MspDeInit 1 */
/* USER CODE END SRAM_MspDeInit 1 */
}
工程修改 drv_sram.h
#ifndef __SRAM_PORT_H__
#define __SRAM_PORT_H__
/*
可以输入的宏
对应的地址区域
FSMC_Bank1_NORSRAM1 — 0x-0x63FFFFFF
FSMC_Bank1_NORSRAM2 — 0x-0x67FFFFFF
FSMC_Bank1_NORSRAM3 — 0x-0x6BFFFFFF
FSMC_Bank1_NORSRAM4 — 0x6C000000-0x6FFFFFFF
*/
/* parameters for sram peripheral */
///* stm32f4 Bank3:0X */
//#define SRAM_BANK_ADDR ((uint32_t)0X)
/* stm32f4 Bank4:0X6C000000 */
#define SRAM_BANK_ADDR ((uint32_t)0X6C000000)
/* data width: 8, 16, 32 */
#define SRAM_DATA_WIDTH 8
/* sram size */
#if SRAM_DATA_WIDTH == 8
#define SRAM_SIZE ((uint32_t)0x00)
#elif SRAM_DATA_WIDTH == 16
#define SRAM_SIZE ((uint32_t)0x00080000)
#else
#endif
#endif
工程修改 drv_sram.c
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#ifdef BSP_USING_SRAM
#include “drv_sram.h”
#define DRV_DEBUG
#define LOG_TAG “drv.sram”
#include <drv_log.h>
#ifdef RT_USING_MEMHEAP_AS_HEAP
static struct rt_memheap sram_heap;
#endif
static SRAM_HandleTypeDef hsram;
static int rt_hw_sram_init(void)
{
int result = RT_EOK;
FSMC_NORSRAM_TimingTypeDef Timing = {0};
/ Perform the SRAM2 memory initialization sequence
*/
hsram.Instance = FSMC_NORSRAM_DEVICE;
hsram.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
/* hsram.Init */
hsram.Init.NSBank = FSMC_NORSRAM_BANK4;//野火NE4;正点:NE3–FSMC_NORSRAM_BANK3
hsram.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
hsram.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
#if SRAM_DATA_WIDTH == 8
hsram.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_8;
#elif SRAM_DATA_WIDTH == 16
hsram.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
#else
hsram.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_32;
#endif
hsram.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
hsram.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
hsram.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
hsram.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
hsram.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
hsram.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
hsram.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
hsram.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
hsram.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
hsram.Init.PageSize = FSMC_PAGE_SIZE_NONE;
/* Timing */
Timing.AddressSetupTime = 0;
Timing.AddressHoldTime = 0;
Timing.DataSetupTime = 8;
Timing.BusTurnAroundDuration = 0;
Timing.CLKDivision = 0;
Timing.DataLatency = 0;
Timing.AccessMode = FSMC_ACCESS_MODE_A;
/* ExtTiming */
if (HAL_SRAM_Init(&hsram, &Timing, &Timing) != HAL_OK)
{
LOG_E(“SRAM init failed!”);
result = -RT_ERROR;
}
else
{
LOG_D(“sram init success, mapped at 0x%X, size is %d bytes, data width is %d”, SRAM_BANK_ADDR, SRAM_SIZE, SRAM_DATA_WIDTH);
#ifdef RT_USING_MEMHEAP_AS_HEAP
/* If RT_USING_MEMHEAP_AS_HEAP is enabled, SRAM is initialized to the heap */
rt_memheap_init(&sram_heap, “sram”, (void *)SRAM_BANK_ADDR, SRAM_SIZE);
#endif
}
return result;
}
INIT_BOARD_EXPORT(rt_hw_sram_init);
#ifdef DRV_DEBUG
#ifdef FINSH_USING_MSH
static int sram_test(void)
{
int i = 0;
uint32_t start_time = 0, time_cast = 0;
#if SRAM_DATA_WIDTH == 8
char data_width = 1;
uint8_t data = 0;
#elif SRAM_DATA_WIDTH == 16
char data_width = 2;
uint16_t data = 0;
#else
char data_width = 4;
uint32_t data = 0;
#endif
/* write data */
LOG_D(“Writing the %ld bytes data, waiting….”, SRAM_SIZE);
start_time = rt_tick_get();
for (i = 0; i < SRAM_SIZE / data_width; i++)
{
#if SRAM_DATA_WIDTH == 8
*(__IO uint8_t *)(SRAM_BANK_ADDR + i * data_width) = (uint8_t)0x55;
#elif SRAM_DATA_WIDTH == 16
*(__IO uint16_t *)(SRAM_BANK_ADDR + i * data_width) = (uint16_t)0x5555;
#else
*(__IO uint32_t *)(SRAM_BANK_ADDR + i * data_width) = (uint32_t)0x;
#endif
}
time_cast = rt_tick_get() – start_time;
LOG_D(“Write data success, total time: %d.%03dS.”, time_cast / RT_TICK_PER_SECOND,
time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000));
/* read data */
LOG_D(“start Reading and verifying data, waiting….”);
for (i = 0; i < SRAM_SIZE / data_width; i++)
{
#if SRAM_DATA_WIDTH == 8
data = *(__IO uint8_t *)(SRAM_BANK_ADDR + i * data_width);
if (data != 0x55)
{
LOG_E(“SRAM test failed!”);
break;
}
#elif SRAM_DATA_WIDTH == 16
data = *(__IO uint16_t *)(SRAM_BANK_ADDR + i * data_width);
if (data != 0x5555)
{
LOG_E(“SRAM test failed!”);
break;
}
#else
data = *(__IO uint32_t *)(SRAM_BANK_ADDR + i * data_width);
if (data != 0x)
{
LOG_E(“SRAM test failed!”);
break;
}
#endif
}
if (i >= SRAM_SIZE / data_width)
{
LOG_D(“SRAM test success!”);
}
return RT_EOK;
}
MSH_CMD_EXPORT(sram_test, sram test);
#ifdef RT_USING_MEMHEAP_AS_HEAP
#define TEST_SIZE 4 * 1024
void mem_sram_test(void)
{
extern long list_memheap(void);
list_memheap();
rt_uint16_t malloc_count = 1;
char *test_buf = RT_NULL;
test_buf = (char *)rt_memheap_alloc(&sram_heap,TEST_SIZE);
rt_kprintf(“No %d, malloc ok,address is %x\r\n”, malloc_count++,test_buf);
while( test_buf != RT_NULL )
{
test_buf = (char *)rt_memheap_alloc(&sram_heap,TEST_SIZE);
if(test_buf != RT_NULL )
rt_kprintf(“No %d, malloc ok,address is %x\r\n”, malloc_count++,test_buf);
/* code */
}
rt_kprintf(“count:%d No memory\n”, malloc_count);
list_memheap();
}
MSH_CMD_EXPORT(mem_sram_test, mem_sram_test);
#endif
#endif /* FINSH_USING_MSH */
#endif /* DRV_DEBUG */
#endif /* BSP_USING_SRAM */
三、测试
测试结果:

重启,测试申请指定内存


免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/183749.html