sw_apps: FreeRTOS support included for RPC demo
Signed-off-by: Kinjal Pravinbhai Patel <patelki@xilinx.com> Acked-by: Anirudha Sarangi <anirudh@xilinx.com>
This commit is contained in:
parent
b5d70fa084
commit
03ea09348d
7 changed files with 527 additions and 70 deletions
|
@ -46,8 +46,8 @@ proc check_standalone_os {} {
|
||||||
}
|
}
|
||||||
set os [lindex $oslist 0];
|
set os [lindex $oslist 0];
|
||||||
|
|
||||||
if { $os != "standalone" } {
|
if { ( $os != "standalone" ) && ( $os != "freertos821_xilinx" ) } {
|
||||||
error "This application is supported only on the Standalone Board Support Package.";
|
error "This application is supported only on the Standalone Board Support Package and freertos821.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,21 @@ proc check_stdout_hw {} {
|
||||||
}
|
}
|
||||||
|
|
||||||
proc swapp_generate {} {
|
proc swapp_generate {} {
|
||||||
return;
|
set oslist [get_os];
|
||||||
|
if { [llength $oslist] != 1 } {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
set os [lindex $oslist 0];
|
||||||
|
if { $os != "standalone" } {
|
||||||
|
set ld_file "lscript.ld"
|
||||||
|
set ld_file_new "lscript_freertos.ld"
|
||||||
|
file rename -force $ld_file_new $ld_file
|
||||||
|
file delete -force $ld_file_new
|
||||||
|
} else {
|
||||||
|
set ld_file "lscript_freertos.ld"
|
||||||
|
file delete -force $ld_file
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc swapp_get_linker_constraints {} {
|
proc swapp_get_linker_constraints {} {
|
||||||
|
@ -104,5 +118,5 @@ proc swapp_get_supported_processors {} {
|
||||||
}
|
}
|
||||||
|
|
||||||
proc swapp_get_supported_os {} {
|
proc swapp_get_supported_os {} {
|
||||||
return "standalone";
|
return "freertos821_xilinx standalone";
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,21 +30,25 @@
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "xparameters.h"
|
|
||||||
#include "xil_exception.h"
|
#include "xil_exception.h"
|
||||||
#include "xscugic.h"
|
#include "xscugic.h"
|
||||||
#include "xil_cache.h"
|
|
||||||
#include "xil_mpu.h"
|
#include "xil_mpu.h"
|
||||||
#include "baremetal.h"
|
#include "baremetal.h"
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
|
#include "platform.h"
|
||||||
XScuGic InterruptController;
|
#ifdef USE_FREERTOS
|
||||||
|
extern XScuGic xInterruptController;
|
||||||
|
#else
|
||||||
|
XScuGic xInterruptController;
|
||||||
|
#endif
|
||||||
|
extern struct isr_info isr_table[ISR_COUNT];
|
||||||
|
extern struct XOpenAMPInstPtr OpenAMPInstPtr;
|
||||||
|
unsigned int xInsideISR;
|
||||||
|
|
||||||
int zynqMP_r5_gic_initialize() {
|
int zynqMP_r5_gic_initialize() {
|
||||||
|
#ifndef USE_FREERTOS
|
||||||
u32 Status;
|
u32 Status;
|
||||||
|
|
||||||
Xil_ExceptionDisable();
|
|
||||||
|
|
||||||
XScuGic_Config *IntcConfig; /* The configuration parameters of the interrupt controller */
|
XScuGic_Config *IntcConfig; /* The configuration parameters of the interrupt controller */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -55,7 +59,7 @@ int zynqMP_r5_gic_initialize() {
|
||||||
return XST_FAILURE;
|
return XST_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = XScuGic_CfgInitialize(&InterruptController, IntcConfig,
|
Status = XScuGic_CfgInitialize(&xInterruptController, IntcConfig,
|
||||||
IntcConfig->CpuBaseAddress);
|
IntcConfig->CpuBaseAddress);
|
||||||
if (Status != XST_SUCCESS) {
|
if (Status != XST_SUCCESS) {
|
||||||
return XST_FAILURE;
|
return XST_FAILURE;
|
||||||
|
@ -66,26 +70,58 @@ int zynqMP_r5_gic_initialize() {
|
||||||
* logic in the ARM processor.
|
* logic in the ARM processor.
|
||||||
*/
|
*/
|
||||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
|
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
|
||||||
(Xil_ExceptionHandler) zynqMP_r5_irq_isr,
|
(Xil_ExceptionHandler)XScuGic_InterruptHandler,&xInterruptController);
|
||||||
&InterruptController);
|
|
||||||
|
|
||||||
Xil_ExceptionEnable();
|
Xil_ExceptionEnable();
|
||||||
|
#endif
|
||||||
|
OpenAMPInstPtr.IntrID = VRING1_IPI_INTR_VECT;
|
||||||
|
XScuGic_Connect(&xInterruptController, VRING1_IPI_INTR_VECT,
|
||||||
|
(Xil_ExceptionHandler)zynqMP_r5_irq_isr,
|
||||||
|
&OpenAMPInstPtr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void bm_env_isr(int vector);
|
|
||||||
|
|
||||||
void zynqMP_r5_irq_isr() {
|
void zynqMP_r5_irq_isr(void *OpenAMPInst) {
|
||||||
|
|
||||||
unsigned int raw_irq;
|
struct XOpenAMPInstPtr *OpenAMPInstance;
|
||||||
int irq_vector;
|
int idx;
|
||||||
raw_irq = (unsigned int)XScuGic_CPUReadReg(&InterruptController,XSCUGIC_INT_ACK_OFFSET);
|
struct isr_info *info;
|
||||||
irq_vector = (int) (raw_irq & XSCUGIC_ACK_INTID_MASK);
|
OpenAMPInstance = (struct XOpenAMPInstPtr *)OpenAMPInst;
|
||||||
|
xInsideISR=1;
|
||||||
|
|
||||||
bm_env_isr(irq_vector);
|
for(idx = 0; idx < ISR_COUNT; idx++)
|
||||||
|
{
|
||||||
|
info = &isr_table[idx];
|
||||||
|
if(info->vector == OpenAMPInstance->IntrID)
|
||||||
|
{
|
||||||
|
unsigned long ipi_base_addr = *((unsigned long *)info->data);
|
||||||
|
OpenAMPInstance->IPI_Status = (unsigned int)Xil_In32(ipi_base_addr + IPI_ISR_OFFSET);
|
||||||
|
Xil_Out32((ipi_base_addr + IPI_ISR_OFFSET), OpenAMPInstance->IPI_Status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef USE_FREERTOS
|
||||||
|
env_release_sync_lock(OpenAMPInstance->lock);
|
||||||
|
#else
|
||||||
|
process_communication(*OpenAMPInstance);
|
||||||
|
#endif
|
||||||
|
xInsideISR=0;
|
||||||
|
}
|
||||||
|
|
||||||
XScuGic_CPUWriteReg(&InterruptController,XSCUGIC_EOI_OFFSET, raw_irq);
|
void process_communication(struct XOpenAMPInstPtr OpenAMPInstance) {
|
||||||
|
int idx;
|
||||||
|
struct isr_info *info;
|
||||||
|
|
||||||
|
for(idx = 0; idx < ISR_COUNT; idx++)
|
||||||
|
{
|
||||||
|
info = &isr_table[idx];
|
||||||
|
if(info->vector == OpenAMPInstance.IntrID)
|
||||||
|
{
|
||||||
|
info->isr(info->vector , info->data, OpenAMPInstance.IPI_Status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -160,9 +196,8 @@ void ipi_unregister_handler(unsigned long ipi_base_addr, unsigned int intr_mask)
|
||||||
memset(&(ipi_handler_table[ipi_hd_i]), 0, sizeof(struct ipi_handler_info));
|
memset(&(ipi_handler_table[ipi_hd_i]), 0, sizeof(struct ipi_handler_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ipi_isr(int vect_id, void *data, unsigned int intr_status) {
|
void ipi_isr(int vect_id, void *data, unsigned int ipi_intr_status) {
|
||||||
unsigned long ipi_base_addr = *((unsigned long *)data);
|
unsigned long ipi_base_addr = *((unsigned long *)data);
|
||||||
unsigned int ipi_intr_status = (unsigned int)Xil_In32(ipi_base_addr + IPI_ISR_OFFSET);
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
do {
|
do {
|
||||||
Xil_Out32((ipi_base_addr + IPI_ISR_OFFSET), ipi_intr_status);
|
Xil_Out32((ipi_base_addr + IPI_ISR_OFFSET), ipi_intr_status);
|
||||||
|
@ -236,12 +271,18 @@ unsigned int old_value = 0;
|
||||||
|
|
||||||
void restore_global_interrupts() {
|
void restore_global_interrupts() {
|
||||||
|
|
||||||
|
#ifdef USE_FREERTOS
|
||||||
|
taskENABLE_INTERRUPTS();
|
||||||
|
#else
|
||||||
ARM_AR_INT_BITS_SET(old_value);
|
ARM_AR_INT_BITS_SET(old_value);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable_global_interrupts() {
|
void disable_global_interrupts() {
|
||||||
|
#ifdef USE_FREERTOS
|
||||||
|
taskDISABLE_INTERRUPTS();
|
||||||
|
#else
|
||||||
unsigned int value = 0;
|
unsigned int value = 0;
|
||||||
|
|
||||||
ARM_AR_INT_BITS_GET(&value);
|
ARM_AR_INT_BITS_GET(&value);
|
||||||
|
@ -253,7 +294,7 @@ void disable_global_interrupts() {
|
||||||
old_value = value;
|
old_value = value;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*==================================================================*/
|
/*==================================================================*/
|
||||||
|
|
|
@ -32,10 +32,23 @@
|
||||||
#ifndef _BAREMETAL_H
|
#ifndef _BAREMETAL_H
|
||||||
#define _BAREMETAL_H
|
#define _BAREMETAL_H
|
||||||
|
|
||||||
|
#include "amp_os.h"
|
||||||
#include "xil_types.h"
|
#include "xil_types.h"
|
||||||
#include "xparameters.h"
|
#include "xparameters.h"
|
||||||
#include "xil_cache.h"
|
#include "xil_cache.h"
|
||||||
#include "xreg_cortexr5.h"
|
#include "xreg_cortexr5.h"
|
||||||
|
#ifdef USE_FREERTOS
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "timers.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct XOpenAMPInstPtr{
|
||||||
|
unsigned int IntrID;
|
||||||
|
unsigned int IPI_Status;
|
||||||
|
void *lock;
|
||||||
|
};
|
||||||
|
|
||||||
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
|
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
|
||||||
|
|
||||||
|
@ -97,6 +110,7 @@ void platform_cache_disable();
|
||||||
void platform_map_mem_region(unsigned int va,unsigned int pa, unsigned int size, unsigned int flags);
|
void platform_map_mem_region(unsigned int va,unsigned int pa, unsigned int size, unsigned int flags);
|
||||||
unsigned long platform_vatopa(void *addr);
|
unsigned long platform_vatopa(void *addr);
|
||||||
void *platform_patova(unsigned long addr);
|
void *platform_patova(unsigned long addr);
|
||||||
|
void process_communication(struct XOpenAMPInstPtr OpenAMPInstance);
|
||||||
void ipi_register_handler(unsigned long ipi_base_addr, unsigned int intr_mask, void *data, void *ipi_handler);
|
void ipi_register_handler(unsigned long ipi_base_addr, unsigned int intr_mask, void *data, void *ipi_handler);
|
||||||
void ipi_trigger(unsigned long ipi_base_addr, unsigned int trigger_mask);
|
void ipi_trigger(unsigned long ipi_base_addr, unsigned int trigger_mask);
|
||||||
|
|
||||||
|
|
328
lib/sw_apps/openamp_rpc_demo/src/lscript_freertos.ld
Normal file
328
lib/sw_apps/openamp_rpc_demo/src/lscript_freertos.ld
Normal file
|
@ -0,0 +1,328 @@
|
||||||
|
/******************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* Use of the Software is limited solely to applications:
|
||||||
|
* (a) running on a Xilinx device, or
|
||||||
|
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||||
|
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||||
|
* this Software without prior written authorization from Xilinx.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x2000;
|
||||||
|
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x2000;
|
||||||
|
|
||||||
|
_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024;
|
||||||
|
_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048;
|
||||||
|
_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024;
|
||||||
|
_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024;
|
||||||
|
_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;
|
||||||
|
|
||||||
|
/* Define Memories in the system */
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
ps8_bbram_0_S_AXI_BASEADDR : ORIGIN = 0xFFCC4000, LENGTH = 0x00001000
|
||||||
|
ps8_csu_ram_0_S_AXI_BASEADDR : ORIGIN = 0xFFC40000, LENGTH = 0x00008000
|
||||||
|
ps8_ddr_S_AXI_BASEADDR : ORIGIN = 0x3ED00000, LENGTH = 0x00040000
|
||||||
|
ps8_ocm_ram_1_S_AXI_BASEADDR : ORIGIN = 0xFFFF0000, LENGTH = 0x00010000
|
||||||
|
ps8_r5_tcm_ram_0_S_AXI_BASEADDR : ORIGIN = 0x00000050, LENGTH = 0x0001FFB1
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specify the default entry point to the program */
|
||||||
|
|
||||||
|
/* ENTRY(_boot) */
|
||||||
|
|
||||||
|
ENTRY(_vector_table)
|
||||||
|
|
||||||
|
/* Define the sections, and where they are mapped in memory */
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
|
||||||
|
.vectors : {
|
||||||
|
*(.vectors)
|
||||||
|
} > ps8_ocm_ram_1_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
|
||||||
|
_binary_firmware1_start = 0;
|
||||||
|
_binary_firmware1_end = 0;
|
||||||
|
_binary_firmware2_start = 0;
|
||||||
|
_binary_firmware2_end = 0;
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
*(.boot)
|
||||||
|
*(.text)
|
||||||
|
*(.text.*)
|
||||||
|
*(.gnu.linkonce.t.*)
|
||||||
|
*(.plt)
|
||||||
|
*(.gnu_warning)
|
||||||
|
*(.gcc_execpt_table)
|
||||||
|
*(.glue_7)
|
||||||
|
*(.glue_7t)
|
||||||
|
*(.vfp11_veneer)
|
||||||
|
*(.ARM.extab)
|
||||||
|
*(.gnu.linkonce.armextab.*)
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.init : {
|
||||||
|
KEEP (*(.init))
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.fini : {
|
||||||
|
KEEP (*(.fini))
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.interp : {
|
||||||
|
KEEP (*(.interp))
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.note-ABI-tag : {
|
||||||
|
KEEP (*(.note-ABI-tag))
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
__rodata_start = .;
|
||||||
|
*(.rodata)
|
||||||
|
*(.rodata.*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
__rodata_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.rodata1 : {
|
||||||
|
__rodata1_start = .;
|
||||||
|
*(.rodata1)
|
||||||
|
*(.rodata1.*)
|
||||||
|
__rodata1_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.sdata2 : {
|
||||||
|
__sdata2_start = .;
|
||||||
|
*(.sdata2)
|
||||||
|
*(.sdata2.*)
|
||||||
|
*(.gnu.linkonce.s2.*)
|
||||||
|
__sdata2_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.sbss2 : {
|
||||||
|
__sbss2_start = .;
|
||||||
|
*(.sbss2)
|
||||||
|
*(.sbss2.*)
|
||||||
|
*(.gnu.linkonce.sb2.*)
|
||||||
|
__sbss2_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
__data_start = .;
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
*(.jcr)
|
||||||
|
*(.got)
|
||||||
|
*(.got.plt)
|
||||||
|
__data_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.data1 : {
|
||||||
|
__data1_start = .;
|
||||||
|
*(.data1)
|
||||||
|
*(.data1.*)
|
||||||
|
__data1_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.got : {
|
||||||
|
*(.got)
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.ctors : {
|
||||||
|
__CTOR_LIST__ = .;
|
||||||
|
___CTORS_LIST___ = .;
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
__CTOR_END__ = .;
|
||||||
|
___CTORS_END___ = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.dtors : {
|
||||||
|
__DTOR_LIST__ = .;
|
||||||
|
___DTORS_LIST___ = .;
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
__DTOR_END__ = .;
|
||||||
|
___DTORS_END___ = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.fixup : {
|
||||||
|
__fixup_start = .;
|
||||||
|
*(.fixup)
|
||||||
|
__fixup_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.eh_frame : {
|
||||||
|
*(.eh_frame)
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.eh_framehdr : {
|
||||||
|
__eh_framehdr_start = .;
|
||||||
|
*(.eh_framehdr)
|
||||||
|
__eh_framehdr_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.gcc_except_table : {
|
||||||
|
*(.gcc_except_table)
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.mmu_tbl (ALIGN(16384)) : {
|
||||||
|
__mmu_tbl_start = .;
|
||||||
|
*(.mmu_tbl)
|
||||||
|
__mmu_tbl_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.ARM.exidx : {
|
||||||
|
__exidx_start = .;
|
||||||
|
*(.ARM.exidx*)
|
||||||
|
*(.gnu.linkonce.armexidix.*.*)
|
||||||
|
__exidx_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.preinit_array : {
|
||||||
|
__preinit_array_start = .;
|
||||||
|
KEEP (*(SORT(.preinit_array.*)))
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
__preinit_array_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.init_array : {
|
||||||
|
__init_array_start = .;
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array))
|
||||||
|
__init_array_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.fini_array : {
|
||||||
|
__fini_array_start = .;
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
KEEP (*(.fini_array))
|
||||||
|
__fini_array_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.ARM.attributes : {
|
||||||
|
__ARM.attributes_start = .;
|
||||||
|
*(.ARM.attributes)
|
||||||
|
__ARM.attributes_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.sdata : {
|
||||||
|
__sdata_start = .;
|
||||||
|
*(.sdata)
|
||||||
|
*(.sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
__sdata_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.sbss (NOLOAD) : {
|
||||||
|
__sbss_start = .;
|
||||||
|
*(.sbss)
|
||||||
|
*(.sbss.*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
__sbss_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.tdata : {
|
||||||
|
__tdata_start = .;
|
||||||
|
*(.tdata)
|
||||||
|
*(.tdata.*)
|
||||||
|
*(.gnu.linkonce.td.*)
|
||||||
|
__tdata_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.tbss : {
|
||||||
|
__tbss_start = .;
|
||||||
|
*(.tbss)
|
||||||
|
*(.tbss.*)
|
||||||
|
*(.gnu.linkonce.tb.*)
|
||||||
|
__tbss_end = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.bss (NOLOAD) : {
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(.bss)
|
||||||
|
*(.bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end__ = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
|
||||||
|
|
||||||
|
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
|
||||||
|
|
||||||
|
/* Generate Stack and Heap definitions */
|
||||||
|
|
||||||
|
.heap (NOLOAD) : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
_heap = .;
|
||||||
|
HeapBase = .;
|
||||||
|
_heap_start = .;
|
||||||
|
. += _HEAP_SIZE;
|
||||||
|
_heap_end = .;
|
||||||
|
HeapLimit = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
.stack (NOLOAD) : {
|
||||||
|
. = ALIGN(16);
|
||||||
|
_stack_end = .;
|
||||||
|
. += _STACK_SIZE;
|
||||||
|
_stack = .;
|
||||||
|
__stack = _stack;
|
||||||
|
. = ALIGN(16);
|
||||||
|
_irq_stack_end = .;
|
||||||
|
. += _IRQ_STACK_SIZE;
|
||||||
|
__irq_stack = .;
|
||||||
|
_supervisor_stack_end = .;
|
||||||
|
. += _SUPERVISOR_STACK_SIZE;
|
||||||
|
. = ALIGN(16);
|
||||||
|
__supervisor_stack = .;
|
||||||
|
_abort_stack_end = .;
|
||||||
|
. += _ABORT_STACK_SIZE;
|
||||||
|
. = ALIGN(16);
|
||||||
|
__abort_stack = .;
|
||||||
|
_fiq_stack_end = .;
|
||||||
|
. += _FIQ_STACK_SIZE;
|
||||||
|
. = ALIGN(16);
|
||||||
|
__fiq_stack = .;
|
||||||
|
_undef_stack_end = .;
|
||||||
|
. += _UNDEF_STACK_SIZE;
|
||||||
|
. = ALIGN(16);
|
||||||
|
__undef_stack = .;
|
||||||
|
} > ps8_ddr_S_AXI_BASEADDR
|
||||||
|
|
||||||
|
_end = .;
|
||||||
|
}
|
|
@ -76,9 +76,10 @@ int _enable_interrupt(struct proc_vring *vring_hw) {
|
||||||
/* Register ISR*/
|
/* Register ISR*/
|
||||||
env_register_isr(vring_hw->intr_info.vect_id, &(chn_ipi_info->ipi_base_addr), ipi_isr);
|
env_register_isr(vring_hw->intr_info.vect_id, &(chn_ipi_info->ipi_base_addr), ipi_isr);
|
||||||
/* Enable IPI interrupt */
|
/* Enable IPI interrupt */
|
||||||
env_enable_interrupt(vring_hw->intr_info.vect_id,
|
/* FIXME: enabled interrupt in application */
|
||||||
|
/*env_enable_interrupt(vring_hw->intr_info.vect_id,
|
||||||
vring_hw->intr_info.priority,
|
vring_hw->intr_info.priority,
|
||||||
vring_hw->intr_info.trigger_type);
|
vring_hw->intr_info.trigger_type);*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +96,7 @@ void _notify(int cpu_id, struct proc_intr *intr_info) {
|
||||||
if (chn_ipi_info == NULL)
|
if (chn_ipi_info == NULL)
|
||||||
return;
|
return;
|
||||||
platform_dcache_all_flush();
|
platform_dcache_all_flush();
|
||||||
|
env_wmb();
|
||||||
/* Trigger IPI */
|
/* Trigger IPI */
|
||||||
ipi_trigger(chn_ipi_info->ipi_base_addr, chn_ipi_info->ipi_chn_mask);
|
ipi_trigger(chn_ipi_info->ipi_base_addr, chn_ipi_info->ipi_chn_mask);
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,22 +84,37 @@
|
||||||
#include "rpmsg_retarget.h"
|
#include "rpmsg_retarget.h"
|
||||||
#include "xil_cache.h"
|
#include "xil_cache.h"
|
||||||
#include "xil_mmu.h"
|
#include "xil_mmu.h"
|
||||||
#include "xreg_cortexr5.h"
|
|
||||||
|
#define SHUTDOWN_MSG 0xEF56A55A
|
||||||
|
#ifdef USE_FREERTOS
|
||||||
|
#define DELAY_200MSEC 200/portTICK_PERIOD_MS
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Internal functions */
|
/* Internal functions */
|
||||||
static void init_system();
|
|
||||||
static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl);
|
static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl);
|
||||||
static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl);
|
static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl);
|
||||||
static void rpmsg_read_cb(struct rpmsg_channel *, void *, int, void *, unsigned long);
|
static void rpmsg_read_cb(struct rpmsg_channel *, void *, int, void *, unsigned long);
|
||||||
static void shutdown_cb(struct rpmsg_channel *rp_chnl);
|
static void shutdown_cb(struct rpmsg_channel *rp_chnl);
|
||||||
|
static void communication_task();
|
||||||
|
static void rpc_demo();
|
||||||
|
|
||||||
/* Globals */
|
/* Static variables */
|
||||||
static struct rpmsg_channel *app_rp_chnl;
|
static struct rpmsg_channel *app_rp_chnl;
|
||||||
volatile int chnl_cb_flag = 0;
|
|
||||||
static struct remote_proc *proc = NULL;
|
static struct remote_proc *proc = NULL;
|
||||||
static struct rsc_table_info rsc_info;
|
static struct rsc_table_info rsc_info;
|
||||||
extern const struct remote_resource_table resources;
|
#ifdef USE_FREERTOS
|
||||||
|
static TimerHandle_t stop_scheduler;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_FREERTOS
|
||||||
|
static TaskHandle_t comm_task;
|
||||||
|
static TaskHandle_t rpc_dmo;
|
||||||
|
#endif
|
||||||
|
void *chnl_cb_flag;
|
||||||
|
/* Globals */
|
||||||
|
|
||||||
|
extern const struct remote_resource_table resources;
|
||||||
|
struct XOpenAMPInstPtr OpenAMPInstPtr;
|
||||||
#define REDEF_O_CREAT 100
|
#define REDEF_O_CREAT 100
|
||||||
#define REDEF_O_EXCL 200
|
#define REDEF_O_EXCL 200
|
||||||
#define REDEF_O_RDONLY 0
|
#define REDEF_O_RDONLY 0
|
||||||
|
@ -112,6 +127,64 @@ extern const struct remote_resource_table resources;
|
||||||
|
|
||||||
/* Application entry point */
|
/* Application entry point */
|
||||||
int main() {
|
int main() {
|
||||||
|
|
||||||
|
#ifdef USE_FREERTOS
|
||||||
|
BaseType_t stat;
|
||||||
|
|
||||||
|
/* Create the tasks */
|
||||||
|
stat = xTaskCreate(communication_task, ( const char * ) "HW2",
|
||||||
|
1024, NULL,2,&comm_task);
|
||||||
|
if(stat != pdPASS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
stat = xTaskCreate(rpc_demo, ( const char * ) "HW2",
|
||||||
|
2048, NULL, 1, &rpc_dmo );
|
||||||
|
if(stat != pdPASS)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/*Create Queues*/
|
||||||
|
env_create_sync_lock(&OpenAMPInstPtr.lock,LOCKED);
|
||||||
|
env_create_sync_lock(&chnl_cb_flag,LOCKED);
|
||||||
|
|
||||||
|
/* Start the tasks and timer running. */
|
||||||
|
vTaskStartScheduler();
|
||||||
|
#else
|
||||||
|
env_create_sync_lock(&chnl_cb_flag,LOCKED);
|
||||||
|
communication_task();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void communication_task(){
|
||||||
|
int status;
|
||||||
|
|
||||||
|
rsc_info.rsc_tab = (struct resource_table *)&resources;
|
||||||
|
rsc_info.size = sizeof(resources);
|
||||||
|
|
||||||
|
zynqMP_r5_gic_initialize();
|
||||||
|
|
||||||
|
/* Initialize RPMSG framework */
|
||||||
|
status = remoteproc_resource_init(&rsc_info, rpmsg_channel_created, rpmsg_channel_deleted,
|
||||||
|
rpmsg_read_cb ,&proc);
|
||||||
|
if (status < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
env_enable_interrupt(VRING1_IPI_INTR_VECT,0,0);
|
||||||
|
|
||||||
|
#ifdef USE_FREERTOS
|
||||||
|
while (1) {
|
||||||
|
env_acquire_sync_lock(OpenAMPInstPtr.lock);
|
||||||
|
process_communication(OpenAMPInstPtr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
rpc_demo();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void rpc_demo(){
|
||||||
int fd, bytes_written, bytes_read;
|
int fd, bytes_written, bytes_read;
|
||||||
char fname[] = "remote.file";
|
char fname[] = "remote.file";
|
||||||
char wbuff[50];
|
char wbuff[50];
|
||||||
|
@ -120,33 +193,17 @@ int main() {
|
||||||
float fdata;
|
float fdata;
|
||||||
int idata;
|
int idata;
|
||||||
int ret;
|
int ret;
|
||||||
int status;
|
|
||||||
|
|
||||||
/* Initialize HW system components */
|
env_acquire_sync_lock(chnl_cb_flag);
|
||||||
init_system();
|
|
||||||
|
|
||||||
rsc_info.rsc_tab = (struct resource_table *) &resources;
|
|
||||||
rsc_info.size = sizeof(resources);
|
|
||||||
|
|
||||||
/* Initialize RPMSG framework */
|
|
||||||
status = remoteproc_resource_init(&rsc_info, rpmsg_channel_created,
|
|
||||||
rpmsg_channel_deleted, rpmsg_read_cb, &proc);
|
|
||||||
if (status < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!chnl_cb_flag) {
|
|
||||||
__asm__ ( "\
|
|
||||||
wfi\n\t" \
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
chnl_cb_flag = 0;
|
|
||||||
|
|
||||||
rpmsg_retarget_init(app_rp_chnl, shutdown_cb);
|
rpmsg_retarget_init(app_rp_chnl, shutdown_cb);
|
||||||
|
#ifdef USE_FREERTOS
|
||||||
|
printf("\r\nRemote>FreeRTOS Remote Procedure Call (RPC) Demonstration\r\n");
|
||||||
|
#else
|
||||||
printf("\r\nRemote>Baremetal Remote Procedure Call (RPC) Demonstration\r\n");
|
printf("\r\nRemote>Baremetal Remote Procedure Call (RPC) Demonstration\r\n");
|
||||||
|
#endif
|
||||||
printf("\r\nRemote>***************************************************\r\n");
|
printf("\r\nRemote>***************************************************\r\n");
|
||||||
|
|
||||||
printf("\r\nRemote>Rpmsg based retargetting to proxy initialized..\r\n");
|
printf("\r\nRemote>Rpmsg based retargetting to proxy initialized..\r\n");
|
||||||
|
|
||||||
/* Remote performing file IO on Master */
|
/* Remote performing file IO on Master */
|
||||||
|
@ -217,13 +274,11 @@ int main() {
|
||||||
wfi\n\t" \
|
wfi\n\t" \
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl) {
|
static void rpmsg_channel_created(struct rpmsg_channel *rp_chnl) {
|
||||||
app_rp_chnl = rp_chnl;
|
app_rp_chnl = rp_chnl;
|
||||||
chnl_cb_flag = 1;
|
env_release_sync_lock(chnl_cb_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl) {
|
static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl) {
|
||||||
|
@ -232,15 +287,18 @@ static void rpmsg_channel_deleted(struct rpmsg_channel *rp_chnl) {
|
||||||
static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
|
static void rpmsg_read_cb(struct rpmsg_channel *rp_chnl, void *data, int len,
|
||||||
void * priv, unsigned long src) {
|
void * priv, unsigned long src) {
|
||||||
}
|
}
|
||||||
|
#ifdef USE_FREERTOS
|
||||||
|
static void StopSchedulerTmrCallBack(TimerHandle_t timer)
|
||||||
|
{
|
||||||
|
vTaskEndScheduler();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
static void shutdown_cb(struct rpmsg_channel *rp_chnl) {
|
static void shutdown_cb(struct rpmsg_channel *rp_chnl) {
|
||||||
rpmsg_retarget_deinit(rp_chnl);
|
rpmsg_retarget_deinit(rp_chnl);
|
||||||
remoteproc_resource_deinit(proc);
|
remoteproc_resource_deinit(proc);
|
||||||
}
|
#ifdef USE_FREERTOS
|
||||||
|
int TempTimerId;
|
||||||
static void init_system() {
|
stop_scheduler = xTimerCreate("TMR", DELAY_200MSEC, pdFALSE, (void *)&TempTimerId, StopSchedulerTmrCallBack);
|
||||||
|
xTimerStart(stop_scheduler, 0);
|
||||||
/* Initilaize GIC */
|
#endif
|
||||||
zynqMP_r5_gic_initialize();
|
}
|
||||||
|
|
||||||
}
|
|
|
@ -44,9 +44,9 @@ struct remote_resource_table {
|
||||||
unsigned int reserved[2];
|
unsigned int reserved[2];
|
||||||
unsigned int offset[NO_RESOURCE_ENTRIES];
|
unsigned int offset[NO_RESOURCE_ENTRIES];
|
||||||
/* text carve out entry */
|
/* text carve out entry */
|
||||||
struct fw_rsc_carveout ocm_1_cout;
|
struct fw_rsc_carveout ocm_1_cout;
|
||||||
struct fw_rsc_carveout ddr_cout;
|
struct fw_rsc_carveout ddr_cout;
|
||||||
/* rpmsg vdev entry */
|
/* rpmsg vdev entry */
|
||||||
struct fw_rsc_vdev rpmsg_vdev;
|
struct fw_rsc_vdev rpmsg_vdev;
|
||||||
struct fw_rsc_vdev_vring rpmsg_vring0;
|
struct fw_rsc_vdev_vring rpmsg_vring0;
|
||||||
struct fw_rsc_vdev_vring rpmsg_vring1;
|
struct fw_rsc_vdev_vring rpmsg_vring1;
|
||||||
|
|
Loading…
Add table
Reference in a new issue