Jump to content

ChrisK

Members
  • Posts

    21
  • Joined

  • Last visited

Everything posted by ChrisK

  1. That's just way too overgeneralized. Of course it is possible to speed up boot time, use a custom kernel and custom u-boot, while staying compatible to the "distro", which is merely the whole userspace stuff. Customizing a u-boot build, with ethernet and USB disabled will save the init tme for that. Removing the wait-time for user input gives another few seconds to save. Just because a system has some init system installed by default doesn't mean one has to use it. One can always tell the kernel what to use as init (PID 1). That can be the required app, or a shell, or some rudimentary script to start some networking, damons and then an app. One just has to be mindfull of what stuff needs to be started/required. Simply saying that nothing is compatible is rather silly and counterproductive. Greeting, Chris
  2. The isolcpus belongs into the bootargs in boot.cmd. For example, this will reserve core number 4: setenv bootargs console=ttyS0,115200 noinitrd root=/dev/mmcblk0p2 rootfstype=ext4 rootwait isolcpus=3 This will reserve cores 3 and 4: setenv bootargs console=ttyS0,115200 noinitrd root=/dev/mmcblk0p2 rootfstype=ext4 rootwait isolcpus=2,3 This will reserve cores 2 to 4: setenv bootargs console=ttyS0,115200 noinitrd root=/dev/mmcblk0p2 rootfstype=ext4 rootwait isolcpus=1-3 The isolcpus argument starts counting cores at 0. Keep in mind that the above are just examples, you may have the root file system elsewhere, for example. It is also possible to assign IRQ's to specific cores using the /proc/irq/... stuff, but i haven't tried that on the H3 yet, since in my own code i set the cpu affinity directly. That _may_ help a bit with latency for the audio i/o through the underlying driver stack, by assigning the irq of the audio hardware to a specific core as well. However, i don't know much about the way audio hardware is handled on the H3. If you want to get really nasty, i made a patch to the sunxi legacy kernel a while back, that allows a specific IRQ to be handled as fast as possibly, by bypassing a bunch of code in the Linux IRQ handler code. But that isn't for the faint of heart and may cause nasty side-effects. Greetings, Chris
  3. Funny, it looks exactly like the FriendlyArm NanoPi M1. Down to the silkscreen, even! The only change seems to be the removal of the FA label, and placing the pcDuino label there instead on the silkscreen.
  4. You can try to reserve one of the cores to the audio process(es). First you isolate a core by using the kernel parameter (boot argument) "isolcpus=...", and then you can use taskset to place threads/threads onto that core. In addition you should then also set a higher priority for those processes/threads. That way you have a complete core only for the audio processing, which should help a bit. Greetings, Chris
  5. It can, it uses GPIOG12 as the OTG-ID input. That is true for the NanoPi Neo as well as the NanoPi M1. It's right there in the schematic... Greetings, Chris
  6. What does the syslog/dmesg say? Does the ethernet disconnect and reconnect often? Here's the thing with chinese vendors: They like to cut corners wherever they can. This doesn't mean that the OPi folks want it that way, it could easily be their own supplier. Cheap chinese power supplies are known for being of lousy quality (frankly, i personally wouldn't leave them plugged in unattended). Those QC stickers, if there are any, are just decoration. I think it would be at least worth try, don't you think? Use the charger plug from your phone, assuming that is of a decent quality, and see what happens then. Greetings, Chris
  7. Ha, it seems that the BananaPI M2+ _does_ have the SPDIF output. I just checked the datasheet: https://drive.google.com/drive/folders/0B4PAo2nW2KfnflVqbjJGTFlFTTd1b1o1OUxDNk5ackVDM0RNUjBpZ0FQU19SbDk1MngzZWM?tid=0B4PAo2nW2Kfndjh6SW9MS2xKSWs. I was checking it because i was wondering why the heck they would use a PA pin on the cam header, whereas the NanoPI's just use all the PE signals, since PE has everything that is needed for the camera (it's the cam interface, after all). Turns out they made a a rather nasty typo. Check page 2, upper-left. In the chip symbol itself you see PA17/SPDIF_OUT/PA_EINT17, over the signal line they put the label "SPDIF_OUT", but they named the signal itself "PA16", probably by mistake. On page 9 then you see that signal PA16 ends up on pin 37 of the expansion header. So, according to the schematic the SPDIF output on the BananaPi M2+ is on pin 37 of that header, mislabelled as PA16. Greetings, Chris
  8. That's not possible. The OWA interface (which is what they call SPDIF in the Allwinner datasheet) can only use PA17, there is no other routing/multiplexing option. The same holds true for any other hardware peripherial of the chip. Check chapter 3.7 of the datasheet, "GPIO Multiplexing Functions". And if you do direct register access to set up pin functions, check chapter 4.22/4.23 to see what register settings are required to chose what pin is selected for which function/peripherial. The case of 1-Wire sensors etc. is different, since that is implemented in software (the H3 does not have a 1-Wire peripherial), and thus can be placed on any generic GPIO pin. Greetings, Chris
  9. Check the output of dmesg repeatedly. If you see a lot of ETH disconnects/connects, it is possible that your power supply is the issue. I had such an effect on a NanoPI M1, getting a lot of dis-/reconnects (and sometimes just settling at 10MBit after a while). The problem was the power supply, which simply wasn't stable enough. Used a different one (the charger of my Samsung phone), and the problem went away instantly. BTW, power supply quality also plays a big role in the stability in general. With a bad supply i can freeze my boards reliably when starting "stress -c 4 -i 4". Sometimes almost immediately, sometimes after a few seconds, but it always happens. Especially those cheap chinese supplies and cables are usually of really bad quality, causing all sorts of problems. Greetings, Chris
  10. Hi Igor, what exactly is the issue with the 39-112 patch? The overlay-patch (02-0003-linux-sunxi-3.4.108-overlayfs.patch) is included in that one. I have tested it here, and so far it works. Let me know what the issue is, the i can re-crete it and possibly fix the large patch. Greetings, Chris
  11. Hi, my current project is about using a NanoPI M1 as a controller for a 3D printer. As such, one wants to have very tight timing on the GPIO output, with as little jitter as possible, to get smooth motion of the stepper motors. However, it is common belief that getting a fast timing with little jitter is virtually impossible to do under linux, without the help of a dedicated chip just for the IO. While that is true in general on stock kernels, it's possible to vastly improve on that front by spending a little effort. One way on ARM chips is to use the FIQ. That is an interrupt that has the highest priority, which can interrupt all other, regular interrupts. However, modern chips use a GIC for interrupt control instead of a VIC, so adding a FIQ is not that easy. There are patches out there to do just that, but then, those are for newer kernels, and not the old 3.4.xxx, which is somewhat of the standard kernel for the time beeing. So, what to do? Well, diving into the kernel sources and do some nasty hacking, of course! To give a quick overview of how an interrupt is usually handled on our ARM platform: 1: IRQ happens, the IRQ controller notifies the CPU about that 2: A small assembly stub is invoked, which then jumps into a small routine, asm_do_IRQ() 3: That small routine calls another routine, handle_IRQ() 4: That in turn calls generic_handle_irq() 5: Which then calls handle_fasteoi_irq(), by using a pointer to that in the IRQ descriptor 6: Subsequently, handle_irq_event() is called 7: And since we are on a SMP machine, that in turn calls handle_irq_event_percpu() 8: And finally, that calls action->handler(), the _actual_ interrupt routine! Now, not only is that a long way to go, but in many of those functions a lot of other functions are called, many of which are by themselves interruptible/preemptible. No surprise then that there is little chance to get a tight timing... Now, this is where my nasty hack come in. Step 2 of the above list is preserved as it is, but in step 3, that is, in handle_IRQ(), i added some code. That code checks if the requested IRQ is one to quickly handle, and if it is, basically calls the real IRQ handler directly. This leads to _great_ improvements, as you can see in the following images. All scope images are with 10 second persistency turned on, so that glitches become visible. First, this is how it would normally look, without any patches at all. It is supposed to be a ~40kHz square wave: Basically just a blur. OK, most of that is because the interrupt runs on core 0, which is used by other stuff as well. I made a patch to have an IRQ attached to a specific core or cores (see this thread: http://forum.armbian.com/index.php/topic/1885-rt-patches-for-sun8i-kernel/). Once the kernel has that patch applied, and the boot-arg isolcpus=3 is given, only the first 3 cores are used by the kernel, leaving the fourth one free. Attaching the used timer-IRQ to that core gives this result: Much better, but still a lot of jitter. Now, this is where the quickirq patch comes in. Applying that patch results in this: Now, that is already a _lot_ better. Is there still room for improvement? Yes, by applying the RT patch. Which gives the final result: In all the scope shots the board was running at 624MHz RAM, 1200MHz core, while in the background "stress -c 4 -i 4" was active, resulting in a cpu load of roundabout 9 according to top. Now, let's be clear: Using the quickirq patch is not for the faint of heart. One has to know exactly what she/he is doing, otherwise the kernel will very likely lock up. There are noc checks, no nothing, it assumes that the handler itself is set up and registered correctly. And that no other interrupt handler wants to attach itself (or is already attached) to that interrupt number. Also, it is no hard realtime. While the outcome is vastly improved, there still is the occasional jitter. However, it is quite good enough to control stepper motors within reasonable limits. Since my aim is tu use the nanoPI M1 to directly control stepper motors, it should be noted that a frequency of 40kHz would, if we assume 100 steps/mm, result in a speed of 400mm/s, or 40cm/s! More reasonable speeds of 200 or 300mm/s mean that any jitter that happens is less pronounced, relative to the pulse width itself. The patch also include a sample driver which will output a square wave on PA0. In the kernel menuconfig, under Device Drivers -> quickirq you can enable/disable the quickirq handling, define up to 3 interrupt numbers to handle through that patch, as well as enable the sample driver. The sample driver uses TMR1 of the H3, which is otherwise completely unused. TMR1 has interrupt number 51. The driver uses PA0, but it accesses the port registers directly. So if you have any other stuff that toggles GPIO pins on PORTA, that will interfere with the output of the sample driver. So, if you want to test it and look at the output on a scope, it's best to disable anything else on PORTA (like the heartbeat LED, for example). If the sample driver is loaded (either directly compiled into the kernel, or as a module and the "modprobe -i quickirq"), it creates a device node at /dev/quickirq. You can echo characters into that to control it: echo 0 > /dev/quickirq -> disable the timer echo 1 > /dev/quickirq -> enable the timer (squarewave appears on PA0) Sending it the numbers 2, 3, 4, 5, 6 and 7 changes the output frequency to (about) 10Hz, 100Hz, 1kHz, 10kHz, 20kHz and 40kHz repsectively. Sending it + or - will adjust the raw timer reload value in 1-increments, q and w in 10-increments, e and r in 100 increments. The shorter the intervall time gets (the higher the frequency), you will notice that there is a base overhead that can't be avoided. Like, the timer reload value for the 40kHz setting is half of that for the 20kHz setting, but the output is slightly less than double. It's just a crude example, after all. All that said, here is the patch: 0000-add-quickirq.patch.gz Have fun with it, hopefully it is useful for others as well. But keep in mind that this is a rather rude brute-force method. You _really_ have to know what you are doing! Greetings, Chris EDIT: Re-uploaded the patch
  12. Just to make sure the edit isn't overlooked: There was a bug in the full RT patch in the post above. Fixed it, and replaced the file in the previous post. Greetings, Chris
  13. Hi, Igor asked me if i could consolidate the RT patches into a single one, and only doing the extra patches seperately, so here they are. First, i added the fix for firmware_class.c in the 02-0005-backport-firmware-loader.patch, because that is what introduces the issue in the first place. So, that patch can be replaced by this file: 02-0005-backport-firmware-loader.patch.gz Then i took the liberty to consolidate all the patches that brings the kernel from 2.4.39 to 2.4.112 into a single one. I did so by first disabling all the patches from 02-0001-patch... down to z-0003... (leaving those before 02-0001 enabled), having the compile script apply the patches. Then i saved the kernel source tree, enabled these 39-112 patches: and ran compile.sh again to have all those applied. Then i saved that source tree, and made single patch file. This one brings the kernel from 2.4.39 up to 2.4.112 in one patch: 02-0001-patch-3.4.39-112.patch.gz That means that in the lib/patch/kernel/sun8i-default directory all the patches in the above list can be removed and the single patch file be used instead. Here is the consolidated RT patch, which now includes the RT itself plus the fixes for it: 0000-rt143-full-plus-rt-fixes.patch.gz So all that is left is the patch for those who want to have irq_set_affinity_hin() work properly. I leave that one extra, because for one it doesn't change anything to the way the kernel operates and sets up IRQ's by default, and it also doesn't have anything to do with the RT patches as such. So, this applies opnly for those who write their own drivers (or want to modify existing ones) that use interrupts, and want to tie said IRQ's to a specific core (or cores): 0001-make-irq-set-affinity-hint-work-properly.patch.gz Greetings, Chris EDIT: There was a bug in the full RT patch. Fixed it, and replaced the file in this post!
  14. Hi, and here is another patch that should be added if the RT patch is applied. This one fixes BUG's that are triggered when using the interactive cpufreq governor. The probelm is that spin_lock_irqsave and spin_lock_irqrestore are used there, which leads to: BUG: scheduling while atomic: swapper/0/0/0x00000002 This patch makes it use the raw_ versions of those in case the PREEMPT_RT_FULL patch is applied. I wasn't aware of the issue until now, since i usually use the "userpsace" governor. Greetings, Chris 0006-cpufreq_interactive-spin_lock_for_rt.patch.gz
  15. Hi, attached is a patch for U-Boot (should work on 2016.09-rc1 and 2016-09-rc2-dirty, will probably work on older ones as well) that makes it use the plain text file uEnv.txt instead of boot.scr, which has to be translated to a binary file first. This way changing the environment means only editing a text file, instead of editing a file, converting it to binary, and copying it over to the /boot partition on the SD. This becomes active if the U-Boot config has the option OLD_SUNXI_COMPAT disabled (in the menuconfig this is under ARM architecture -> Enable workarounds for booting old kernels). It also adds a small patch to board/sunxi/board.c to skip the setting of the MAC address if the option CONFIG_CMD_NET is disabled. That way it is possible to leave out networking stuff and save some time at boot because it doesn't init the networking stuff. Personally i prefer a boot that is as quick as possible, because i just hate it to wait for no useful reason On my board it basically just falls through to immediately boot the kernel after power-up, because i have the wait time for user-input disabled as well in the config. As an example, this is what my uEnv.txt looks like, i have reserved a core and incresed the loglevel: machid=1029 bootm_boot_mode=sec bootargs=console=ttyS0,115200 noinitrd root=/dev/mmcblk0p2 rootfstype=ext4 rootwait loglevel=7 isolcpus=3 bootcmd=load mmc 0 0x43000000 script.bin; load mmc 0 0x40008000 uImage; bootm 0x40008000 Greetings, Chris 0000-use-uEnv.txt-by-default-on-sunxi.patch.gz
  16. The other patches don't break or modify the default behaviour of the kernel. However, you should also disable 0003 if 0001 is not used. That one only fixes an issue that shows up when the RT patches are applied, and will fail if they are not applied first. 0000 is a general fix for an issue that exists in the 3.4.112 armbian kernel, 0002 just excludes SUNXI SS if highmem is not enabled, 0004 and 0005 are just additions to the IRQ handling/config that does not affect regular operation, but is handy to have in case one wants/needs these functionalities in their own drivers. Greetings, Chris
  17. That reminds me, i forgot to include another patch. That one makes irq_set_affinity_hint() work properly. The interrupt controller allows IRQ's to be tied to specific cores, by setting the cpu affinity of the IRQ. While irq_set_affinity_hint() is already there and exported, it fails to actually put the IRQ on the selected CPU(s). It can be quite useful to be able to tie an IRQ to a specific CPU/core, especially in conjunction with the RT patches. You can, for example, simply exclude one core from being used by the kernel, using the isolcpus= boot arg for the kernel. Like, isolcpus=3 will exclude the fourth core from being used by the kernel. If you then install your interrupt and call irq_set_affinity_hint(IRQNUM, cpumask_of(3)) (with IRQNUM being the number of the IRQ in question), that IRQ will then handled exclusively on the fourth core. This greatly reduces latency and jitter. Greetings, Chris 0005-make-irq-set-affinity-hint-work-properly.patch.gz
  18. It should be noted, however, that such thick SILPADS are quite bad when it comes to thermal resistance. While in some cases using such a thick pad and some metal may be better than nothing at all, it is better to avoid them and find a better solution. Using thermal pads or paste or glue is mainly to bridge air gaps due to imperfect surfaces. That stuff isn't really that thermally conductive at all, it just happens to be better than air. The general rule is that such layers should be as thins possible. Using a small 14x14x10mm heatsink, attached with thermal glue, is very likely to be far better than a 4mm SILPAD and a big piece of metal. Nice, suitable heatsinks for the H3 would be these: http://www.ebay.de/itm/172290970476. Add a very small dab of heat conductive glue, for example http://www.ebay.de/itm/181026615992, then put on the heatsink, align it and finally press it down _really_ good (most of the glue should squeeze out on the sides). Let it sit for a while until it's cured, done. Greetings, Chris
  19. Hi, first of all, thanks for moving this part into a separate thread. Attached is .tar.gz with the patches. While the RT patches themselves are in a single patch file, there are 4 more patches. I created them by first running the compile.sh script. I selected the legacy kernel, and Nanopi M1, then had it unpack the kernel patch it and then compile it. Once that was done i copied over the sources/linux-sun8i/sun8i dierectory to apply the patches. In fact i copied it twice, to be able to get a patchset consistin of single patch files for the RT stuff as well. I then fixed up a few other issues /thus the extra patches), and added a patch to allow setting priority levels on IRQ's. After all that i copied the clean sun8i directory again and applied the just created patches, to verify the result applies cleanly to the 3.4.112 sunxi kernel in Armbian. Which they do. The patches are as follows: 0000-... : The lib/patch/kernel/sun8i-default/02-0005... patch has a small bug. The patched result makes use of kobj_to_dev(), but it can't find that because genhd.h is missing from the includes in firmware_class.c. This patch fixes that. 0001-... : The full preempt_rt patch. Most of the patches of the original rt143 apply just fine. A few have only line offsets, even fewer have failed hunks or errors. The latter ones are where i manually added the rejected parts into their proper places. 0002-... : Afte the RT patches are applied, when one want to use PREEMPT_RT_FULL, the use of highmem is no longer possible (in the 2.6 kernel patches it is possible again, though...). The SUNXI SS hardware crypto driver makes use of kmap/kunmap, which are provided by highmem functions. This patch disables that driver if no CONFIG_HIGHMEM is possible. No idea in what places the SUNXI SS is used anyways. By default it builds as a module, and i never saw it loaded. 0003-... : There is a small bug in the RT patches in rimerfd.c, where in one places it tries to access ctx->tmr, whereas it should be ctx->t.tmr. This patch fixes that. 0004-... : This adds the ability to set priorities for IRQ's on the GIC. Normally all IRQ's have the same priority, 0xa0. This patch allows three levels, and high priority can be selected for an IRQ by adding IRQF_HIGH_PRIORITY to its flags. About the issue with no highmem available when PREEMPT_RT_FULL is used, i will dive into that once i have more time. Maybe i can backport some stuff from newer RT patches, who knows. Other than that the kernel runs fine, at least i didn't encounter any issues yet. As usual, the RT patches add two extra choices to Kernel Features -> Preemption Model, Preemtible Kernel (Basic RT) and Fully Preemptible Kernel (RT). Also as usual, using those patches makes the kernel slightly less performant when it comes to things like raw I/O stuff. It simply improves the response time to events, decreases latency, etc., which is very useful in certain applications. Anyways, i hope that this is helpful for you folks. Greetings, Chris patches.tar.gz
  20. Hello, thnaks for the welcome. Yea, i wasn't sure wether to open a new thread or just add to this. If this isn't the right pülace, maybe a mod can move these parts to a new thread? Or i open a new one? The method i used for patching the original kernel was indeed time consuming, but i did it that way on purpose. Great way to get a rough idea of what changed, plus, my last kernel hacking was way over 10 years ago, so it was also a great way to get back into that stuff. Also, i learned about Armbian only later, when it was already "too late", so to say. I guess i could try to create a diff between the Armbian kernel and the rt kernel. After all, the only difference between the two now should be just the rt patches (unless i somehow forgot to apply one/some of the Armbian patches from lib/patch/kernel for the 3.4.112 version). Alternatively i could apply the rt patches to the "final" Armbian kernel, manually adding the failed hunks (as i did with my version of it). Now that i know what to look for that should be done rather quickly. What kind of patch-set would you guys prefer? The way i applied the rt stuff was by using the patch-set patches-3.4.112-rt143.tar.gz, instead of the single big patch file. So there are two options, i can either create basically the same patch set, just for the Armbian kernel, or make a single big rt patch that could be optionally applied to it after all the other patches from Armbian have been applied. Regarding the Armbian build script, for what i am doing right now it is rather bulky. I'm writing a kernel driver/module, so all i ever need is to recompile that, copy over the uImage, and boot it. Building a whole new image all the time is just too much. So, let me know how you guys would prefer the rt patch, small patches or a single big patch, and i try to get it done by the weekend. Greetings, Chris
  21. Hello everyone, since i couldn't find a section for the NanoPi Neo/M1 (or maybe i just overlooked it), and the OrangePi One is rather close to it anyways, i'll post it here. Would there be interrest in a 3.4.112 kernel tree with the preempt_rt patches (rt143) added? I got myself said NanoPi's some days ago, and started to patch my way up from the original sunxi kernel 3.4.39 to the 3.4.112 version, then added the preempt_rt patches, and finally added (most?) patches from the Armbian build. Obviously manually adding the rejects. I'm also having a U-Boot 2016.09-rc1 that i have slightly patched to have it use uEnv.txt instead of boot.scr, because i got too annoyed to edit a text file, then male a binary version of it... So far the kernel seems to wok fine, although i have only tested it with the stuff i need for my project (a controller for 3D printing). I needed the preempt_rt patches to get some half-decent chance to actually control steppers directly from Linux (i'm writing my own driver for that currently), since there is no usable FIQ support in the 3.4 kernel (and all the patches to add such a thing are usually for newer kernels), but they also generally improve the responsiveness of the system. So it may be useful for others as well. I'm rather new to Github (and git in general), will create an account there soon and hopefully get the source trees checked in there. This is a bottlog, from power up until the point systemd is started. U-Boot basically falls through (i have network and USB disabled in my own U-Boot config) and almost immediately loads the kernel. So, if there is interrest i will let you know once i got it stuffed onto Github. In case anyone wants it before that i can just bzip it up and put it on my server. Greetings, Chris
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines