πŸ“œ ⬆️ ⬇️

Overview of the domestic single-board computer MB 77.07: From unpacking and firmware, to writing the first DSP program

Nowadays, the SBC (Single Board Computer) market has greatly expanded, and a huge number of single-board computers have appeared on a wide variety of processors, from old and well-known to completely new and specialized ones. Recently, Module MB 77.07 hit me β€” a single-board computer from the STC β€œModule” on a domestic-made K1879HB1Y processor, about which once from Hubre people from Promwad had already left a small note . From the moment of that post they began to sell the fee to everyone and the software was posted on the company's official github - http://github.com/RC-MODULE

The article will describe hardware and software, from unpacking and flashing, to writing a simple example - an echo audio effect on the NeuroMatrix core embedded in the DSP processor used.

Equipment


The board comes in a color branded box. Inside are:


Here you can argue whether all this is necessary or would be enough for the usual OEM delivery in the form of an antistatic bag with a fee. I think it will be useful for beginners to get a USB-UART right away, there will be less people willing to google, get the standard bad advice β€œconnect to a COM port, nothing will happen” and burn the board on the very first day after purchase.
')








Iron


Now it is worth considering the board itself. The board is ARM1176, the same core is used in the Raspberry Pi. You can run the distros sharpened under r-pi, of course, with the proviso that you need to slip the drivers for the local IP core used in the processor. To facilitate this task, the processor developer, SEC Module, provides ready-made images of Debian Jessie and Raspbian Wheezy, packages are updated periodically.

Next to K1879HB1Y itself, two 128MB DDR2 memory chips, 1GB NAND memory, 4-port USB hub, Ethernet PHY and piping are soldered.

On the pins located on both sides of the board, various external interfaces are located:

Right side:


Left side, long IDE-like connector:


Detailed pinout is available at the link: http://www.module.ru/mb7707/doc/MB77.07-X9-pinout.pdf

Consider the GPIO in more detail, since this is the very first place that you want to feel for yourself. GPIO here are two different types. The first type is those that are displayed on the comb, they are picked up by the gpio-pl061 driver (IP core ARM PrimeCell β„’ General Purpose Input / Output PL061 ). These GPIOs can pull interrupts to the ARM core, which is sometimes useful. In addition, if you do not need the Transport Stream, then its _D [0-7] pins can be multiplexed into GPIO, so you can get 16 controlled legs.

The numbering of GPIO legs in sysfs is in the documents above by reference, and if you like, you can pull them through sysfs:

#   sysfs,  ,    gpio cd /sys/class/gpio #  23-  echo 23 > export #     out echo out > gpio23/direction #    echo 1 > gpio23/value 

The second type of GPIO is more simplified, managed by another IP core, they cannot pull interrupts. Two printed LEDs are installed on these GPIOs, one of them is registered through the LED framework of the Linux kernel as heartbeat and shows the Load Average. It is useful when visually debugging to see if everything is stuck.

A separate place on the board is occupied by two pins for the boot jumper.

Downloading is done simply and securely: when there is no jumper, it is loaded from NAND memory, when the jumper is worn - the board is waiting for download via JTAG or EDCL. The jumper position is read when the board resets. It is worth telling about the last mode in more detail, since it is possible that you have not encountered it.

EDCL


EDCL or Ethernet Debug Communications Link is a hardware function, built-in Ethernet controller that allows you to write and read physical memory, sending well-formed Ethernet packets. This feature was bundled with the IP Core of the used Ethernet controller - greth. EDCL itself is quite convenient, but if you leave it enabled in production, you get a very big security hole (I wonder how many processors with the same Ethernet controller work with EDCL enabled in production?).

On top of EDCL, there is a curious edcltool tool that gives the host the edua lua API. This technology is used for anbrika and firmware boards. Edcltool itself was originally designed for Linux, in contrast to the popular manufacturers of SoCs, providing you with some livesuit / phoenixsuit or rkbatch.

There is a version for Windows, but it is experimental, assembled in haste through mingw and requires WinPCAP installation. In addition, it works quite slowly.

The Linux version is set as standard ./bootstrap && ./configure --prefix = / usr && make && sudo make install and asks only lua5.1-dev or lua5.2-dev and libelf. The latter is needed if you need to work with NeuroMatrix DSP, which will be discussed below.

The edcltool itself executes edcl scripts, which are actually ordinary lua scripts that look very simple and readable. For example, here is the script that runs the code on the bare ARM:

 fw = require("fw"); edcl_init(); fw.run_code("mboot-uemd.bin"); 

Next, here is the mboot bootloader firmware:

 fw = require("fw"); edcl_init(); fw.run_code("mboot-uemd.bin", true); -- start in slave mode fw.write_bootloader("mboot-signed.bin") 

