PYNQ-Z2调试笔记:在Microblaze软核中编程运行C程序

本篇主要介绍,通过Jupyter在Microblaze Subsystems上使用C语言编程,实现一些简单的功能。


目录

前言

正文

一、软核PMODA、PMODB、RPI、ARDUINO

二、在软核上编程C程序

(1)加载基础覆盖

(2)定义子函数并调用

(3)数据类型转换

(4)申请指针,申请获取大块的内存空间存放数组数据等。

(5)创建类对象等

(6)注意事项

结尾


前言

关于软核的知识,笔者所知比较少,个人浅显的理解为,软核是一种比较特殊的IP核,是一种微处理器IP核。在由电源、Microblaze以及FPGA构成的主板和内存所组成的最小系统下,我们可以像在PC机上使用C语言一样进行编程,从而对硬件进行操作。

下面是在网上找开源项目时偶然发现的关于软核编程的教程,所以拿来和大家一起分享。

正文

一、软核PMODA、PMODB、RPI、ARDUINO

笔者发现,pynq上可以用来编程的软核主要有PMODA、PMODB、RPI、ARDUINO,而这恰恰对应官方手册里的IOPs部分。仔细阅读过文档不难发现,这四个其实是开发板留出来的扩展接口,所以根据推测可知,每个接口对应的软核其实是在接口与扩展设备交互时,用于控制使用的。

我们可以打开开发板的文件base.py,从代码中也可以印证我们的推测。下面以ARDUINO为例,介绍如何在软核上编程。

二、在软核上编程C程序

(1)加载基础覆盖

 load an overlay

from pynq.overlays.base import BaseOverlay

base = BaseOverlay('base.bit')

jupyter编程界面(此文件文末给出):

(2)定义子函数并调用

The %%microblaze magic provides an environment where we can write the code and it takes a single argument - the Microblaze we wish to target this code at. This first example simply adds two numbers together and returns the result.

The functions we defined in the magic are now available for us to interact with in Python as any other function.

%%microblaze base.ARDUINO
#此处可以使用的有: PMODA、PMODB、RPI、ARDUINO

int add(int a, int b) {
    return a + b;
}
add(4,6)

(3)数据类型转换

The main purpose of the Python bindings it to transfer data between the host and slave processors. For simple cases, any primitive C type can be used as function parameters and return values and Python values will be automatically converted as necessary.

%%microblaze base.ARDUINO

float arg_passing(float a, char b, unsigned int c) {
    return a + b + c;
}
arg_passing(1, 2, 3)

(4)申请指针,申请获取大块的内存空间存放数组数据等。

Finally we can pass a void pointer which will allow the Microblaze to directly access the memory of the host processing system for transferring large quantities of data. In Python these blocks of memory should be allocated using the Xlnk.cma_array function and it is the responsibility of the programmer to make sure that the Python and C code agree on the types used.

%%microblaze base.ARDUINO

long long big_sum(void* data, int len) {
    int* int_data = (int*)data;
    long long sum = 0;
    for (int i = 0; i < len; ++i) {
        sum += int_data[i];
    }
    return sum;
}
from pynq import Xlnk
allocator = Xlnk()

buffer = allocator.cma_array(shape=(1024 * 1024), dtype='i4')
buffer[:] = range(1024*1024)

big_sum(buffer, len(buffer))

(5)创建类对象等

In the C code typedefs can be used to create psuedo classes in Python. If you have a typedef called my_class then any functions that being my_class_ are assumed to be associated with it. If one of those functions takes my_class as the first argument it is taken to be equivalent to self. Note that the typedef can only ultimately refer a primitive type. The following example does some basic modular arithmetic base 53 using this idiom.

%%microblaze base.ARDUINO

typedef unsigned int mod_int;

mod_int mod_int_create(int val) { return val % 53; }
mod_int mod_int_add(mod_int lhs, int rhs) { return (lhs + rhs) % 53; }
a = mod_int_create(63)
b = a.add(4)
print(b)
print(b.val)

(6)注意事项

有些C中的功能是不受支持的

There are some limitations to be aware of in the Jupyter integration with the Microblaze subsystem in particular the following things are unsupported and will result in the function not being available.

  • structs or unions of any kind
  • Pointers to pointers
  • returning pointers

All non void* parameters are passed on the stack so beware of passing large arrays in this fashion or a stack overflow will result.

结尾

目前还不知道在软核中编程C的用途,不过应该是一个比较重要的功能,后续用到会再拿来说的。


代码文件链接:https://pan.baidu.com/s/1lMdQ2_WEfheJIyA7paCr_w 
提取码:ambc


文章到这里就结束了,如果这篇文章帮助到了您,请点赞鼓励,谢谢!

技术交流请在下方评论区,笔者会尽快回复的!

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值