jjzjj

基于安路FPGA的Cortex M0移植【FPGA】

aqua_cat 2023-09-29 原文

基于安路FPGA的Cortex M0移植

这其实是今年上半年参加集创赛安路科技杯时候做的内容,当时忙着考研复习大概做了个框架参赛,没想到还混到一个分赛区二等奖加一次公费旅游,现在保研后闲着写点博客记录下当时碰上的问题。

软硬件介绍


硬件平台是硬木课堂的安路EG4S20BG256核心板,资源一般够用,在这次赛题里面移植M0加上其他外设绰绰有余;
软件平台使用安路公司的TD软件开发FPGA部分,Keil软件对M0进行编程;

具体移植过程

具体移植过程强烈建议直接看官方教程,十分详细。配合ARM Cortex-M0 权威指南这本书,能更深入理解M0内核架构和各个部分工作原理,后面自己要添加其他外设也不至于不知道怎么去写代码。
Arm Cortex-M0的SoC实现

移植过程中碰上的问题

RAM和ROM资源不足

在 Anlogic 的 EG4S20 系列 FPGA 中,总共有两类 Memory 资源,分别是 Block Memory 与 Distributed Memory。EG4S20BG256芯
片的存储部分包含了:

  1. 156 Kbits 分布存储器(Distribute RAM)
  2. 1 Mbits 嵌入块存储器(Block RAM 简称 BRAM)包括:
    • 64 个 9 Kbits BRAM,可配置为真双口,8Kx1 到 512x18 模式
    • 16 个 32 Kbits BRAM,可配置为真双口,可设置为 2Kx16 或 4Kx8

按照官方教程进行移植的时候,分配的RAM、ROM空间都较小(4096*32bit)。但是如果直接在Block_RAM.v代码中对空间大小进行修改, TD软件可能会在综合编译时会报错。这是因为由于此次使用的 FPGA 内部存储器的单个空间较小,TD软件无法自动生成这么大的BRAM资源块。
解决方法大致有:

  1. 在TD软件中使用IP核生成大小合适的整块BRAM资源;
  2. 先生成小块BRAM块,再使用数据线扩展或者地址线扩展的方法进行扩展。

FPGA 内部 BRAM 资源分为 9Kbits、32Kbits 两种,其中 32Kbits 可具体设置为 2K * 16 或 4K * 8 两种模式。由于 M0 内核使用的数据位宽最长为 32bits,且需要支持 8bits、16bits、24bits、32bits 四种变长数据宽度传输(可以看上面那本书),所以设定的具体 ROM、RAM 扩展方案如下:

  1. 使用 32Kbits BRAM 资源块分别生成 4 个 8K*8 配置模式的内存资源模块,每个模块将使用两个 32Kbits BRAM 资源块;
  2. 以上 4 个模块进行数据位扩展,组成一个 8K*32 的内存资源模块,即 32KB 的内存空间;
  3. 该内存空间深度为 8192,数据位宽为 8K,因为是由 4 个分别的小模块组合而来,还可以支持变长数据宽度传输;

使用以上方案分别构建 ROM、RAM 模块,共使用了 16 个 32Kbits BRAM 资源块,得到的 ROM、RAM 空间大小都为 32KB。

启动文件编写

启动文件这一部分,一开始我是直接抄的教程的代码,能用,但是不是很理解。等到后面引入了中断后,就更加不理解了,感觉写起来很乱。于是突发奇想,去找到STM32某个同样也是M0内核的型号单片机,抄了一份启动文件,按照自己的硬件进行修改后,验证同样能用。
代码如下:

;/**************************************************************************//**
; * @file     startup_CMSDK_CM0.s
; * @brief    CMSIS Cortex-M0 Core Device Startup File for
; *           Device CMSDK_CM0
; * @version  V3.01
; * @date     06. March 2012
; *
; * @note
; * Copyright (C) 2012 ARM Limited. All rights reserved.
; *
; * @par
; * ARM Limited (ARM) is supplying this software for use with Cortex-M
; * processor based microcontrollers.  This file can be freely distributed
; * within development tools that are supporting such ARM based processors.
; *
; * @par
; * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
; *
; ******************************************************************************/
;/*
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
;*/


; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Stack_Size      EQU     0x00000400

                AREA    STACK, NOINIT, READWRITE, ALIGN=4
Stack_Mem       SPACE   Stack_Size
__initial_sp


; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000400

                AREA    HEAP, NOINIT, READWRITE, ALIGN=4
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit


                PRESERVE8
                THUMB


; Vector Table Mapped to Address 0 at Reset

                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler			      ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     SVC_Handler	              ; SVCall Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     PendSV_Handler       	  ; PendSV Handler
                DCD     SysTick_Handler        	  ; SysTick Handler
                DCD     UART0_Handler             ; UART_Handler
                DCD     SW_Handler                ; SW_Handler
				DCD     KEY_Handler               ; KEY_Handler
                DCD     ESP_Handler               ; ESP_Handler
__Vectors_End