Creating a partition table in NAND, kernel record, dtb and root filesystem:

 fw = require("fw"); edcl_init(); fw.run_code("mboot-uemd.bin",true); -- start in slave mode fw.write_bootloader("mboot-signed.bin") -- save signed loader in NAND -- all sizes are in bytes partition_table = { { "kernel", 4*1024*1024 }, { "rootfs", "-" }, } fw.partition(partition_table); -- prepare and erase all nand fw.mboot_cmd("parterase kernel y y") fw.mboot_cmd("parterase rootfs y y") fw.flash_part("kernel", "uImage", false); fw.flash_part("dtb", "mb77.07.dtb", false); fw.flash_part("rootfs", "filesystem.ubifs", false); fw.mboot_cmd("setenv bootargs console=ttyS0,38400n8 earlyprintk=serial ubi.mtd=4,2048 root=ubi0:rootfs rootfstype=ubifs"); fw.mboot_cmd("setenv bootfdt 1") fw.mboot_cmd("save"); 

This is how the launch of the code on the bare NeuroMatrix (abbreviated NMC) looks like:

 nmc = require("easynmc"); nmc.debug = true; edcl_init(); nmc.init_core("ipl-K1879-nmc-debug.abs"); entry = nmc.upload("myfile.abs"); nmc.run(entry); -- Warning: nmc stdio, arguments and return code are NOT yet supported -- when running nmc prog via edcltool. Use linux libeasynmc. -- Expect these implemented in future updates. Sorry. 

Running the scripts themselves is very simple:

 edcltool -f script.edcl -i _ 

If you forget the interface name, edcltool will use eth0 (on Windows, the 0th interface). The edcltool –l command that lists the available interfaces may be useful, especially on Windows, where it may not be very clear in the control panel which interface is registered under which system number.

In addition to the above, the bundle includes other scripts for DSP, in fact, you can not load Linux to develop DSP code. For writing your scripts in the archive with edcltool is a file SCRIPTING.TXT, which describes in detail the functions available from the edcl environment.

Firmware


Now let's talk about the main thing that is required from the processor developer after its release - support for the firmware and their delivery set. Each firmware from the official site contains a complete environment, including the bootloader, the kernel, the edcl script for the firmware, the win version just in case, and the README.

Detailed instructions on the current set of firmware is in each archive, but it makes no sense to quote it, since everything boils down to one thing:


Environment


For full-fledged work with the board, we will need an environment for building software for the board's processor and its DSP - the module provides already assembled toolchains for both Linux and Windows. Installing them is quite simple, for example, suppose that toolchains are stored in a familiar place called ~ / x-tools. Next, you need to put the downloaded toolchain from the Module there and do not forget to register the next bin in your PATH:

 export PATH=$PATH:~/x-tools/arm-module-linux-gnueabi/bin 

Distributions


The processor manufacturer adheres to minimalism when building its distributions and, by default, Debian and Raspbian come in minimal configuration with network and ssh support. X11 at 324MHz is somehow slow, plus the bootloader cannot draw anything on the screen. The main method of communication with the board is its serial console, for the sake of which the UART was installed. By default, the network is distributed by distributions from the manufacturer with the address of the board 192.168.0.7, root login, password 12345678.

Manufacturer repositories are set as follows in sources.list:

 # RC Module's repository with MB77.07 packages deb http://www.module.ru/mb7707/ stable updates 

System loading


Now a little about how the system is loaded with NAND. The first executes the IPL bootloader and checks the position of the boot jumper and:


The first boot loader is mboot. This is a u-boot fork, a bit refactored. It works from SRAM memory, which is surprisingly a lot on the processor: 4 banks, under the names IM [0-3]. Each bank is 256 kilobytes. As we found out, the purpose of each of the following:


By the way, the old version of mboot can be found in google, it lies on Sergey Mironov’s github account, a link to reduce search time: github.com/ierton/mboot , you can also find overlay for Gentoo there, but it hasn’t been updated for quite a long time so it is unlikely that he will come in handy.

The last thing to say about the bootloader is that apart from the pmgr command, there are a couple of update commands, fwupgrade and eupgrade, designed for flashing tftp images that can be larger than the size available on the DDR memory card, this also happens. Otherwise, this is the usual u-boot, to which many are accustomed. A network is available from the bootloader, working with NAND, SPI Flash (which, unfortunately, was not installed on MB77.07) and a bit of usb, without the support of file systems.

Let's go back to the memory, in the address space immediately after IM0 comes IM1, and then immediately IM3, it is worth remembering when writing low-level code that works with SRAM, as well as writing such code, it’s worth remembering that there’s really a lot of SRAM memory on some The good old AT91RM9200 on the crystal memory was only 4K. For this reason, the bootloader works here directly in SRAM, without SPL. This approach is very useful, since, unlike DDR, that ARM, that NeuroMatrix access time will be only a couple of cycles. In other words - the code from there will work very, very quickly. Moreover, if the code for the NMC will work only from IM1 / IM3, without addressing DDR in any way, it will be possible to turn some very tough realtime part on the NMC.

Next, it is worth considering NAND in more detail, it is divided into sections, the first to go boot, env and dtb. They are rigidly clogged and cannot be resized. In the first one there is a loader, in the second one its surroundings, in the third one a compiled Device Tree Blob. The rest is broken interactively by the pmgr boot command, or automatically by flashing the image from the edcl script. The boot loader sends the specified sections to the kernel by writing standard mtdparts to cmdline.

