4

I want to write a bit-banging driver for a Raspberry Pi 3. For testing I developed a simple Linux kernel mode driver which toggles a GPIO pin with approx. 1Mhz. Here is the code excerpt.

static ssize_t dev_write(struct file *filep, const char *buffer, size_t len, loff_t *offset)
...
volatile int k;

spin_lock_irqsave(&my_lock, flags);
// also disable FIQ  
asm volatile ("mrs %0, cpsr":  "=r" (mycpsr):);
asm volatile ("msr cpsr, %0":  : "r" (mycpsr | 0x000000C0));

while(1)
{
   iowrite32(32, (u8*)gpio+0x200000+0x1c);
   for(k=0;k< 100;k++);
   iowrite32(32, (u8*)gpio+0x200000+0x28);
   for(k=0;k< 100;k++);
}

...

In order to get no interference by the Linux kernel, I disabled IRQ and FIQ before entering the toggling loop. I have also set CPU speed fix to 1.2Ghz. Then I monitor the GPIO pin with a scope. If I trigger the scope by pulse-width > 2, I can see gaps of different length, which sometimes last longer than 5 us (seems to depend on load for the other cores)

On a Rasperry Pi Zero no such effect occurs. The signal is total clean and stays at a stable frequency.

As I have disabled all interrupts, my Linux driver is running like a bare-metal OS. So I assume that the delays must be a pure hardware effect (e.g. cache misses ?).

Can anyone explain me how the hardware is causing such long delays?

  • 1
    We would need to see the code to usefully comment. The bare metal forum at raspberrypi.org/forums is possibly a more appropriate site. – joan Sep 7 '18 at 20:16
  • Are you using a Real Time Linux Kernel? – earthmeLon Dec 6 '18 at 18:10
  • No, but I disabled all IRQs in a kernel module. That gives far better real time behaviour than any real time kernel can provide. Meanwhile I think the delays result from ARM AHB bus multiplexing. – Rainer Urian Dec 7 '18 at 19:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.