MicroPython on Altera NIOS 2

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
usjcarkm
Posts: 17
Joined: Fri Jun 05, 2015 9:25 pm

MicroPython on Altera NIOS 2

Post by usjcarkm » Fri Jun 05, 2015 9:54 pm

Hello,

I am porting the code to work with a Altera NIOS 2 family processor.
If someone has already done this work let me know, so I can
learn what was needed.

To obtain a bare minimum code set to start porting, I have the following folders copied from the latest
micropython-lib-master.zip:
/lib
/minimal
/py
/stmhal

Does anyone have any pointers to get a minimal 'hello world' python script running ?
I am starting to remove files from the above folders to minimize functionality I won't need until later.
I can build up the code after. Again just want to prove the concept first.

Thanks for any help provided.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: MicroPython on Altera NIOS 2

Post by dhylands » Fri Jun 05, 2015 11:01 pm

I moved your question into the "Other Boards" section.

When I ported to teensy, I started by getting a REPL on a serial port. This is definitely the easiest way to go.

You don't need any of the peripheral support, or filesystem support.

stmhal/pybstdio.c calls out to mp_hal_stdout_tx_xxx

So you should make an mphal.c which is specific to your port.

Your main.c will then be quite small.

usjcarkm
Posts: 17
Joined: Fri Jun 05, 2015 9:25 pm

Re: MicroPython on Altera NIOS 2

Post by usjcarkm » Wed Jun 10, 2015 9:02 pm

Thanks.

So far I'm having some makefile issues when porting the code to our Altera NIOS 2 environment.
We use cygwin (linux shell) in windows 7 and the in our makefile CROSS_COMPILE := nios2-elf- ).