With NAND, it was generally expected to see something stunned. From my experience with linux-sunxi and linux-rockchip, NAND was both in terrible condition there. Allwinner made NAND its own block device with a partially closed FTL (flash translation layer), with its own wear-leveling and other algorithms. Rockchip generally provides NAND only in the form of a closed module rknand.ko, the source code of which is not provided even under the company's NDA, as I was told in # linux-rockhip @ freenode. Here, NAND is an ordinary standalone mtd device, on top of which the already standard UBIFS is used, which is good news.

Now about the download itself. I think many would be interested to look at the dmesg:
System loading
 MBOOT (K1879 and friends): Version mboot-00063-g9302e24-dirty (Built Thu Aug 21 17:10:13 MSK 2014) OTP info: boot_source 2 jtag_stop 0 words_len 1024 Maximum bank size: 0x10000000 bytes Detected 134217728 bytes of EM0 memory MEMORY: 40000000 -> 48000000 Memory layout 0x00100010 early 0x001001C8 text 0x0011E9BC data 0x00127D40 signature 0x00127D44 bss_start 0x00135EB4 stack_start 0x00137FF8^ stack_ptr 0x00138000 malloc 0x0017F000 env mnand_read_id: flash id 0xD3 mnand_read_id: flash ext_id 0x95 mnand_read_id: CS0 NAND 1GiB 3,3V 8-bit size(1024) writesize(2048) oobsize(64) erasesize(131072) mnand_read_id: flash id 0x00 mnand_read_id: WARNING: Unknown flash ID. Using default (0xF1) mnand_read_id: flash ext_id 0x00 mnand: Chip configurations differ, ignoring CS1 greth: Setting GRETH base addr to 0x20034000 greth: Found GRETH at 0x20034000, irq 255 greth: Resetting GRETH greth: greth: 'phyaddr' not set, fall back to built-in table greth: greth: using preset PHY addr: 1f greth: Resetting the PHY greth: write_mii: 0x20034010 < 0xF809F801 [p:31 a:0 d:0xF809] greth: write_mii: 0x20034010 < 0x0000F801 [p:31 a:0 d:0x0000] greth: 10/100 GRETH Ethermac at [0x20034000] irq 255. Running 10 Mbps half duplex PHY info not available greth: greth_init greth: greth_init: enabling receiver ETH new device: name GRETH_10/100 greth: GRETH: New MAC address: 02:00:f7:00:27:0f USB thresholds: in 0x20 out 0x7e Is there an EDCL emergency? Nope edcl: Ethernet debug disabled by environment MTD Partition: boot @ 0x00000000 size 0x00040000 MTD Partition: env @ 0x00040000 size 0x00020000 MTD Partition: dtb @ 0x00060000 size 0x00020000 MTD Partition: kernel @ 0x00080000 size 0x00400000 MTD Partition: rootfs @ 0x00480000 size 0x3FB80000 Hit any key (in 2 sec) to skip autoload... Running autoload command 'tftp;bootm;' TFTP Using GRETH_10/100 device TFTP params: server 192.168.0.1 our_ip 192.168.0.7 TFTP params: filename 'uImage-3' load_address 0x40100000 TFTP Loading: T ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################################################# ################################ TFTP done Linux preparing to boot the kernel: machid 0xcd1 Using Flatterned Device Tree boot method IMG moving image: type 2 from 0x40100040 to 0x40008000 HINT: To optimize boot time adjust loadaddr to: 0x40007fc0 Linux entry 0x40008000 USB thresholds: in 0x20 out 0x7e Uncompressing Linux... done, booting the kernel. [ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 3.10.28-shadow1-00032-gb8b1a50 (necromant@sylwer) (gcc version 4.8.1 (crosstool-NG 1.19.0) ) #141 Thu Aug 21 14:23:26 MSK 2014 [ 0.000000] CPU: ARMv6-compatible processor [410fb767] revision 7 (ARMv7), cr=00c5387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache [ 0.000000] Machine: Module MB77.07, model: Module MB77.07 [ 0.000000] bootconsole [earlycon0] enabled [ 0.000000] Memory policy: ECC disabled, Data cache writeback [ 0.000000] On node 0 totalpages: 24128 [ 0.000000] free_area_init_node: node 0, pgdat c050df84, node_mem_map c0596000 [ 0.000000] Normal zone: 288 pages used for memmap [ 0.000000] Normal zone: 0 pages reserved [ 0.000000] Normal zone: 24128 pages, LIFO batch:3 [ 0.000000] pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768 [ 0.000000] pcpu-alloc: [0] 0 [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 23840 [ 0.000000] Kernel command line: debug console=ttyS0,38400n8 earlyprintk=serial ubi.mtd=4,2048 root=ubi0:rootfs rootfstype=ubifs mtdparts=mnand:0x40000@0x0(boot),0x20000@0x40000(env),0x20000@0x60000(dtb),0x400000@0x80000(kernel),0x3FB8000) [ 0.000000] PID hash table entries: 512 (order: -1, 2048 bytes) [ 0.000000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes) [ 0.000000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes) [ 0.000000] Memory: 94MB 0MB = 94MB total [ 0.000000] Memory: 89208k/89208k available, 41864k reserved, 0K highmem [ 0.000000] Virtual kernel memory layout: [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB) [ 0.000000] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB) [ 0.000000] vmalloc : 0xc8800000 - 0xff000000 ( 872 MB) [ 0.000000] lowmem : 0xc0000000 - 0xc8000000 ( 128 MB) [ 0.000000] modules : 0xbf000000 - 0xc0000000 ( 16 MB) [ 0.000000] .text : 0xc0008000 - 0xc04af9cc (4767 kB) [ 0.000000] .init : 0xc04b0000 - 0xc04d31d4 ( 141 kB) [ 0.000000] .data : 0xc04d4000 - 0xc0515d50 ( 264 kB) [ 0.000000] .bss : 0xc0515d50 - 0xc0595990 ( 512 kB) [ 0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 [ 0.000000] NR_IRQS:128 [ 0.000000] regs = 0xf8000000, irq_start = 0 [ 0.000000] VIC @f8000000: id 0x00041192, vendor 0x41 [ 0.000000] regs = 0xf8010000, irq_start = 32 [ 0.000000] VIC @f8010000: id 0x00041192, vendor 0x41 [ 0.000000] UEMD: Firing up timer system [ 0.000000] Clocksource: rate 54000000 mult 19418074 shift 20 [ 0.000000] Clockevent: rate 54000000 mult 231928233 shift 32 [ 0.000000] sched_clock: 32 bits at 100 Hz, resolution 10000000ns, wraps every 4294967286ms [ 0.000000] Console: colour dummy device 80x30 [ 0.020000] Calibrating delay loop... 215.04 BogoMIPS (lpj=1075200) [ 0.100000] pid_max: default: 32768 minimum: 301 [ 0.110000] Mount-cache hash table entries: 512 [ 0.120000] CPU: Testing write buffer coherency: ok [ 0.130000] Setting up static identity map for 0xc03417b8 - 0xc03417f0 [ 0.150000] devtmpfs: initialized [ 0.160000] NET: Registered protocol family 16 [ 0.170000] DMA: preallocated 256 KiB pool for atomic coherent allocations [ 0.240000] OTP ROM is not flashed [ 0.250000] msvdhd: configuring memory [ 0.260000] hw-breakpoint: found 6 breakpoint and 1 watchpoint registers. [ 0.270000] hw-breakpoint: maximum watchpoint size is 4 bytes. [ 0.410000] bio: create slab <bio-0> at 0 [ 0.430000] SCSI subsystem initialized [ 0.440000] ssp-pl022 2002e000.ssp: ARM PL022 driver, device ID: 0x00041022 [ 0.450000] ssp-pl022 2002e000.ssp: BUSNO: 0 [ 0.460000] pl022: mapped registers from 0x2002e000 to f802e000 [ 0.470000] ssp-pl022 2002e000.ssp: registered master spi0 [ 0.480000] spi spi0.0: allocated memory for controller's runtime state [ 0.490000] ssp-pl022 2002e000.ssp: SSP Target Frequency is: 25000000, Effective Frequency is 13500000 [ 0.500000] ssp-pl022 2002e000.ssp: SSP cpsdvsr = 2, scr = 1 [ 0.510000] spi spi0.0: 4 <= n <=8 bits per word [ 0.520000] spi spi0.0: DMA mode NOT set in controller state [ 0.530000] spi spi0.0: setup mode 1, 8 bits/w, 25000000 Hz max --> 0 [ 0.540000] ssp-pl022 2002e000.ssp: registered child spi0.0 [ 0.550000] ssp-pl022 2002e000.ssp: probe succeeded [ 0.570000] usbcore: registered new interface driver usbfs [ 0.580000] usbcore: registered new interface driver hub [ 0.590000] usbcore: registered new device driver usb [ 0.600000] media: Linux media interface: v0.10 [ 0.610000] Linux video capture interface: v2.00 [ 0.620000] Advanced Linux Sound Architecture Driver Initialized. [ 0.630000] Switching to clocksource uemd_timer1 [ 0.730000] NET: Registered protocol family 2 [ 0.740000] TCP established hash table entries: 1024 (order: 1, 8192 bytes) [ 0.750000] TCP bind hash table entries: 1024 (order: 0, 4096 bytes) [ 0.760000] TCP: Hash tables configured (established 1024 bind 1024) [ 0.780000] TCP: reno registered [ 0.790000] UDP hash table entries: 256 (order: 0, 4096 bytes) [ 0.800000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes) [ 0.810000] NET: Registered protocol family 1 [ 0.820000] RPC: Registered named UNIX socket transport module. [ 0.830000] RPC: Registered udp transport module. [ 0.840000] RPC: Registered tcp transport module. [ 0.850000] RPC: Registered tcp NFSv4.1 backchannel transport module. [ 0.930000] squashfs: version 4.0 (2009/01/31) Phillip Lougher [ 0.950000] NFS: Registering the id_resolver key type [ 0.960000] Key type id_resolver registered [ 0.970000] Key type id_legacy registered [ 0.980000] msgmni has been set to 174 [ 1.000000] alg: No test for stdrng (krng) [ 1.010000] io scheduler noop registered (default) [ 1.020000] fj_gpio: Added 32 gpio lines at base -981095888 [ 1.040000] module_vdu 80173000.vdu: found VDU device at 80173000, id <ebebab01> [ 1.070000] Console: switching to colour frame buffer device 90x36 [ 1.090000] fb0: Module VDU frame buffer device [ 1.140000] Serial: 8250/16550 driver, 3 ports, IRQ sharing disabled [ 1.150000] 2002b000.uart: ttyS0 at MMIO 0x2002b000 (irq = 7) is a 8250 [ 1.160000] console [ttyS0] enabled, bootconsole disabled [ 1.160000] console [ttyS0] enabled, bootconsole disabled [ 1.170000] 20022000.uart: ttyS1 at MMIO 0x20022000 (irq = 9) is a 8250 [ 1.180000] 2002c000.uart: ttyS2 at MMIO 0x2002c000 (irq = 8) is a 8250 [ 1.200000] [drm] Initialized drm 1.1.0 20060810 [ 1.240000] loop: module loaded [ 1.250000] msvdhd 80180000.video_decoder: found device at 0x80180000, id 0x0025300b [ 1.300000] EasyNMC Unified DSP Framework. (c) RC Module 2014 [ 1.310000] easynmc-nmc3: imem at phys 0x140000 virt 0xc8900000 size 0x80000 bytes [ 1.320000] easynmc-nmc3: HP IRQ 14 LP IRQ 15 [ 1.330000] easynmc: registering core K1879-nmc (nmc3) with id 0 [ 1.350000] flash ext_id 0x95 [ 1.360000] mnand CS0 Samsung size(1024) writesize(2048) oobsize(64) erasesize(131072) [ 1.370000] mnand: Bad chip id or no chip at CS1 [ 1.380000] mnand: Detected 1073741824 bytes of NAND [ 1.390000] 5 cmdlinepart partitions found on MTD device mnand [ 1.400000] Creating 5 MTD partitions on "mnand": [ 1.410000] 0x000000000000-0x000000040000 : "boot" [ 1.430000] 0x000000040000-0x000000060000 : "env" [ 1.450000] 0x000000060000-0x000000080000 : "dtb" [ 1.470000] 0x000000080000-0x000000480000 : "kernel" [ 1.510000] 0x000000480000-0x000040000000 : "rootfs" [ 6.500000] libphy: greth-mdio: probed [ 9.590000] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver [ 9.600000] uemd-ehci 10040000.ehci: UEMD EHCI [ 9.610000] uemd-ehci 10040000.ehci: new USB bus registered, assigned bus number 1 [ 9.630000] uemd-ehci 10040000.ehci: irq 35, io mem 0x10040000 [ 9.660000] uemd-ehci 10040000.ehci: USB 2.0 started, EHCI 1.00 [ 9.680000] hub 1-0:1.0: USB hub found [ 9.690000] hub 1-0:1.0: 2 ports detected [ 9.700000] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver [ 9.710000] usbcore: registered new interface driver usb-storage [ 9.720000] usbcore: registered new interface driver usbserial [ 9.730000] mousedev: PS/2 mouse device common for all mice [ 9.740000] i2c /dev entries driver [ 9.770000] module_hdmi: module_hdmi: Device ID: 0x9132 [ 9.780000] usbcore: registered new interface driver i2c-tiny-usb [ 9.800000] ledtrig-cpu: registered to indicate activity on CPUs [ 9.850000] usbcore: registered new interface driver usbhid [ 9.860000] usbhid: USB HID core driver [ 9.900000] TCP: cubic registered [ 9.910000] Key type dns_resolver registered [ 9.920000] VFP support v0.3: implementor 41 architecture 1 part 20 variant b rev 5 [ 9.950000] UBI: attaching mtd4 to ubi0 [ 10.020000] usb 1-1: new high-speed USB device number 2 using uemd-ehci [ 10.180000] hub 1-1:1.0: USB hub found [ 10.190000] hub 1-1:1.0: 4 ports detected [ 25.560000] UBI: scanning is finished [ 25.640000] UBI: attached mtd4 (name "rootfs", size 1019 MiB) to ubi0 [ 25.650000] UBI: PEB size: 131072 bytes (128 KiB), LEB size: 126976 bytes [ 25.660000] UBI: min./max. I/O unit sizes: 2048/2048, sub-page size 2048 [ 25.670000] UBI: VID header offset: 2048 (aligned 2048), data offset: 4096 [ 25.680000] UBI: good PEBs: 8141, bad PEBs: 15, corrupted PEBs: 0 [ 25.690000] UBI: user volume: 1, internal volumes: 1, max. volumes count: 128 [ 25.700000] UBI: max/mean erase counter: 4/1, WL threshold: 4096, image sequence number: 23379108 [ 25.710000] UBI: available PEBs: 0, total reserved PEBs: 8141, PEBs reserved for bad PEB handling: 145 [ 25.720000] mvdu: will allocate buffers [ 25.730000] mvdu: did allocate buffers cc000000 [ 25.740000] UBI: background thread "ubi_bgt0d" started, PID 620 [ 25.750000] ALSA device list: [ 25.760000] #0: Module MB7707 [ 25.860000] UBIFS: recovery needed [ 26.940000] UBIFS: recovery deferred [ 26.950000] UBIFS: mounted UBI device 0, volume 0, name "rootfs", R/O mode [ 26.960000] UBIFS: LEB size: 126976 bytes (124 KiB), min./max. I/O unit sizes: 2048 bytes/2048 bytes [ 26.970000] UBIFS: FS size: 1013395456 bytes (966 MiB, 7981 LEBs), journal size 9023488 bytes (8 MiB, 72 LEBs) [ 26.980000] UBIFS: reserved for root: 0 bytes (0 KiB) [ 26.990000] UBIFS: media format: w4/r0 (latest is w4/r0), UUID D7B60B07-E5DE-408F-886D-5EACF67535FC, small LPT model [ 27.010000] VFS: Mounted root (ubifs filesystem) readonly on device 0:11. [ 27.020000] devtmpfs: mounted [ 27.030000] Freeing unused kernel memory: 140K (c04b0000 - c04d3000) Mount failed for selinuxfs on /sys/fs/selinux: No such file or directory INIT: version 2.88 booting [info] Using makefile-style concurrent boot in runlevel S. [info] Setting the system clock. head: cannot open '/etc/adjtime' for reading: No such file or directory hwclock: Cannot access the Hardware Clock via any known method. hwclock: Use the --debug option to see the details of our search for an access method. [....] Unable to set System Clock to: Thu Jan 1 00:00:33 UTC 1970 ... (warning). [....] Activating swap...done. [ 33.700000] UBIFS: completing deferred recovery [ 33.830000] UBIFS: background thread "ubifs_bgt0_0" started, PID 870 [ 33.850000] UBIFS: deferred recovery completed [....] Activating lvm and md swap...done. [....] Checking file systems...fsck from util-linux 2.20.1 done. [....] Cleaning up temporary files... /tmp. ok [....] Mounting local filesystems...done. [....] Activating swapfile swap...done. [....] Cleaning up temporary files.... ok [....] Setting kernel variables ...done. [....] Configuring network interfaces...done. [....] Cleaning up temporary files.... ok INIT: Entering runlevel: 2 [info] Using makefile-style concurrent boot in runlevel 2. [....] Starting OpenBSD Secure Shell server: sshd. ok Debian GNU/Linux jessie/sid shadow ttyS0 shadow login: root Password: Last login: Thu Jan 1 00:16:23 UTC 1970 from 192.168.0.1 on pts/0 Linux shadow 3.10.28-shadow1-00032-gb8b1a50 #141 Thu Aug 21 14:23:26 MSK 2014 armv6l The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. root@shadow:~# uname -a Linux shadow 3.10.28-shadow1-00032-gb8b1a50 #141 Thu Aug 21 14:23:26 MSK 2014 armv6l GNU/Linux root@shadow:~# 


