zynq petalinux AMP双核运行linux+ucos(或者裸机)之间进行 IPI 软中断通讯的实现

博主分享了自己实现的Linux驱动程序,用于在Zynq平台的双核CPU间进行启动、停止及中断通讯。驱动简化了官方remoteprocAMP程序的复杂性,提供了启动CPU1、停止CPU1和IPI中断通知的功能。通过设备树配置和ioctl接口,驱动能够加载CPU1的bin文件并在两CPU间进行数据交换。应用示例展示了如何在Linux用户空间触发和响应这些操作。

前几天试验了xilinx官方remotporc AMP程序,运行是运行起来了,但是感觉太复杂了,我只想要一个能启动停止cpu1,能在两个cpu之间方便通讯的功能就行了,看着remotproc框架一堆的代码,编译出来的elf文件体积还超级大心里就非常不爽,想着干脆自己实现一个简单处理驱动程序算了,so...经过几天的痛苦研究,也算完整实现了想要的功能

由于linux应用程序不能处理硬件中断,因此这个IPI通讯只能在驱动层进行处理,所以第一步,要编写一个驱动程序,实现cpu1的bin(不是elf)文件加载,控制启动和停止cpu1,处理cpu0和cpu1之间的ipi中断,完整驱动代码如下

/*  ampipidevice.c - The simplest kernel module.

* Copyright (C) 2013 - 2016 Xilinx, Inc
*
*   This program is free software; you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation; either version 2 of the License, or
*   (at your option) any later version.

*   This program is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License along
*   with this program. If not, see <http://www.gnu.org/licenses/>.

*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/uaccess.h> 
#include <linux/cdev.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_irq.h>
#include <linux/fs.h>
#include <linux/fcntl.h> 

#include <../../arch/arm/mach-zynq/common.h>
#include <linux/irqchip/arm-gic.h> 

extern int zynq_cpun_stop(int cpu);



/* Standard module information, edit as appropriate */
MODULE_LICENSE("GPL");
MODULE_AUTHOR
    ("Xilinx Inc.");
MODULE_DESCRIPTION
    ("ampipidevice - loadable module template generated by petalinux-create -t modules");

#define DRIVER_NAME "ampipi_Device"
#define DRIVER_NUM   1                      



#define StarCpu1			0x10000000
#define StopCpu1			0x20000000
#define KickCpu1			0x30000000

struct ampipidevice_local 
{
	int cpu0_to_cpu1_ipi;
	int cpu1_to_cpu0_ipi;
	unsigned long mem_start;
	unsigned long mem_end;
	void __iomem *base_addr;
};


struct ampipi_dev 
{ 
	dev_t devid;                   /*  设备号  */ 
	struct cdev chdev;            	/* cdev 结构体  */ 
	struct class *class;         	/*  类  */ 
	struct device *device;     		/*  设备  */ 
	struct ampipidevice_local *param;
	struct fasync_struct *async_queue; 
}; 

static struct ampipi_dev ampipi;  


/*********************************************************************
*
*
*
**********************************************************************/
static int ampipi_open(struct inode *inode, struct file *filp) 
{ 

	cpu_up(1);
	printk("ampipi Dev: open success  \r\n"); 
					
	return 0; 
} 

/*********************************************************************
*
*
*
**********************************************************************/
static ssize_t ampipi_write(struct file *filp, const char __user *buf,size_t cnt, loff_t *offt) 
{
	int ret; 
	
	ret = copy_from_user((unsigned char*)(ampipi.param->base_addr + (*offt)), buf, cnt);  
	
	if(0 > ret)
	{
		printk(KERN_ERR "ampipi Dev: Failed to copy data from user space \r\n"); 
		return -EFAULT; 			
	}
	
	printk("ampipi Dev: write add: %08X  cnt: %d\r\n",(unsigned int)(ampipi.param->base_addr + (*offt)),cnt); 
	
	*offt = *offt + cnt;
	
	return cnt;
}

/*********************************************************************
*
*
*
**********************************************************************/
static ssize_t ampipi_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt) 
{ 
	int ret = 0; 
	
	ret = copy_to_user(buf, (unsigned char*)(ampipi.param->base_addr + (*offt)) , cnt); 
	
	if(ret < 0)
	{ 
		pri
评论 13
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值