__Vectors_Size  EQU     __Vectors_End - __Vectors

                AREA    |.text|, CODE, READONLY



; Reset Handler

Reset_Handler   PROC
                GLOBAL  Reset_Handler
				ENTRY
                IMPORT  __main
                LDR     R0, =__main
				MOV     R8, R0
                MOV     R9, R8
                BX      R0
                ENDP
 
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler     PROC
                EXPORT  NMI_Handler               [WEAK]
                B       .
                ENDP
HardFault_Handler\
                PROC
                EXPORT  HardFault_Handler         [WEAK]
                B       .
                ENDP
SVC_Handler     PROC
                EXPORT  SVC_Handler               [WEAK]
                B       .
                ENDP
PendSV_Handler  PROC
                EXPORT  PendSV_Handler            [WEAK]
                B       .
                ENDP
SysTick_Handler PROC
                EXPORT  SysTick_Handler           [WEAK]
                B       .
                ENDP

Default_Handler PROC
				EXPORT  UART0_Handler             [WEAK]
				EXPORT  SW_Handler                [WEAK]
				EXPORT  KEY_Handler               [WEAK]
				EXPORT  ESP_Handler               [WEAK]
UART0_Handler
SW_Handler
KEY_Handler
ESP_Handler
                B       .
                ENDP


                ALIGN


; User Initial Stack & Heap

				IF      :DEF:__MICROLIB

                EXPORT  __initial_sp
                EXPORT  __heap_base
                EXPORT  __heap_limit

                ELSE

                IMPORT  __use_two_region_memory
                EXPORT  __user_initial_stackheap

__user_initial_stackheap 

                LDR     R0, =  Heap_Mem
                LDR     R1, =(Stack_Mem + Stack_Size)
                LDR     R2, = (Heap_Mem +  Heap_Size)
                LDR     R3, = Stack_Mem
                BX      LR
     
                ALIGN 

				ENDIF
					
                END

如果需要新增中断,只需要更改完FPGA硬件后,在下图的地方依葫芦画瓢添加自己的中断名称即可:


KEIL下载算法编写

软硬件都经过仿真验证没问题后,先通过TD软件将FPGA比特流下载到FPGA芯片内,再使用KEIL软件将软核代码下载到M0内核内,整个系统才能正常运作。这个过程中需要一个KEIL下载算法,路径:\KEIL\ARM\Flash\。
1、首先将该文件夹下的例程文件夹复制一份,改成需要的名称;

2、根据自己的硬件flash大小,更改FlashDev.c文件;

struct FlashDevice const FlashDevice  =  {
   FLASH_DRV_VERS,             // Driver Version, do not modify!
   "CM0_SoC",                  // Device Name 
   ONCHIP,                     // Device Type
   0x00000000,                 // Device Start Address
   0x00008000,                 // Device Size in Bytes (32kB)
   1024,                       // Programming Page Size
   0,                          // Reserved, must be 0
   0xFF,                       // Initial Content of Erased Memory
   100,                        // Program Page Timeout 100 mSec
   3000,                       // Erase Sector Timeout 3000 mSec

// Specify Size and Address of Sectors
   0x008000, 0x000000,         // Sector Size  32kB (1 Sectors)
   SECTOR_END
};

3、编写FlashPrg.c文件中的几个函数;

/**************************************************************************//**
 * @file     FlashPrg.c
 * @brief    Flash Programming Functions adapted for New Device Flash
 * @version  V1.0.0
 * @date     10. January 2018
 ******************************************************************************/
/*
 * Copyright (c) 2010-2018 Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the License); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
#include "..\FlashOS.H"        // FlashOS Structures
#include "string.h"

/* 
   Mandatory Flash Programming Functions (Called by FlashOS):
                int Init        (unsigned long adr,   // Initialize Flash
                                 unsigned long clk,
                                 unsigned long fnc);
                int UnInit      (unsigned long fnc);  // De-initialize Flash
                int EraseSector (unsigned long adr);  // Erase Sector Function
                int ProgramPage (unsigned long adr,   // Program Page Function
                                 unsigned long sz,
                                 unsigned char *buf);

   Optional  Flash Programming Functions (Called by FlashOS):
                int BlankCheck  (unsigned long adr,   // Blank Check
                                 unsigned long sz,
                                 unsigned char pat);
                int EraseChip   (void);               // Erase complete Device
      unsigned long Verify      (unsigned long adr,   // Verify Function
                                 unsigned long sz,
                                 unsigned char *buf);

       - BlanckCheck  is necessary if Flash space is not mapped into CPU memory space
       - Verify       is necessary if Flash space is not mapped into CPU memory space
       - if EraseChip is not provided than EraseSector for all sectors is called
*/


/*
 *  Initialize Flash Programming Functions
 *    Parameter:      adr:  Device Base Address
 *                    clk:  Clock Frequency (Hz)
 *                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
 *    Return Value:   0 - OK,  1 - Failed
 */

int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {

  /* Add your Code */
  return (0);                                  // Finished without Errors
}