The first thing that attracts attention is the line "EasyNMC DSP Framework Β© RC Module 2014". Further, the log is written, how many NMC cores are found, and based on this, we can assume that the drivers and utilities are sharpened to the fact that there will be many NMC cores. In the processor on this board, the NMC core is only one.

The next many would be interested to know how NMC interacts with Linux. The developers had the following information: to NMC from ARM there are three interruptions. Non-maskable NMI, HP (High Priority) and LP (Low Priority). In the opposite direction as HP and LP. To start the DSP core, you need to submit an initial reset and pull the NMI. This starts the IPL code NeuroMatrix. After the first run, the NMC is spinning in this initial code that handles the NMI interrupt. This start code is used to restart the application. It's pretty simple.

Time for DSP


DSP, , . nmc-utils, :


IPL NeuroMatrix, libeasynmc-nmc ( nmc ). , Free Software Foundation .

nmctl


. nmctl. , , , , .
nmctl
root@shadow:~# nmctl --help
nmctl β€” The EasyNMC control utility
Β© 2014 RC Module | Andrew 'Necromant' Andrianov <andrew@ncrmnt.org>
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
License: LGPLv2
Usage: ./nmctl [options] [actions] β€” operate on core 0 (default)
./nmctl --core=n [options] β€” operate on selected core
./nmctl --core=all [options] β€” operate all cores
Valid options are:
--core=id β€” Select a core to operate on (--core=all selects all cores)
--list β€” list available nmc cores in this system and their state
--help β€” Show this help
--force β€” Disable internal seatbelts (DANGEROUS!)
--nostdio β€” Do not auto-attach stdio
--debug β€” print lots of debugging info (nmctl)
--debug-lib β€” print lots of debugging info (libeasynmc)
Valid actions are:
--boot β€” Load initcode and boot a core (all cores)
--reset-stats β€” Reset driver statistics for core (all cores)
--load=file.abs β€” Load abs file to core internal memory
--start=file.abs β€” Load abs file to core internal memory and start it
--irq=[nmi,lp,hp] β€” Send an interrupt to NMC
--kill β€” Abort nmc program execution
--mon β€” Monitor IRQs from NMC
--dump-ldr-regs β€” Dump init code memory registers

