0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

keil5+Env将变量定义到SDRAM中的过程

冬至子 来源:疯洋CrazySheep 作者:疯洋CrazySheep 2023-08-02 14:39 次阅读

其实要把特别大的变量(数组)定义到SDRAM中步骤很简单,但这个过程却困扰了我好久,此篇文章就作为个人学习笔记参考参考吧。

一、开启SDRAM

在Env中输入menuconfig进入菜单,找到Enable SDRAM,开启该bsp

1.jpg

可以看到在Drivers下多了一个drv_sdram.c文件

1.jpg

编译成功后可以看一下SDRAM的各项参数,在sdram_port.h文件中

1.jpg

查阅资料时,都提到如果要使用SDRAM,必须要在进入 __main 前对SDRAM进行初始化,但是RTT很人性化的直接解决了这个问题,这个BSP已经实现了初始化这一步。可以看看串口打印的数据:

1.jpg

sdram init success, mapped at 0xC0000000, size is 33554432 bytes, data width is 16
初始化已经成功,首地址、大小以及数据长度的信息都已经打印出来,所以不需要画蛇添足地再在start_up.s文件中添加SDRAM_Init函数

二、使用memheap申请和管理SDRAM空间

这一步要在Env中开启Use all of memheap objects as heap

1.jpg

1.jpg

开启后生成新工程,实际上就是开启了RT_USING_MEMHEAP_AS_HEAP

1.jpg

三、定义和使用变量

我们可以使用rt_memheap_alloc来直接申请SDRAM内的空间,直接上代码

struct rt_memheap system_heap;
#define LED0 GET_PIN(B,1)
void sdram_entry()
{
rt_uint8_t key;
rt_uint8_t i=0,led0sta=1;
rt_uint32_t ts=0,ty=0;
rt_uint16_t * testsram = RT_NULL;
testsram = rt_memheap_alloc(&system_heap, 2050*1024);
led_Init();
key_init();
//SDRAM_INIT();//RTT已经初始化了
for(ts=0;ts<800;ts++)
{
for(ty=0;ty<1280;ty++)
{
testsram[ts*ty]=ty*ts;
}
}
while(1)
{
key=key_scan(0);//不支持连按
if(key==KEY1_PRES)//打印预存测试数据
{
for(ts=0;ts<1280*800;ts++)
{
rt_kprintf("testsram[%d]:%drn",ts,testsram[ts]);//显示测试数据
ts+=200;
}
}else rt_thread_mdelay(10);
i++;
if(i==20)//DS0闪烁.
{
i=0;
led0sta=!led0sta;
rt_pin_write(LED0,led0sta);
}
}
}
#define THREAD_STACK_SIZE 440
#define THRAED_PRIORITY 20
#define THREAD_TIMESKICE 10
int sdram_sample(void)
{
rt_thread_t tid = RT_NULL;
tid = rt_thread_create("sdram_thread",sdram_entry(void*)1,THREAD_STACK_SIZE,THRAED_PRIORITY,THREAD_TIMESKICE);
if(tid!=RT_NULL)rt_thread_startup(tid);
return 0;
}
MSH_CMD_EXPORT(sdram_sample,sdram sample);
struct rt_memheap system_heap;

考虑到SDRAM初始化的问题,这一句主要是把初始化好的SDRAM空间用上,我在drv_sdram.c中将system_heap设为了外部变量

1.jpg

这样就可以在其他文件中继续使用这个初始化好的SDRAM。

接下来我主要是想定义一个16位1280*800大小的数组,是1280 乘以 800 乘以 2字节(16位为2字节)再除以1024等于2000KBytes,多算一点2050KBytes。

代码中的按键和LED相关代码可以删除,要验证的话可以直接看这三处:

rt_uint16_t * testsram = RT_NULL;
testsram = rt_memheap_alloc(&system_heap, 2050*1024);
for(ts=0;ts<800;ts++)
{
for(ty=0;ty<1280;ty++)
{
testsram[ts*ty]=ty*ts;
}
}
for(ts=0;ts<1280*800;ts++)
{
rt_kprintf("testsram[%d]:%drn",ts,testsram[ts]);//显示测试数据
ts+=200;
}

四、烧写到板子上,验证结果

在调用sdram_sample前使用命令list_memheap可以看到:

1.jpg

SDRAM初始化成功,大小和使用量都有,我们可以看到片外的 SDRAM 初始化之后我们并没有使用,但是在 max used size 字段中确显示已经使用了 48 字节的空间,这部分空间是内存堆的数据头,用于 magic、used 信息及链表节点使用。

使用sdram_sample后,可以看到打印数据:

1.jpg

由于定义的是16位,最大为65535,所以后面溢出了。

1.jpg

最后打印完毕(因为一个一个打印太慢了,所以我加了“ts+=200”的语句,跳着打印),再使用list_memheap可以看到:

1.jpg