I admit I'm not a pro at makefile internals, but I'm a little confused on how the
"minimal" makefile and/or associated mk files pull in the py/*.c files to build.
I see that this line may potentially make this connection.
include ../py/mkrules.mk
This line in that file appears to pull in the py/*.c files to build.
vpath %.c . $(TOP)$(BUILD)/%.o: %.c$ (call compile_c)

Is the above what allows the py/*.c files to build ? If not what does ?
Hopefully it is compatible with our environment. Otherwise, I'm sure an alternate method
of manually adding each file the makefile is possible.

Thanks

Here below is a portion of the linux/unix build output, where the py/*.c files are shown being built.

waters@ubuntu:~/Desktop/micropython-master/unix$ make
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
mkdir -p build/genhdr
GEN build/genhdr/qstrdefs.generated.h
Generating build/genhdr/mpversion.h
mkdir -p build/build
mkdir -p build/lib/mp-readline
mkdir -p build/py
mkdir -p build/py/../extmod
CC ../py/mpstate.c
CC ../py/nlrx86.S
CC ../py/nlrx64.S
...

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: MicroPython on Altera NIOS 2

Post by dhylands » Wed Jun 10, 2015 10:29 pm

usjcarkm wrote:Thanks.

So far I'm having some makefile issues when porting the code to our Altera NIOS 2 environment.
We use cygwin (linux shell) in windows 7 and the in our makefile CROSS_COMPILE := nios2-elf- ).
What issues are you having?
I admit I'm not a pro at makefile internals, but I'm a little confused on how the
"minimal" makefile and/or associated mk files pull in the py/*.c files to build.
I see that this line may potentially make this connection.
include ../py/mkrules.mk
This line in that file appears to pull in the py/*.c files to build.
vpath %.c . $(TOP)$(BUILD)/%.o: %.c$ (call compile_c)
the py/py.mk defines a variable called PY_O which is the name of all of the objects whicch come from the source files in the py tree.
https://github.com/micropython/micropyt ... py.mk#L125

the stmhal/Makefile, then adds PY_O to the OBJ variable:
https://github.com/micropython/micropyt ... efile#L239

The all target is the first target (when you call make with no arguments) and it eventually has a dependency on firmware.elf:
https://github.com/micropython/micropyt ... efile#L277

which, in turn, depends on the objects listed in $(OBJ) which includes all of the $(PY_O).
Is the above what allows the py/*.c files to build ? If not what does ?
For any object files which don't have any explicit rules (there are a bunch listed at the end of py.mk)
then https://github.com/micropython/micropyt ... mk#L45-L47 will be used to compile the files (as you surmised).

When compiling for the pyboard, BUILD will wind expanding to build-PYBV10 and a typical file from PY_O will look like: build-PYBV10/py/objmap.o, so the actual makerule will look like:

build-PYBV10/py/objmap.o: py/objmap.c

and the vapth specified for %.c causes the py/objmap.c to look from the top of the tree (the micropython directory, not the directory which make was invoked from, which would be inside the stmal directory)

If you're using gcc, then the -MD causes gcc to generate a dependency file, and the sed script massages it (see the references URL for a full background on what the sed script does).

If you have the cygwin version of sed installed, then you should be fine.
Hopefully it is compatible with our environment. Otherwise, I'm sure an alternate method
of manually adding each file the makefile is possible.
Micropython currently builds fine in cygwin as far as I'm aware.
Here below is a portion of the linux/unix build output, where the py/*.c files are shown being built.

waters@ubuntu:~/Desktop/micropython-master/unix$ make
Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.
mkdir -p build/genhdr
GEN build/genhdr/qstrdefs.generated.h
Generating build/genhdr/mpversion.h
mkdir -p build/build
mkdir -p build/lib/mp-readline
mkdir -p build/py
mkdir -p build/py/../extmod
CC ../py/mpstate.c
If you were to add V=1 to your make command line, then you would see the full commands being used to compile the code.

usjcarkm
Posts: 17
Joined: Fri Jun 05, 2015 9:25 pm

Re: MicroPython on Altera NIOS 2

Post by usjcarkm » Thu Jun 11, 2015 9:39 pm

I see. Thanks. The main issue was that I was attempting to compile using an existing makefile that creates a shared library in our environment.

I've instead switched to the basic framework the micropython source tree gives and build an elf for starters. In the end I will need to build a micropython library (i.e. micropython.a), so we can insulate the micropython from our own and ease the transition to micropython base code in the future.

I started out with the 'minimal' folder code base and changed the makefile to use the altera nios2-elf-gcc cross compiler.

So far all the obj's are built apart from the assembly source in the nlrx86.s and nlrx64.s files, which is ecpected as the chip is not intel based.
So removed these from the PY_O_BASENAME = list.

# usjcarkm removed from below list
# nlrx86.o \
# nlrx64.o \

# py object files
PY_O_BASENAME = \
mpstate.o \
nlrthumb.o \

-

I also get "undefined reference to `_nlr_jump'" in spots when linking, which may be because of incompatibility with the altera vs intel chipset.

Getting closer.

Here is the tail end of output:

-

nios2-elf-gcc -Wl,-Map=build/firmware.elf.map,--cref -o build/firmware.elf build/py/mpstate.o build/py/nlrthumb.o build/py/nlrxtensa.o build/py/nlrsetjmp.o build/py/malloc.o build/py/gc.o build/py/qstr.o build/
py/vstr.o build/py/mpprint.o build/py/unicode.o build/py/mpz.o build/py/lexer.o build/py/lexerstr.o build/py/lexerunix.o build/py/parse.o build/py/scope.o build/py/compile.o build/py/emitcommon.o buil
d/py/emitcpy.o build/py/emitbc.o build/py/asmx64.o build/py/emitnx64.o build/py/asmx86.o build/py/emitnx86.o build/py/asmthumb.o build/py/emitnthumb.o build/py/emitinlinethumb.o build/py/asmarm.o buil
d/py/emitnarm.o build/py/formatfloat.o build/py/parsenumbase.o build/py/parsenum.o build/py/emitglue.o build/py/runtime.o build/py/nativeglue.o build/py/stackctrl.o build/py/argcheck.o build/py/warnin
g.o build/py/map.o build/py/obj.o build/py/objarray.o build/py/objattrtuple.o build/py/objbool.o build/py/objboundmeth.o build/py/objcell.o build/py/objclosure.o build/py/objcomplex.o build/py/objdict
.o build/py/objenumerate.o build/py/objexcept.o build/py/objfilter.o build/py/objfloat.o build/py/objfun.o build/py/objgenerator.o build/py/objgetitemiter.o build/py/objint.o build/py/objint_longlong.
o build/py/objint_mpz.o build/py/objlist.o build/py/objmap.o build/py/objmodule.o build/py/objobject.o build/py/objproperty.o build/py/objnone.o build/py/objnamedtuple.o build/py/objrange.o build/py/o
bjreversed.o build/py/objset.o build/py/objsingleton.o build/py/objslice.o build/py/objstr.o build/py/objstrunicode.o build/py/objstringio.o build/py/objtuple.o build/py/objtype.o build/py/objzip.o bu
ild/py/opmethods.o build/py/sequence.o build/py/stream.o build/py/binary.o build/py/builtinimport.o build/py/builtinevex.o build/py/modarray.o build/py/modbuiltins.o build/py/modcollections.o build/py
/modgc.o build/py/modio.o build/py/modmath.o build/py/modcmath.o build/py/modmicropython.o build/py/modstruct.o build/py/modsys.o build/py/vm.o build/py/bc.o build/py/showbc.o build/py/repl.o build/py
/smallint.o build/py/frozenmod.o build/py/../extmod/moductypes.o build/py/../extmod/modujson.o build/py/../extmod/modure.o build/py/../extmod/moduzlib.o build/py/../extmod/moduheapq.o build/py/../extm
od/moduhashlib.o build/py/../extmod/modubinascii.o build/py/../extmod/modmachine.o build/main.o build/uart_core.o build/uart_extra.o build/stmhal/printf.o build/stmhal/pyexec.o build/lib/libc/string0.
o build/lib/mp-readline/readline.o
build/py/parse.o:parse.c:(.text+0x8b5): undefined reference to `_nlr_jump'
build/py/compile.o:compile.c:(.text+0x3e4a): undefined reference to `_nlr_jump'
build/py/parsenum.o:parsenum.c:(.text+0x34): undefined reference to `_nlr_jump'

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: MicroPython on Altera NIOS 2

Post by dhylands » Thu Jun 11, 2015 11:44 pm

You shouldn't have to remove nlrx86.o and nlrx64.o

There is a provision to use the C runtime libraries setjmp/longjmp by adding

Code: Select all

#define MICROPY_NLR_SETJMP 1
in your mpconfigport.h file.

This is what the MIPs port does. Currently there are 5 source files containing alternate implementations of nlr_setjmp_jump

nlrx86.o \
nlrx64.o \
nlrthumb.o \
nlrxtensa.o \
nlrsetjmp.o \

We normally leave all 5 in every build and the configuration flags cause the 4 versions we don't want to wind up building as empty objects and the one that we do want gets compiled/assembled.

usjcarkm
Posts: 17
Joined: Fri Jun 05, 2015 9:25 pm

Re: MicroPython on Altera NIOS 2

Post by usjcarkm » Fri Jun 12, 2015 2:50 pm

Great. Thanks.

This added param to mpconfigport.h fixed the issue:

Code: Select all

undefined reference to `_nlr_jump'

Code: Select all

#define MICROPY_NLR_SETJMP 1
However adding back in nlrx86.o and nlrx64.o here still generates the errors as shown below:

Code: Select all

# py object files
PY_O_BASENAME = \
	mpstate.o \
	nlrx86.o \
	nlrx64.o \
-

Code: Select all

$ make V=1
GEN build/genhdr/qstrdefs.generated.h
cat ../py/qstrdefs.h qstrdefsport.h | sed 's/^Q(.*)/"&"/' | gcc -E -I. -I.. -I../lib/mp-readline -I../stmhal -Ibuild -Wall -Werror -ansi -std=gnu99  -Os -DNDEBUG - | sed 's/^"\(Q(.*)\)"/\1/' > build/g
enhdr/qstrdefs.preprocessed.h
python ../py/makeqstrdata.py build/genhdr/qstrdefs.preprocessed.h > build/genhdr/qstrdefs.generated.h
python ../py/makeversionhdr.py build/genhdr/mpversion.h
mkdir -p build/
mkdir -p build/lib/libc/
mkdir -p build/lib/mp-readline/
mkdir -p build/py/
mkdir -p build/py/../extmod/
mkdir -p build/stmhal/
CC ../py/mpstate.c
gcc -I. -I.. -I../lib/mp-readline -I../stmhal -Ibuild -Wall -Werror -ansi -std=gnu99  -Os -DNDEBUG -c -MD -o build/py/mpstate.o ../py/mpstate.c
CC ../py/nlrx86.S
gcc -I. -I.. -I../lib/mp-readline -I../stmhal -Ibuild -Wall -Werror -ansi -std=gnu99  -Os -DNDEBUG -c -o build/py/nlrx86.o ../py/nlrx86.S
../py/nlrx86.S: Assembler messages:
../py/nlrx86.S:56: Warning: .type pseudo-op used outside of .def/.endef ignored.
../py/nlrx86.S:56: Error: junk at end of line, first unrecognized character is `n'
../py/nlrx86.S:73: Warning: .size pseudo-op used outside of .def/.endef ignored.
../py/nlrx86.S:73: Error: junk at end of line, first unrecognized character is `n'
../py/nlrx86.S:85: Warning: .type pseudo-op used outside of .def/.endef ignored.
../py/nlrx86.S:85: Error: junk at end of line, first unrecognized character is `n'
../py/nlrx86.S:93: Warning: .size pseudo-op used outside of .def/.endef ignored.
../py/nlrx86.S:93: Error: junk at end of line, first unrecognized character is `n'
../py/nlrx86.S:105: Warning: .type pseudo-op used outside of .def/.endef ignored.
../py/nlrx86.S:105: Error: junk at end of line, first unrecognized character is `n'
../py/nlrx86.S:130: Warning: .size pseudo-op used outside of .def/.endef ignored.
../py/nlrx86.S:130: Error: junk at end of line, first unrecognized character is `n'
make: *** [build/py/nlrx86.o] Error 1

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: MicroPython on Altera NIOS 2

Post by blmorris » Fri Jun 12, 2015 4:18 pm

My guess is that the Altera Nios assembler is expecting different syntax for the .size and .type pseudo-ops.
I'm not an expert in this, but a similar problem had to be resolved in order to get the unix port to build correctly on OSX - the very old version of the GNU assembler that ships with OSX didn't recognize all of the pseudo-ops and how they were being used; the solution was to #ifdef those ops out for OSX / Darwin.

I will say that I'm interested in seeing how this progresses; MicroPython running on a soft-IP processor on an FPGA opens up some really cool possibilities!

-Bryan

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: MicroPython on Altera NIOS 2

Post by dhylands » Fri Jun 12, 2015 5:09 pm

ok - Lets figure out what's defined for gcc. Could you provide the output of:

Code: Select all

touch empty.c
nios2-elf-gcc -E -Wp,-dM empty.c
That will let us know what all of the builtin predefined macros are for the compiler and figure out the best way to tackle this problem.

usjcarkm
Posts: 17
Joined: Fri Jun 05, 2015 9:25 pm

Re: MicroPython on Altera NIOS 2

Post by usjcarkm » Fri Jun 12, 2015 6:30 pm

Sure, here is the output after executing "touch empty.c":

Code: Select all

$ nios2-elf-gcc -E -Wp,-dM empty.c
#define __DBL_MIN_EXP__ (-1021)
#define __FLT_MIN__ 1.17549435e-38F
#define __CHAR_BIT__ 8
#define nios2_little_endian 1
#define __WCHAR_MAX__ 2147483647
#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
#define __FLT_EVAL_METHOD__ 0
#define __nios2_little_endian__ 1
#define __DBL_MIN_10_EXP__ (-307)
#define __FINITE_MATH_ONLY__ 0
#define __GNUC_PATCHLEVEL__ 2
#define __SHRT_MAX__ 32767
#define __LDBL_MAX__ 1.7976931348623157e+308L
#define __UINTMAX_TYPE__ long long unsigned int
#define __LDBL_MAX_EXP__ 1024
#define __SCHAR_MAX__ 127
#define __nios2__ 1
#define __STDC_HOSTED__ 1
#define __LDBL_HAS_INFINITY__ 1
#define NIOS2 1
#define __DBL_DIG__ 15
#define __FLT_EPSILON__ 1.19209290e-7F
#define __LDBL_MIN__ 2.2250738585072014e-308L
#define __nios2 1
#define __DECIMAL_DIG__ 17
#define __NIOS2 1
#define __LDBL_HAS_QUIET_NAN__ 1
#define __GNUC__ 4
#define __FLT_HAS_DENORM__ 1
#define __NIOS2__ 1
#define __DBL_MAX__ 1.7976931348623157e+308
#define __DBL_HAS_INFINITY__ 1
#define __LDBL_HAS_DENORM__ 1
#define __USING_SJLJ_EXCEPTIONS__ 1
#define __DBL_MAX_EXP__ 1024
#define __LONG_LONG_MAX__ 9223372036854775807LL
#define __GXX_ABI_VERSION 1002
#define __FLT_MIN_EXP__ (-125)
#define __DBL_MIN__ 2.2250738585072014e-308
#define __DBL_HAS_QUIET_NAN__ 1
#define __REGISTER_PREFIX__
#define __DBL_HAS_DENORM__ 1
#define __NO_INLINE__ 1
#define __FLT_MANT_DIG__ 24
#define __VERSION__ "4.1.2"
#define __SIZE_TYPE__ long unsigned int
#define __ELF__ 1
#define __nios2_5b__ 1
#define __FLT_RADIX__ 2
#define __LDBL_EPSILON__ 2.2204460492503131e-16L
#define nios2_5b 1
#define __USER_LABEL_PREFIX__
#define __LDBL_DIG__ 15
#define __FLT_HAS_QUIET_NAN__ 1
#define __FLT_MAX_10_EXP__ 38
#define __LONG_MAX__ 2147483647L
#define __FLT_HAS_INFINITY__ 1
#define __nios2_5b 1
#define __nios2_little_endian 1
#define __LDBL_MANT_DIG__ 53
#define __WCHAR_TYPE__ int
#define __FLT_DIG__ 6
#define __INT_MAX__ 2147483647
#define __FLT_MAX_EXP__ 128
#define __DBL_MANT_DIG__ 53
#define __WINT_TYPE__ unsigned int
#define __LDBL_MIN_EXP__ (-1021)
#define __LDBL_MAX_10_EXP__ 308
#define __DBL_EPSILON__ 2.2204460492503131e-16
#define nios2 1
#define __INTMAX_MAX__ 9223372036854775807LL
#define __FLT_DENORM_MIN__ 1.40129846e-45F
#define __FLT_MAX__ 3.40282347e+38F
#define __FLT_MIN_10_EXP__ (-37)
#define __INTMAX_TYPE__ long long int
#define __GNUC_MINOR__ 1
#define __DBL_MAX_10_EXP__ 308
#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324L
#define __STDC__ 1
#define __PTRDIFF_TYPE__ long int
#define __LDBL_MIN_10_EXP__ (-307)

Post Reply