ProTIP(tm): You can supply init code file to use via NMC_STARTUPCODE env var
When no env is set nmctl will search a set of predefined paths

, NMC :
nmctl --list
root@shadow:~# ./nmctl --list
0. name: K1879-nmc type: nmc3 (cold)
IRQs Recv: HP: 0 LP: 0
IRQs Sent: NMI: 0 HP: 0 LP: 0

nmrun


nmrun.
nmrun
root@shadow:~# ./nmrun --help
nmrun β€” The EasyNMC app runner wrapper
Β© 2014 RC Module | Andrew 'Necromant' Andrianov <andrew@ncrmnt.org>
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
License: LGPLv2
Usage: ./nmrun [options] myapp.abs [arguments] β€” operate on core 0 (default)
Valid options are:
--help β€” Show this help
--core=id β€” Select a core to operate on (Default β€” use first usused core)
--force β€” Disable internal seatbelts (DANGEROUS!)
--nostdio β€” Do not auto-attach stdio
--nosigint β€” Do not catch SIGINT
--detach β€” Run app in background (do not attach console)
Debugging options:
--debug β€” Print lots of debugging info (nmctl)
--debug-lib β€” Print lots of debugging info (libeasynmc)

DSP . .abs NMC , printf NMC stdout , , stdin – NMC. , .abs – NMC argv. Return main() NMC nmrun, return . DSP command line , DSP. , .

