查看: 4636|回复: 2

​【STM32F746试用】跟着小狂玩F7之试用在SDRAM执行程序

[复制链接]
  • TA的每日心情
    无聊
    2017-3-12 00:04
  • 签到天数: 62 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2016-9-13 08:58:04 | 显示全部楼层 |阅读模式
    分享到:
        鉴于F7那么强大的功能,如果没有一个充足的内存空间,再多的外设也会受到执行空间的限制,当然一般的程序,这个还真是不需要考虑,但是你要是想跑个大点的系统或者想要做个炫酷的GUI,或者实现炫酷的功能,肯能内部的SRAM就不够用了,我们先看一下内部SRAM的分配,整个的SRAM 共分为4个部分,但是用户可用的只有3个部分,ITCM RAM为指令存储区,只能被CPU访问,字节大小为4kb,系统SRAM总计有320KB,SRAM1的起始地址为0x2001000总共字节大小为240KB可以直接被所有的AHB总线存取,SRAM2的起始地址为0x2004C000总字节大小为16KB可以直接被所有的AHB总线存取. DTCM-RAM起始地址为0x20000000总字节大小为64KB可以直接被所有的AHB总线存取但是通过一种特殊的AHB从总线。其实用大白话来说DTCM-RAM和ITCM-RAM的存储速度更快,就是内部的高速缓冲区,可以直接开启的。这么算来供我们实际使用的RAM为256KB字节,256说大不大,说小不小,曾经做了一个项目用的是M4的核内部也是256KB的内存,后来实现一个功能的时候就是由于SRAM的空间不够伤透了脑筋,要是能使用SDRAM那可是如虎添翼啊。今天的帖子要做的事情就是让我们的程序在SDRAM上运行。在这里想说明一下,其实SDRAM和SRAM的区别呢没有特别大的地方,在小狂的认知中,SRAM的速度比SDRAM的速度要快,但是由于技术的限制,SRAM做不大,大的SRAM的价格也是相当昂贵,总的来说性价比不高,就是你会发现一个芯片内部的SRAM总不会超过1M的,SDRAM虽然说速度慢点,但是性价比还是比较高的。当然有好多前辈们在F4上实现了,小狂这里也是参考修改,加上自己的理解,如果有不对的地方,还请指正,谢谢。



        在这里我们先分析一下F7对SDRAM的支持。内部存在两个SDRAM的控制器,每一个有13位行地址,11位列地址,4个块,每一个控制器最大支持256MB。也就是说两块最大支持512MB(在这里偷偷笑一下,如果是这样的话,哈哈,那岂不是玩啥都不是问题了,哈哈,我都有想把LINUX内核移植到F7的冲动了,哈哈)

        DISCOVERY板子上有一片SDRAM,内部存储空间128Mb,也就是16MB的内存,一般的应用也是足够了,对于单片机来说,这个存储空间完全够用,妈妈再也不怕我存储空间不够了,哈哈。



        介绍也基本完事了,下面就要实现功能了,其实,实现功能很简单,在这里不得不说一下STM32的启动流程了,在初学者的世界里,大部分人都认为main函数是一个程序的开始,其实并不是这样,每一个STM32都会有一个启动文件,在这个文件里会初始化单片机的堆栈空间,定义中断变量,初始化系统时钟,最后才会进入到main函数中去执行相应的程序,这个事编译器给我们做好的事情,从单片机步入嵌入式的行列就会更加明白这个的流程,因为大部分的嵌入式是没有集成的IDE的所有的都要自己写,自己完成。要实现我们想要的功能也不难,也就几个步骤,因为我们使用的是集成的IDE keil,所有的内存分配都是在编译的时候完成的。

    • 1、在keil5中重新定义RAM的分配
    • 2、修改启动文件,在执行Main函数之前初始化SDRAM。
    • 3、重新把栈指针指向SDRAM,然后转到main函数。
        先说第一步,修改编译器的内存分配,看图


        因为我们得SDRAM挂在了Bank1上,其实地址为0xC0000000,所以我们的RAM中的起始地址也是0xC0000000,大小为16MB,换算成二进制位0x1000000,这样软件就分配好了内存空间,其次是修改启动代码,这一部分基本上都是用汇编写的,但是也都是基本的语言,看不懂可以百度搜索一下,基本上就没有啥问题,我们就是主要添加几个部分


        1和3基本上不用你来写,是自己生成的,主要是1、定义栈空间3、定义堆空间,2的目的是在SRAM中开辟一个空间用于初始化时钟和SDRAM程序


        1是初始化物理存储地址,其实是第一次调用函数的地址,我们第一次调用的函数是systeminit函数,这个位置必须是实际的物理地址,第二个按照正常的顺序来写,在手册中有顺序,千万不能写错。否则就找不到入口了,执行完向量表后,会执行RESET_HANDLER


        首先调用SystemInit程序,里边有RCC初始化程序和SDRAM初始化程序,具体可参考Stm32F746的FSC例程


        图中红线框内的就是sdram的初始化程序,具体代码就不贴了,有兴趣的可以找Stm32F746的FSC的历程,找不到的可以在下方留言,要是真有需要我会贴上来,然后声明函数


    在编译器里定义宏变量


        执行了这个函数之后,重新给定栈指针,让其指向SDRAM的内存空间


        然后执行__main函数,__main函数中会初始化堆栈空间,然后跳转到真正的main函数中


        基本上到这里,我们得程序就搭建完成了,然后让我们来测试一下,在main()函数中定义一个数组然后读取定义数组的地址,以及主函数入口的地址,我们就知道我们得程序到底执行在什么当中了。


        由打印结果来看,我们得程序已经正确在SDRAM中执行了,可以一起愉快的玩耍了,哈哈。


        到此,这一篇帖子的内容也算完成了,其实小狂在做这个的时候只用了半个小时不到,但是写帖子确实是废了不少时间,至少是做的4倍吧,小狂在这里谢谢各位看官的支持,下一篇帖子也会往更深层的走,撒花,撒花,哈哈。
    回复

    使用道具 举报

    该用户从未签到

    发表于 2022-3-18 15:57:24 | 显示全部楼层
    看不到图片啊,SDRAM初始化后也没有代码在里面啊,怎么指向他的地址就可以运行了呢?还有是怎么指向的也搞不清楚,主要是图片看不到,求指点
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /5 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-12-19 13:42 , Processed in 0.136740 second(s), 21 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.