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];
|
||||
|
||||
if { $os != "standalone" } {
|
||||
error "This application is supported only on the Standalone Board Support Package.";
|
||||
if { ( $os != "standalone" ) && ( $os != "freertos821_xilinx" ) } {
|
||||
error "This application is supported only on the Standalone Board Support Package and freertos821.";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,6 +90,20 @@ proc check_stdout_hw {} {
|
|||
}
|
||||
|
||||
proc swapp_generate {} {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -104,5 +118,5 @@ proc swapp_get_supported_processors {} {
|
|||
}
|
||||
|
||||
proc swapp_get_supported_os {} {
|
||||
return "standalone";
|
||||
return "freertos821_xilinx standalone";
|
||||
}
|
||||
|
|
|
@ -30,21 +30,25 @@
|
|||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "xparameters.h"
|
||||
#include "xil_exception.h"
|
||||
#include "xscugic.h"
|
||||
#include "xil_cache.h"
|
||||
#include "xil_mpu.h"
|
||||
#include "baremetal.h"
|
||||
#include "env.h"
|
||||
|
||||
XScuGic InterruptController;
|
||||
#include "platform.h"
|
||||
#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() {
|
||||
#ifndef USE_FREERTOS
|
||||
u32 Status;
|
||||
|
||||
Xil_ExceptionDisable();
|
||||
|
||||
XScuGic_Config *IntcConfig; /* The configuration parameters of the interrupt controller */
|
||||
|
||||
/*
|
||||
|
@ -55,7 +59,7 @@ int zynqMP_r5_gic_initialize() {
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XScuGic_CfgInitialize(&InterruptController, IntcConfig,
|
||||
Status = XScuGic_CfgInitialize(&xInterruptController, IntcConfig,
|
||||
IntcConfig->CpuBaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
|
@ -66,26 +70,58 @@ int zynqMP_r5_gic_initialize() {
|
|||
* logic in the ARM processor.
|
||||
*/
|
||||
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
|
||||
(Xil_ExceptionHandler) zynqMP_r5_irq_isr,
|
||||
&InterruptController);
|
||||
|
||||
(Xil_ExceptionHandler)XScuGic_InterruptHandler,&xInterruptController);
|
||||
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;
|
||||
}
|
||||
|
||||
extern void bm_env_isr(int vector);
|
||||
|
||||
void zynqMP_r5_irq_isr() {
|
||||
void zynqMP_r5_irq_isr(void *OpenAMPInst) {
|
||||
|
||||
unsigned int raw_irq;
|
||||
int irq_vector;
|
||||
raw_irq = (unsigned int)XScuGic_CPUReadReg(&InterruptController,XSCUGIC_INT_ACK_OFFSET);
|
||||
irq_vector = (int) (raw_irq & XSCUGIC_ACK_INTID_MASK);
|
||||
struct XOpenAMPInstPtr *OpenAMPInstance;
|
||||
int idx;
|
||||
struct isr_info *info;
|
||||
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));
|
||||
}
|
||||
|
||||
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 int ipi_intr_status = (unsigned int)Xil_In32(ipi_base_addr + IPI_ISR_OFFSET);
|
||||
int i = 0;
|
||||
do {
|
||||
Xil_Out32((ipi_base_addr + IPI_ISR_OFFSET), ipi_intr_status);
|
||||
|
@ -236,12 +271,18 @@ unsigned int old_value = 0;
|
|||
|
||||
void restore_global_interrupts() {
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
taskENABLE_INTERRUPTS();
|
||||
#else
|
||||
ARM_AR_INT_BITS_SET(old_value);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void disable_global_interrupts() {
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
taskDISABLE_INTERRUPTS();
|
||||
#else
|
||||
unsigned int value = 0;
|
||||
|
||||
ARM_AR_INT_BITS_GET(&value);
|
||||
|
@ -253,7 +294,7 @@ void disable_global_interrupts() {
|
|||
old_value = value;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*==================================================================*/
|
||||
|
|
|
@ -32,10 +32,23 @@
|
|||
#ifndef _BAREMETAL_H
|
||||
#define _BAREMETAL_H
|
||||
|
||||
#include "amp_os.h"
|
||||
#include "xil_types.h"
|
||||
#include "xparameters.h"
|
||||
#include "xil_cache.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
|
||||
|
||||
|
@ -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);
|
||||
unsigned long platform_vatopa(void *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_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*/
|
||||
env_register_isr(vring_hw->intr_info.vect_id, &(chn_ipi_info->ipi_base_addr), ipi_isr);
|
||||
/* 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.trigger_type);
|
||||
vring_hw->intr_info.trigger_type);*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -95,6 +96,7 @@ void _notify(int cpu_id, struct proc_intr *intr_info) {
|
|||
if (chn_ipi_info == NULL)
|
||||
return;
|
||||
platform_dcache_all_flush();
|
||||
env_wmb();
|
||||
/* Trigger IPI */
|
||||
ipi_trigger(chn_ipi_info->ipi_base_addr, chn_ipi_info->ipi_chn_mask);
|
||||
}
|
||||
|
|
|
@ -84,22 +84,37 @@
|
|||
#include "rpmsg_retarget.h"
|
||||
#include "xil_cache.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 */
|
||||
static void init_system();
|
||||
static void rpmsg_channel_created(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 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;
|
||||
volatile int chnl_cb_flag = 0;
|
||||
static struct remote_proc *proc = NULL;
|
||||
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_EXCL 200
|
||||
#define REDEF_O_RDONLY 0
|
||||
|
@ -112,6 +127,64 @@ extern const struct remote_resource_table resources;
|
|||
|
||||
/* Application entry point */
|
||||
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;
|
||||
char fname[] = "remote.file";
|
||||
char wbuff[50];
|
||||
|
@ -120,33 +193,17 @@ int main() {
|
|||
float fdata;
|
||||
int idata;
|
||||
int ret;
|
||||
int status;
|
||||
|
||||
/* Initialize HW system components */
|
||||
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;
|
||||
env_acquire_sync_lock(chnl_cb_flag);
|
||||
|
||||
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");
|
||||
#endif
|
||||
printf("\r\nRemote>***************************************************\r\n");
|
||||
|
||||
printf("\r\nRemote>Rpmsg based retargetting to proxy initialized..\r\n");
|
||||
|
||||
/* Remote performing file IO on Master */
|
||||
|
@ -217,13 +274,11 @@ int main() {
|
|||
wfi\n\t" \
|
||||
);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rpmsg_channel_created(struct rpmsg_channel *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) {
|
||||
|
@ -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,
|
||||
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) {
|
||||
rpmsg_retarget_deinit(rp_chnl);
|
||||
remoteproc_resource_deinit(proc);
|
||||
}
|
||||
|
||||
static void init_system() {
|
||||
|
||||
/* Initilaize GIC */
|
||||
zynqMP_r5_gic_initialize();
|
||||
|
||||
#ifdef USE_FREERTOS
|
||||
int TempTimerId;
|
||||
stop_scheduler = xTimerCreate("TMR", DELAY_200MSEC, pdFALSE, (void *)&TempTimerId, StopSchedulerTmrCallBack);
|
||||
xTimerStart(stop_scheduler, 0);
|
||||
#endif
|
||||
}
|
Loading…
Add table
Reference in a new issue