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

    文章

    409

    浏览量

    54732
  • led灯
    +关注

    关注

    22

    文章

    1554

    浏览量

    107032
  • BSP
    BSP
    +关注

    关注

    1

    文章

    83

    浏览量

    25745
  • SDRAM控制器
    +关注

    关注

    0

    文章

    28

    浏览量

    8075
  • RTThread
    +关注

    关注

    7

    文章

    129

    浏览量

    40519
收藏 人收藏

    评论

    相关推荐

    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

    S3C2410启动代码从ADSv1.2移植KEIL For ARM uV4的方法

    KEIL编译器字节对齐。 4. ADSv1.2里面的RO、RW、ZI基地址和大小定义的系统变量,修改为KEIL
    发表于 07-05 03:53

    请问怎样变量定义在ram

    怎样变量定义在ram?编译器手册给了关键字“_RAM_BASE”,但是不知道怎么用, 编译器手册
    发表于 07-23 03:52

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

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

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

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

    ARM单片函数定义指定程序地址的方法

    在单片机编程使用,会涉及某些函数定义指定的code区。此时需要对工程文件进行配置修改才可完成。本期针对ARM平台单片机做出说明介绍1
    发表于 12-13 06:20

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

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

    Env工具到底是什么?怎样去使用Env工具呢

    时的显示文字,不错不错,挺好menuconfig 命令同样好使scons 编译成功那么,我们可以去看看 CmdInit.cmd 到底做了什么,其实他就是配置了一些环境变量一些 env
    发表于 06-24 11:31

    如何让链接器识别变量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

    如何在LA1224RDB启用uboot.env

    0x2000 # VFAT 示例 /uboot.env 0x0000 0x4000 我的问题是,当我尝试 u-boot 环境变量存储在名为 uboot.env 的文件
    发表于 05-06 07:02

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

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

    如何在Keil中将函数或变量编译指定地址

    如何在Keil中将函数或变量编译指定地址在Keil 中将函数或变量编译指定地址
    发表于 10-19 06:51

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

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