赞
踩
这其实是今年上半年参加集创赛安路科技杯时候做的内容,当时忙着考研复习大概做了个框架参赛,没想到还混到一个分赛区二等奖加一次公费旅游,现在保研后闲着写点博客记录下当时碰上的问题。
硬件平台是硬木课堂的安路EG4S20BG256核心板,资源一般够用,在这次赛题里面移植M0加上其他外设绰绰有余;
软件平台使用安路公司的TD软件开发FPGA部分,Keil软件对M0进行编程;
具体移植过程强烈建议直接看官方教程,十分详细。配合ARM Cortex-M0 权威指南这本书,能更深入理解M0内核架构和各个部分工作原理,后面自己要添加其他外设也不至于不知道怎么去写代码。
Arm Cortex-M0的SoC实现
在 Anlogic 的 EG4S20 系列 FPGA 中,总共有两类 Memory 资源,分别是 Block Memory 与 Distributed Memory。EG4S20BG256芯
片的存储部分包含了:
按照官方教程进行移植的时候,分配的RAM、ROM空间都较小(4096*32bit)。但是如果直接在Block_RAM.v代码中对空间大小进行修改, TD软件可能会在综合编译时会报错。这是因为由于此次使用的 FPGA 内部存储器的单个空间较小,TD软件无法自动生成这么大的BRAM资源块。
解决方法大致有:
FPGA 内部 BRAM 资源分为 9Kbits、32Kbits 两种,其中 32Kbits 可具体设置为 2K * 16 或 4K * 8 两种模式。由于 M0 内核使用的数据位宽最长为 32bits,且需要支持 8bits、16bits、24bits、32bits 四种变长数据宽度传输(可以看上面那本书),所以设定的具体 ROM、RAM 扩展方案如下:
使用以上方案分别构建 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硬件后,在下图的地方依葫芦画瓢添加自己的中断名称即可:
软硬件都经过仿真验证没问题后,先通过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文件即可;
还有啥问题暂时想不起来了,想起来再写。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。