完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
先使用片外 RAM 的读写测试一下片外 RAM 是不是配置正确了,确认正确了之后再分配内存试一下
|
|
|
|
我用安富莱的SDRAM测试代码测试了一下没问题: 可能是由于屏幕的原因,之前一直测试不成功,很奇怪,把LCD注释掉测试就通过了。 但是我用rt_memheap_alloc();依然报错。 这是我调用动态内存分配的代码 //测试IPC通信 static int sram_test(void) { int i = 0; char *ptr_t; for(i=0; i<5; i++) { ptr_t = rt_memheap_alloc(&sdram_heap, 1024); if(ptr_t != RT_NULL) rt_kprintf("ptr_t: %p", ptr_t); } return RT_EOK; } void IPCR_thread_entry(void* parameter) { // uint32_t *ppr =NULL; // ppr = (uint32_t*)(RAM_HEAP_EX_START); // for(int i = 0;i<1024;i++) // { // *ppr = i; // // LOG_D("ppr: %p->%d", ppr,*ppr); // ppr++; // } #ifdef SU if (bsp_TestExtSRAM() == 0) { rt_kprintf("SRAM Test successrn"); } else { rt_kprintf("SRAM Test failrn"); } #endif sram_test(); while(1) { rt_thread_mdelay(200); } } 安富莱的测试SDRAM代码: ********************************************************************************************************* * 函 数 名: bsp_TestExtSRAM * 功能说明: 扫描测试外部SRAM的全部单元。 * 形 参: 无 * 返 回 值: 0 表示测试通过; 大于0表示错误单元的个数。 ********************************************************************************************************* */ uint32_t bsp_TestExtSRAM(void) { uint32_t i; uint32_t *pSRAM; uint8_t *pBytes; uint32_t err; const uint8_t ByteBuf[4] = {0x55, 0xA5, 0x5A, 0xAA}; /* 写SRAM */ pSRAM = (uint32_t *)RAM_HEAP_EX_START; for (i = 0; i < RAM_HEAP_EX_SIZE / 4; i++) { *pSRAM = i; pSRAM++; } /* 读SRAM */ err = 0; pSRAM = (uint32_t *)RAM_HEAP_EX_START; for (i = 0; i < RAM_HEAP_EX_SIZE / 4; i++) { if (*pSRAM++ != i) { err++; } } rt_kprintf("SDRAM check round 1 error = %dn", err); if (err > 0) { return (4 * err); } #if 1 /* 对SRAM 的数据求反并写入 */ pSRAM = (uint32_t *)RAM_HEAP_EX_START; for (i = 0; i < RAM_HEAP_EX_SIZE/4; i++) { *pSRAM = ~*pSRAM; pSRAM++; } /* 再次比较SRAM的数据 */ err = 0; pSRAM = (uint32_t *)RAM_HEAP_EX_START; for (i = 0; i if (*pSRAM++ != (~i)) { err++; } } rt_kprintf("SDRAM check round 2 error = %dn", err); if (err>0) { return (4 * err); } #endif /* 测试按字节方式访问, 目的是验证 FSMC_NBL0 、 FSMC_NBL1 口线 */ pBytes = (uint8_t *)RAM_HEAP_EX_START; for (i = 0; i < sizeof(ByteBuf); i++) { *pBytes++ = ByteBuf; } /* 比较SRAM的数据 */ err = 0; pBytes = (uint8_t *)RAM_HEAP_EX_START; for (i = 0; i < sizeof(ByteBuf); i++) { if (*pBytes++ != ByteBuf) { err++; } } rt_kprintf("SDRAM check round 3 error = %dn", err); if (err > 0) { return err; } return 0; } |
|
|
|
大佬我现在用rt_alloc();分配成功了 我有几点疑惑:这算是已经把内部SRAM写满了,才到外部,这样应该不会影响其他线程的内存分配吧? 怎么样只用外部SRAM,之前看你的贴子是用rt_memheap_alloc(),但是我的不知道为什么不成功。 如果线程用了外部SRAM效率应该会低吧? |
|
|
|
是不会影响其他线程的分配的。用 rt_malloc 的時候按照源码的逻辑会优先分配内部的 RAM,等到内部的 RAM 分配完了就会分配外部的 RAM。 void *rt_malloc(rt_size_t size) { void *ptr; /* try to allocate in system heap */ ptr = rt_memheap_alloc(&_heap, size); // 首先从内部 RAM 申请空间 #ifdef RT_USING_MEMHEAP_AUTO_BINDING if (ptr == RT_NULL) // 内部 RAM 申请失败 { struct rt_object *object; struct rt_list_node *node; struct rt_memheap *heap; struct rt_object_information *information; /* try to allocate on other memory heap */ information = rt_object_get_information(RT_Object_Class_MemHeap); RT_ASSERT(information != RT_NULL); for (node = information->object_list.next; node != &(information->object_list); node = node->next) { object = rt_list_entry(node, struct rt_object, list); // 从 memheap_item 链表中找其他堆空间,对于本问题就是定义的外部 RAM heap = (struct rt_memheap *)object; RT_ASSERT(heap); RT_ASSERT(rt_object_get_type(&heap->parent) == RT_Object_Class_MemHeap); /* not allocate in the default system heap */ if (heap == &_heap) continue; ptr = rt_memheap_alloc(heap, size); // 从其他堆空间申请内存(也就是外部RAM) if (ptr != RT_NULL) break; } } #endif /* RT_USING_MEMHEAP_AUTO_BINDING */ ... ... // 省略掉无关代码 } 从上面的源码可以看出来 rt_malloc 首先从 _heap 里面分配内存,而 _heap 就是内部的定义的内部的 RAM,相关的代码如下。上面的代码如果呢不空间申请失败,会从 memheap_item 链表中寻找其他的堆空间,然后在其他的堆空间(外部RAM)上申请内存。 // rt-thread/src/memheap.c static struct rt_memheap _heap; // 全局变量_heap,包含了的是内部 RAM 的起始地址和大小 void rt_system_heap_init(void *begin_addr, void *end_addr) { RT_ASSERT((rt_uint32_t)end_addr > (rt_uint32_t)begin_addr); /* initialize a default heap in the system */ rt_memheap_init(&_heap, "heap", begin_addr, // 起始地址 (rt_uint32_t)end_addr - (rt_uint32_t)begin_addr); // 大小 } |
|
|
|
一般都是先使用内部的 RAM,因为内部的 RAM 速度比较快,内部 RAM 分配完了再分配外部的,如果是定义的 LCD 的显存空间比较大,就可以直接把这部分空间定义在外部的 RAM 上面。
另外一个问题直接使用外部 RAM 的方法,根据 rt_malloc 的源码,里面实际是调用了 void *rt_memheap_alloc(struct rt_memheap *heap, rt_size_t size),所以直接使用 rt_memheap_alloc() 第一个参数传入你定义的外部 RAM 的对空间的结构体指针就可以直接用外部 RAM 了,这个结构体变量需要先调用 rt_memheap_init() 进行初始化,如下所示。 rt_memheap_init(&sram_heap, "sram_heap", (void *) SRAM_BANK_ADDR, SRAM_SIZE); |
|
|
|
我看你的代码有一个这个函数 bsp_TestExtSRAM() 不知道你这个函数是怎么实现的,是不是从外部 RAM 的起始位置进行了读写测试。需要注意的是你在进行外部 RAM 的读写测试的时候不能对外部 RAM 最开始的那部分空间进行写操作,因为使用 rt_memheap_alloc() 进行初始化之后在外部的 RAM 最前面的部分定义了一些东西,比如说幻数这些,我猜想这些东西为了表征外部 RAM 的参数,具体的也没仔细分析,这也和你使用 rt_memheap_alloc() 进行初始化之后 list_memheap 发现外部 RAM 已经使用了 48 字节吻合,代码如下。你把最开始的位置的内容修改了就会导致分配失败。
rt_err_t rt_memheap_init(struct rt_memheap *memheap, const char *name, void *start_addr, rt_size_t size) { ... ... // 省略 /* initialize the free list header */ item = &(memheap->free_header); item->magic = (RT_MEMHEAP_MAGIC | RT_MEMHEAP_FREED); item->pool_ptr = memheap; item->next = RT_NULL; item->prev = RT_NULL; item->next_free = item; item->prev_free = item; ... ... // 省略 } |
|
|
|
谢谢大佬的分析,我根据你写的,看了系统分配内存的源码,发现我原来是传了空参进去,没有传初始化后的结构体。现在好了。十分感谢。
|
|
|
|
补充一下和总结一下
在外部SRAM上使用动态内存分配的时候,有个前提就是外部SRAM初始化成功,并且单独测试SRAM写入没有问题。 struct rt_memheap ex_ram_heap; static SRAM_HandleTypeDef SRAM_Handler; static FMC_NORSRAM_TimingTypeDef Timing; int DRV_EX_SRAM_Register(void) { //注册内存堆到内存堆管理 rt_memheap_init(&ex_ram_heap,”SRAM EX”,(void*)RAM_HEAP_EX_START,RAM_HEAP_EX_SIZE); return 0; } ptr_t = rt_memheap_alloc(&ex_ram_heap, 1024);//这里的参数是注册过的结构体 这个错误挺蠢的 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
764 浏览 0 评论
3847 浏览 0 评论
如何使用python调起UDE STK5.2进行下载自动化下载呢?
2479 浏览 0 评论
开启全新AI时代 智能嵌入式系统快速发展——“第六届国产嵌入式操作系统技术与产业发展论坛”圆满结束
2901 浏览 0 评论
获奖公布!2024 RT-Thread全球巡回线下培训火热来袭!报名提问有奖!
31185 浏览 11 评论
72793 浏览 21 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-20 00:38 , Processed in 0.707993 second(s), Total 87, Slave 69 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号