:

 root@shadow:~# nmrun /usr/share/examples/easynmc-0.1/arguments.abs hello world Application now started, hit CTRL+C to stop it Hello world! I am the NMC blinking ledz! I have been given 3 arguments Argument 0 is nmrun Argument 1 is hello Argument 2 is world App terminated with result 3, exiting root@shadow:~# echo $? 3 

NMC /dev/nmc0io /dev/nmc0mem, :


– ioctl, , libeasynmc.

, LGPLv2. , API. , API node.js? , DSP epoll/select stdio, NMC (, NMI ) poll/epoll. , libevent, libuv ..

Action


, , - NMC. , MB77.07 Raspbian, .

nmc-utils.

 git clone github.com/RC-MODULE/nmc-utils.git cd nmc-utils 

github:


- :

 GNU_TARGET_NAME=arm-module-linux-gnueabihf make 

(nmctl, mnrun) :

 GNU_TARGET_NAME=arm-module-linux-gnueabihf make STATIC=y 

NFS - , :

 DESTDIR=/srv/rootfs/mb7707/ make install 

, , .deb based , deb-:

 GNU_TARGET_NAME=arm-module-linux-gnueabihf ARCH=armhf make deb 

deb dpkg-deb deb-, : armhf Raspbian, armel Debian. :