/*
 *  De-Initialize Flash Programming Functions
 *    Parameter:      fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
 *    Return Value:   0 - OK,  1 - Failed
 */

int UnInit (unsigned long fnc) {

  /* Add your Code */
  return (0);                                  // Finished without Errors
}


/*
 *  Erase complete Flash Memory
 *    Return Value:   0 - OK,  1 - Failed
 */

int EraseChip (void) {

  /* Add your Code */
	memset((unsigned char *)0, 0, 0x8000);
  return (0);                                  // Finished without Errors
}


/*
 *  Erase Sector in Flash Memory
 *    Parameter:      adr:  Sector Address
 *    Return Value:   0 - OK,  1 - Failed
 */

int EraseSector (unsigned long adr) {

  /* Add your Code */
	memset((unsigned char *)adr, 0, 1024);
  return (0);                                  // Finished without Errors
}


/*
 *  Program Page in Flash Memory
 *    Parameter:      adr:  Page Start Address
 *                    sz:   Page Size
 *                    buf:  Page Data
 *    Return Value:   0 - OK,  1 - Failed
 */

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {

  /* Add your Code */
	memcpy((unsigned char *)adr, buf, sz);
  return (0);                                  // Finished without Errors
}

4、然后执行编译,会在文件夹下生成一个.FLM文件;

改一个名字,然后复制到\KEIL\ARM\Flash\路径下;

5、然后在工程下载器设置中,添加相应的FLM文件即可;

其他

还有啥问题暂时想不起来了,想起来再写。

有关基于安路FPGA的Cortex M0移植【FPGA】的更多相关文章

  1. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  2. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  3. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  4. ruby-on-rails - (Ruby,Rails) 基于角色的身份验证和用户管理...? - 2

    我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源

  5. ruby-on-rails - 可移植 Ruby on Rails 环境 - 2

    我给自己买了一个新的8gigUSBkey,我正在寻找一个合适的解决方案来拥有一个可移植RoR环境来学习。我在谷歌上搜索了一下,发现了一些可能性,但我很想听听一些现实生活中的经历和意见。谢谢! 最佳答案 我喜欢InstantRails,非常容易使用,无需安装程序,也不会修改您的系统环境。 关于ruby-on-rails-可移植RubyonRails环境,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/q

  6. ruby - 在 Rakefile 中动态生成 Rake 测试任务(基于现有的测试文件) - 2

    我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n

  7. ruby - 如何使用 Ruby 基于字母数字字符串生成颜色? - 2

    我想要像“嘿那里”这样的东西变成,例如,#316583。我希望将任意长度的字符串“归结”为十六进制颜色。我不知道从哪里开始。我在想,每个字符串的MD5散列都是不同的-但如何将该散列转换为十六进制颜色数字? 最佳答案 你可以只取几位前几位:require'digest/md5'color=Digest::MD5.hexdigest('Mytext')[0..5] 关于ruby-如何使用Ruby基于字母数字字符串生成颜色?,我们在StackOverflow上找到一个类似的问题:

  8. 【自动驾驶环境感知项目】——基于Paddle3D的点云障碍物检测 - 2

    文章目录1.自动驾驶实战:基于Paddle3D的点云障碍物检测1.1环境信息1.2准备点云数据1.3安装Paddle3D1.4模型训练1.5模型评估1.6模型导出1.7模型部署效果附录show_lidar_pred_on_image.py1.自动驾驶实战:基于Paddle3D的点云障碍物检测项目地址——自动驾驶实战:基于Paddle3D的点云障碍物检测课程地址——自动驾驶感知系统揭秘1.1环境信息硬件信息CPU:2核AI加速卡:v100总显存:16GB总内存:16GB总硬盘:100GB环境配置Python:3.7.4框架信息框架版本:PaddlePaddle2.4.0(项目默认框架版本为2.3

  9. ruby - 规范测试基于 EventMachine 的(Reactor)代码 - 2

    我正在尝试整个BDD方法并想测试AMQP基于Vanilla的方面Ruby我正在写的应用程序。选择Minitest后作为与其他名副其实的蔬菜框架不同的平衡功能和表现力的测试框架,我着手编写此规范:#File./test/specs/services/my_service_spec.rb#Requirementsfortestrunningandconfigurationrequire"minitest/autorun"require"./test/specs/spec_helper"#Externalrequires#MinitestSpecsforEventMachinerequire

  10. ruby - JSON的基于流的解析和写入 - 2

    我分1,000个批处理从服务器获取大约20,000个数据集。每个数据集都是一个JSON对象。坚持这会产生大约350MB的未压缩明文。我的内存限制为1GB。因此,我以追加模式将每1,000个JSON对象作为一个数组写入到一个原始JSON文件中。结果是一个包含20个需要聚合的JSON数组的文件。无论如何我都需要触摸它们,因为我想添加元数据。一般RubyYajlParser使这成为可能:raw_file=File.new(path_to_raw_file,'r')json_file=File.new(path_to_json_file,'w')datasets=[]parser=Yajl::

随机推荐