前几天试验了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

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