, .

NMC , NMC . pipeline:
 arecord | nmrun ./echo.abs | aplay 

arecord DSP, , aplay. USB , . libeasynmc , nmrun.

, . stdin/stdout , . , ARM , NMC , , , ARM. , , SRAM . , , stdio libeasynmc.

C/++ NeuroMatrix , , DSP , . , :


C. NMC 8-, DSP 32- .
, hello world :


Makefile. - . , – EASYNMC_DIR, libeasynmc-nmc NMC libeasynmc. - , libs.

Makefile
 # # This is a basic Makefile template for a Neuromatrix DSP project # to be run on Module MB77.07. To compile it you need: # * Latest NMSDK installed with utilities in your $PATH # * NEURO environment variable pointing to NMSDK directory # * Host GCC (Since nmcpp doesn't support generating deps, # we use gcc for that) # # For verbose build run 'make VERBOSE=y' # -include colorizer.mk -include *.dep .SUFFIXES: OBJECTS := \ main.o \ easyconf.o TARGET=helloworld # Set this to libeasynmc-nmc dir. Relative or absolute. # Make sure you build it prior to building the actual project. EASYNMC_DIR = ../../libeasynmc-nmc CROSS_COMPILE = NMCPP_FLAGS = -DNEURO -OPT2 -inline -I$(EASYNMC_DIR)/include ASM_FLAGS = -soc -Sc -Stmp -Xq -I$(EASYNMC_DIR)/include C2ASM_FLAGS = -soc -q #BIG FAT WARNING: easynmc.lib MUST go BEFORE libc #BIG FAT WARNING: Otherwise argc/argv won't work LIBS = easynmc.lib libc05.lib BUILDER_FLAGS = -cK1879.cfg -m -heap=0 -heap1=0 -heap2=0 -heap3=0 -stack=20000 \ -full_names IDIRS = -I. -I"$(NEURO)/include" LIBDIR = -l"$(NEURO)/lib" -l"$(EASYNMC_DIR)" .DEFAULT_GOAL=all all: $(TARGET).abs %.asmx: %.cpp $(SILENT_DEP)gcc -E -MM $(<) -o$(@).dep $(SILENT_NMCPP)$(CROSS_COMPILE)nmcpp -Tp $(NMCPP_FLAGS) $(<) -O$(@) $(IDIRS) %.asmx: %.c $(SILENT_DEP)gcc -E -MM $(<) -o$(@).dep $(SILENT_NMCPP)$(CROSS_COMPILE)nmcpp -Tc99 $(NMCPP_FLAGS) $(<) -O$(@) $(IDIRS) %.o: %.asmx $(SILENT_ASM)$(CROSS_COMPILE)asm $(C2ASM_FLAGS) $(<) -o$(@) %.o: %.asm $(SILENT_DEP)gcc -E -MM -xassembler-with-cpp $(<) -o$(@).dep $(SILENT_ASM)$(CROSS_COMPILE)nmcc $(ASM_FLAGS) $(<) -o$(@) $(TARGET).lib: $(OBJECTS) -$(SILENT_LIBRARIAN)$(CROSS_COMPILE)libr -c $(@) $(^) > /dev/null $(TARGET).abs: $(OBJECTS) -$(SILENT_LINKER)$(CROSS_COMPILE)linker $(BUILDER_FLAGS) -o$(@) $(^) $(LIBS) $(LIBDIR) $(TARGET).dump: $(TARGET).abs -$(SILENT_NMDUMP)$(CROSS_COMPILE)nmdump -f $(^) > $(@) run: $(TARGET).abs edcltool -f run_nmc_code.edcl -i eth1 clean: -$(SILENT_CLEAN)rm -f *.asmx; rm -f *.o; rm -f $(TARGET).abs $(TARGET).dump *.dep \ *.ac *.map *~ *.abs *.lib 


