Grumpy Mike wrote: firstname.lastname@example.org wrote:
Dave_G_2 wrote:@Grumpy Mike
GrumpyMikes code is poking the 1st register directly with a mask of 0x3e6cf93 which (assuming he's set all the output), will affect 15 of all the 17 usable bits in it. Re-coding in assembler might save a cycle or 2, but not 10mS.
No it affects all 17 usable pins not just 15 of them. Count the number of ones in 0x3e6cf93. I was also verifying the pinout of the header. This seems to have been screwed up by software types who don't know which end of a soldering iron is hot.
From what I gather, it was laid out by a hardware engineer and one of the cost issues was - time vs. number of layers on the PCB - to get the routing from the BGA chip to the header (and to everything else). So AIUI, going from a 6 layer board to 8 layers plus the time would have pushed the price way over the target. So it's somewhat sub-optimal, but it's usable.
Grumpy Mike wrote:
I am not interested in the speed, the least significant bit goes at 4.2MHz so there is little point in trying to poke the registers with assembler.
Yes there are other glitches as well as the massive 10mS one, some at 2mS and others around 5mS. It is just that I was not expecting such a massive glitch.
Grumpy Mike wrote:
dom wrote:You could try playing with nice.
Thanks I will try that when I get on to my real application.
I do not think you will ever get round things like this under Linux... Well, unles you go to the troubles of porting/adapting one of the real-time kernel variants and even then there are going to be other issues. Simply put you can not use a general purpose pre-emptive, multi-tasking, multi-user operating system from timing critical things like this.
However, you can improve things slightly using the sched_setscheduler(2) system call. (probably with a schedulling priority set to 10 and the SCHED_RR parameter) but that's only part of it - you may also want to look at mlock(2) to make sure your process never gets swapped out, however even with the real-time schedulling, it's still scedulling - your process will be de-schedulled when Linux needs to do someting else - for exameple background activity - network - any broadcast on your LAN will generate an interrupt (and your Pi needs to generate at least one of these every 30 seconds to process ARP requests to maintain the default gateway - and if it's a busy LAN, especially with Microsoft PCs broadbasing for domain controllers, etc. then there can easilly be more than one broadcast a second), then there's other more hidden things - cron jobs, log-file writes, (change the syslog config to not use fsync) and so on.
Probably far easier to use something more suited to this level of real-time control in the first place - e.g. an attached arduino/GertBoard an so on.. Do higher level control from the Pi and get a separate IO board to do more timing critical stuff.
The Pi is great for doing introductory stuff - lights, switches, simple sensors - and talking to more advanced sensors, etc. via the I2C and SPI, but proper "hard" real-time control? I really have my doubts as I suspect the first person to try to drive a stepper motor smoothly will find out.