5316 views|5 replies

2549

Posts

0

Resources
The OP
 

【ART-Pi Review】Part 3: Onboard Storage - SDRAM [Copy link]

 This post was last edited by Digital Leaf on 2021-7-6 22:52

Although the main chip STM32H750XBH6 of ART-Pi has 1MB of internal SRAM, it still has a 32-Mbytes SDRAM chip W9825G6KH on board.

Or start from a blank project

Before opening any components, let's take a look at the resources of ART-Pi.

Obviously there is no 1MB size. Looking at the source file, you can find the defined size

Only 512KB of size is used

After opening the SDRAM component, check the resource status again

The board support package is more convenient for chip support packages or porting them yourself. Many components will generate corresponding initialization code after directly checking them.

After checking, a macro definition is actually added to rtconfig.h

#define BSP_USING_SDRAM

This macro then triggers a series of conditional compilations

In this driver file, you can see some code for initializing the SDRAM interface. For using the FMC interface to connect to SDRAM, a lot of low-level timing operations are omitted. You only need to give a few interface and timing parameters.

When you really connect to rtthread, you can use rt_memheap_init(struct rt_memheap *memheap, const char *name, void *start_addr, rt_uint32_t size); memory heap initialization function

#define SDRAM_BANK_ADDR ((uint32_t)0XC0000000)

#define SDRAM_SIZE ((uint32_t)0x2000000)

How does this address come from? Combined with the manual and ART-Pi's hardware circuit connection

The chip select signal enables the use of FMC SDNE0, selects BANK1, then the address will come out naturally

Finally, the SDRA test. The rtthread official document provides several test ideas, such as continuously applying for memory

 for (i = 0; ; i++)
    {
        /* 每次分配 (1 << i) 大小字节数的内存空间 */
        ptr = rt_malloc(1 << i);

        /* 如果分配成功 */
        if (ptr != RT_NULL)
        {
            rt_kprintf("get memory :%d byte\n", (1 << i));
            /* 释放内存块 */
            rt_free(ptr);
            rt_kprintf("free memory :%d byte\n", (1 << i));
            ptr = RT_NULL;
        }
        else
        {
            rt_kprintf("try to get %d byte memory failed!\n", (1 << i));
            return;
        }
    }

For example, write data, read data, and then compare

for (i = 0; i < SDRAM_SIZE / data_width; i++)
{
	*(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width) = (uint16_t)0x5555;
}
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));


LOG_D("start Reading and verifying data, waiting....");
for (i = 0; i < SDRAM_SIZE / data_width; i++)
{
	data = *(__IO uint16_t *)(SDRAM_BANK_ADDR + i * data_width);
	if (data != 0x5555)
	{
		LOG_E("SDRAM test failed!");
		break;
	}

}
if (i >= SDRAM_SIZE / data_width)
{
	LOG_D("SDRAM test success!");
}

The results can be seen through the finsh interface

Because the application was made in multiples, it stopped after reaching 16Mb.

The read and write tests were also verified. When doing the read and write tests, it was found that rtthread studio does not support the simple way in keil to directly define variables to the specified external address.

uint16_t testsram[250000] __attribute__((at(0XC0000000)));

The reason is that the GCC compiler is used, and the GCC compiler does not support the __attribute__ ((at(address))) instruction

But if you must use this definition method, there is a way. You need to modify the .lds file mentioned in the previous article, define the data segment in it, and then define the variable in the data segment, which is a bit similar to the operation of ccs.

Latest reply

Thanks for sharing~~   Details Published on 2021-7-9 10:43

赞赏

1

查看全部赞赏

 

1370

Posts

2

Resources
2
 

uint16_t testsram[250000] __attribute__((at(0XC0000000)));

This way, specifying the address directly bypasses the linker and writes

uint16_t *testsram=(uint16_t *)0xC0000000;

It works, but you can't use sizeof().

Comments

Learned something more, thank you  Details Published on 2021-7-7 19:45
 
 
 

1942

Posts

2

Resources
3
 

Nice, very detailed!

 
 
 

7422

Posts

2

Resources
4
 

Thanks for sharing, looking forward to the follow-up!

 
Personal signature

默认摸鱼,再摸鱼。2022、9、28

 
 

2549

Posts

0

Resources
5
 
cruelfox posted on 2021-7-7 09:44 uint16_t testsram[250000] __attribute__((at(0XC0000000))); Directly specifying the address bypasses the linker and directly...

Learned something more, thank you

 
 
 

3

Posts

0

Resources
6
 

Thanks for sharing~~

 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list