MPU Native
Contents |
Overview
The native code version of an MPU library is an optimized straight C-language implementation of the function with no calls to external hardware. Using conditional compilation, it may call vendor optimized CPU only library functions.
During compilation an auto-generated header file will be created.
Example
FooNative.c
/* Create Wrappers */
#include "MPULibNative.h"
#define CMETHOD(M) FooNative_## M
#define JMETHOD(M) Java_nxm_demo_lib_FooNative_## M
#include "MPULibWrappers.h"
typedef struct {
int mult;
char * keyStr;
char format[2];
} FooObj;
/* c-functions */
void *CMETHOD (alloc) () {
FooObj *p = malloc(sizeof(FooObj));
p->mult = 2;
p->keyStr = NULL;
strncpy(p->format, "SI", 2);
return (void *) p;
}
int_4 CMETHOD (setkey) (void *handle, char *key, void *val, int_4 len) {
FooObj *p = (FooObj*)handle;
if ( keyMatch("MULTKEY") ) {
p->mult = *(int*) val;
}
else if ( keyMatch("STRKEY") ) {
p->keyStr = calloc(len, sizeof(char));
strncpy( p->keyStr, (char *) val, len);
printf("The string resource is now set to: %s\n", p->keyStr);
}
else if ( keyMatch("FORMAT") ) {
/* format can only be 2 char's */
strncpy(p->format, (char *) val, 2);
}
else {
return 0;
}
return len;
}
int_4 CMETHOD (init) (void *handle) {
FooObj *p = (FooObj*)handle;
if ( strcmp(p->format, "CI") && strcmp(p->format, "SI") ) {
printf("Error! format must be CI or SI\n!!!");
return -1;
}
return 0;
}
int_4 CMETHOD (work2) (void *handle, void *b1, int_4 n1, void *b2, int_4 n2) {
FooObj *p = (FooObj*)handle;
short *buf1 = (short*)b1;
short *buf2 = (short*)b2;
/* do some work and return */
int m;
for (m=0; m<n1; m++)
buf2[m] = p->mult*buf1[m];
return n1;
}
int_4 CMETHOD (free) (void *handle) {
FooObj *p = (FooObj*)handle;
if (p->keyStr) free(p->keyStr);
free(p);
return 0;
}
Wrapper Code
FooNative.java
package nxm.demo.lib;
import nxm.sys.lib.MPULibNative;
/* wrapper for c-implementation of foo */
public class FooNative extends MPULibNative {
/* override method's in MPULibNative */
public native long alloc();
public native int setkey (long handle, String key, byte[] value, int len);
public native int getkey (long handle, String key, byte[] value, int len);
public native int init (long handle);
public native int work2 (long handle, byte[] buf1, int n1, byte[] buf2, int n2);
public native int free (long handle);
}
Compilation
In order to run native code under NeXtMidas, a Java wrapper class AND a native C file are required. Both the Java and the Native function MUST have the same file name and be located in the same folder. This will allow the NeXtMidas compiler to link the two objects.
Compilation can be performed by 'making' the entire option tree or by using the 'bld' command. Here is an example of how to run the bld command (for our example above):
nM> bld fooNative lib demo
The output should look as follows:
INFO: Compiling /midas/opt/nmxxx/nxm/demo/lib/FooNative.java INFO: Compiling /midas/opt/nmxxx/nxm/demo/lib/FooNative.c INFO: Build 2 files for opt=DEMO area=lib name=fooNative
Now, you are ready to run native code!
Other Examples
Java: MPU Java
GPU: MPU GPU
ICE: MPU ICE
Verilator: MPU Verilator