SDRAM内的空间已经使用了一部分,而内部RAM使用量没有变。2050KBytes乘以1024=2099200字节,这就是我们申请使用的空间。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • SDRAM
    +关注

    关注

    7

    文章

    423

    浏览量

    55205
  • led灯
    +关注

    关注

    22

    文章

    1592

    浏览量

    107950
  • BSP
    BSP
    +关注

    关注

    1

    文章

    87

    浏览量

    26147
  • SDRAM控制器
    +关注

    关注

    0

    文章

    28

    浏览量

    8138
  • RTThread
    +关注

    关注

    8

    文章

    132

    浏览量

    40861
收藏 人收藏

    评论

    相关推荐

    stm32f429如何把变量定义sdram中去?

    最近搞stm32f429,请教如何把变量定义sdram中去?能够同时使用内部的sram和外部的sdram吗?
    发表于 05-15 07:54

    Keil C51变量的使用方法详解

    引言 8051内核单片机是一种通用单片机,在国内占有较大的市场份额。在C语言用于51内核单片机的研究方面,Keil公司做得最为成功。由于51内核单片机的存储结构的特殊性,Keil C51
    发表于 11-30 17:21

    keil局部变量分配地址问题

    得到的结论是两个task的a和b地址被ucos的其它变量使用了 只有a和b变量定义为sta
    发表于 01-20 12:25

    keil单片机C编程指针与变量的关系

    赋值;q=&qq;p或q的值会出问题正常,没问题(Type为一结构体)结论:情景二,是指针使用的规范过程,先分配了变量,然后指针指向变量。情景一
    发表于 07-14 08:35

    51单片机的变量的位如何定义

    51单片机的变量的位如何定义,在单片机编程使用,会涉及某些函数定义
    发表于 07-19 09:02

    RT Thread Studio如何数据定义到外部SDRAM中去?

    在LVGL为了提高LCD RGB屏幕的刷新速度,现在static lv_color_t buf_1[MY_DISP_HOR_RES * 20]; 的buf_1缓存改大,并定义
    发表于 05-20 15:20

    如何让链接器识别变量sdram定义并对其进行内存管理?

    DEADBEEF 分配给 sdram[0] 之前在 main() 内部本地声明它,编译器 barfs。如何让链接器识别变量 sdram定义
    发表于 01-04 09:04

    RT Thread Studio怎么数据定义到外部SDRAM中去呢?

    在LVGL为了提高LCD RGB屏幕的刷新速度,现在static lv_color_t buf_1[MY_DISP_HOR_RES * 20];的buf_1缓存改大,并定义
    发表于 02-22 14:27

    请问如何通过某些修改变量定义SRAM或SDRAM

    现在,我正在使用带有 SDRAM 的 imxrt1052。所有变量都在 SDRAM 。但我想要 SRAM 的一些
    发表于 05-12 08:23

    西门子PLC变量定义变量

    什么是变量变量是用于程序的,可以有不同值的变量。  根据应用范围,变量可分为以下几类 ●  局部变量:  局部
    的头像 发表于 12-23 16:25 2w次阅读
    西门子PLC<b class='flag-5'>变量</b>表<b class='flag-5'>中</b><b class='flag-5'>定义</b><b class='flag-5'>变量</b>

    IAR EWARM的一个函数拷贝Keil里后编译出错了?

    有读者问了这样一个问题:我IAR EWARM的一个函数,拷贝Keil MDK-ARM之后,编译出错了? 为什么在EWARM
    的头像 发表于 04-02 10:56 2353次阅读
    <b class='flag-5'>将</b>IAR EWARM的一个函数拷贝<b class='flag-5'>到</b><b class='flag-5'>Keil</b>里后编译出错了?

    【STM32CubeIDE】变量定义指定地址

    使用Keil在使用Keil编写程序的时候我们可以很轻松的变量定义指定地址uint8_t ar
    发表于 12-27 19:08 28次下载
    【STM32CubeIDE】<b class='flag-5'>将</b><b class='flag-5'>变量</b><b class='flag-5'>定义</b><b class='flag-5'>到</b>指定地址

    KEIL5C语言编程时可以在可执行语句之后定义变量

    以前看过有的程序在可执行变量之后定义,当时就挺纳闷,C语言不是只能在函数的可执行语句之前定义变量吗。后来偶然发现KEIL5
    发表于 01-13 13:05 2次下载
    <b class='flag-5'>KEIL5</b><b class='flag-5'>中</b>C语言编程时可以在可执行语句之后<b class='flag-5'>定义</b><b class='flag-5'>变量</b>

    oracle sql 定义变量并赋值

    赋值可以通过使用PL/SQL语句块或使用SQL*Plus工具来实现。下面详细介绍这两种方法以及它们的具体用法。 使用PL/SQL语句块定义和赋值变量: 在Oracle SQL,PL
    的头像 发表于 12-06 10:46 2789次阅读

    Keil变量不被初始化方法

    有些时候在我们的应用过程中要求变量有连续性,或者现场保留,例如Bootloader跳转,某种原因的复位过程中我们有些关键变量不能被初始化,在不同的编译环境下有不同的设置,本文就这个操作
    的头像 发表于 08-30 11:47 647次阅读
    <b class='flag-5'>Keil</b><b class='flag-5'>中</b><b class='flag-5'>变量</b>不被初始化方法