easynmc.lib – stdin/stdout, argc/argv , , C.

– mb7707brd.cfg, NeuroMatrix , gcc LD . . :
.cfg
 MEMORY { //-------------- NMC --------------------------------------- LOADERMEM: at 0x00000000, len = 0x00000200; IM1: at 0x00000200, len = 0x0000fe00; IM3: at 0x00010000, len = 0x00010000; //------------- ARM ---------------------------------------- INTERNAL_MEMORY0: at 0x00040000, len = 0x00010000; // 256K-IM0 ARM (ARM:0x00100000 0x0013ffff 0x4000(256kB)) INTERNAL_MEMORY2: at 0x20040000, len = 0x00010000; // 256K-IM2 ARM (ARM:0x80100000 0x8013ffff 0x4000(256kB)) //------------- DDR ---------------------------------------- EXTERNAL_MEMORY0: at 0x10000000, len = 0x10000000; // 16MB-EM0-DDR (ARM:0x40000000 0x7fffffff) EXTERNAL_MEMORY1: at 0x30000000, len = 0x10000000; // 16MB-EM1-DDR (ARM:0xc0000000 0xffffffff) } SEGMENTS { code : in IM3; data : in IM1; } SECTIONS { .text : in code; .init : in code; .fini : in code; .data : in code; .bss : in code; .stack : in code; .heap : in code; .heap1 : in code; .heap2 : in code; .heap3 : in code; } 


memory map – http://www.module.ru/mb7707/doc/K1879-memory-map.pdf

make – hello.abs hello.dump. abs – ELF NMC. IM1 IM3, Linux , Linux, edcl , . dump – , , NMC.

, – easyconf.asm. , . easyconf stdio , :
.asm
 import from "easynmc/easynmc.mlb"; /* Declare 2 circular buffers for stdio */ const EASYNMC_IOBUFLEN = 128; EASYNMC_CBUF(".easynmc_stdin", _easynmc_stdin_hdr, _easynmc_stdin_data, EASYNMC_IOBUFLEN); EASYNMC_CBUF(".easynmc_stdout", _easynmc_stdout_hdr, _easynmc_stdout_data, EASYNMC_IOBUFLEN); /* Reserve 128 32-bit words for arguments */ EASYNMC_ARGS(128); 


abs , , stdio 128 , . nmrun , 128 – nmrun .

, main.c, :
main.c
 #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <easynmc/easynmc.h> int main(int argc, char** argv) { printf("Hello world from NeuroMatrix! I am the NMC printf'ing to you!\n"); return 0; } 


hello world, . , - 200, 1600 . 2048. NMC ( float'), , .

- :
main.c
 #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <easynmc/easynmc.h> #define SIZE 2048 static unsigned int delaybuf[SIZE]; static unsigned int pos; int main() { while(1) { unsigned int in = getc(); unsigned int out = in + (delaybuf[pos] >> 2); if (out >255) out = 255; delaybuf[pos++] = in; pos &= (SIZE -1); putc(out); } } 


, abs . ALSA – HDMI. / USB . ALSA, , -L arecord aplay. :

 arecord -D default:CARD=Device | nmrun echo.abs | aplay -D default:CARD=Device 

, DSP .

Conclusion


, . . MB77.07 , , , ARM. :

+ , , IPL DSP . github . Freescale Qualcomm (Code Aurora). GPL source-drop rar tar' ftp , – . , , .git .

+ DSP , . , , K&R. , NMC realtime – .

+ . , , Allwinner (libnand), Rockchip (rk_fb, rknand), Mediatek ( ) . . , mainline. .

+ . 3.10 LTS, LTS. , linux-sunxi – 3.4, upstream . Rockchip 3.10.x rk3288. rk3188 – MMC . HardKernel ODROID 3.8.y linux-stable + ubuntu merge, mainline.

+ . NAND , MB77.07 EDCL. , , , , .. . NAND RK3188 .

+ deb-, . , .

+ , , r-pi.

β€” . , , (pun intended)

β€” RTC. , . ntp.

β€” . , 324MHz ARM1176 . , ARM, NMC , , . OpenSource , .

β€” . , . «» qiwi.

Links


Source: https://habr.com/ru/post/234541/


All Articles