Rebuild and test

Next we need to modify hello_world.c to call the assembly functions we created in the earlier steps:

#include <stdio.h>
#include <stdint.h>
#include "pl011_uart.h"

extern void gicInit(void);
extern uint32_t readIAR0(void);
extern void writeEOIR0(uint32_t);

extern void setTimerPeriod(uint32_t);
extern void enableTimer(void);
extern void disableTimer(void);

volatile uint32_t flag;

int main () {

	printf("hello world\n");

  flag = 0;
  setTimerPeriod(0x1000);  // Generate an interrupt in 1000 ticks

  // Wait for the interrupt to arrive

  printf("Got interrupt!\n");

	return 0;

void fiqHandler(void) {
  uint32_t intid;
  intid = readIAR0(); // Read the interrupt id

  if (intid == 29) {
    flag = 1;
  } else {
    printf("Should never reach here!\n");


Here we have defined fiqHandler() to produce the desired behavior when the interrupt is triggered.

Build and run the project using these instructions:

$ armclang -c -g --target=aarch64-arm-none-eabi startup.s
$ armclang -c -g --target=aarch64-arm-none-eabi vectors.s
$ armclang -c -g --target=aarch64-arm-none-eabi gic.s
$ armclang -c -g --target=aarch64-arm-none-eabi timer.s
$ armclang -c -g --target=aarch64-arm-none-eabi hello_world.c
$ armclang -c -g --target=aarch64-arm-none-eabi pl011_uart.c
$ armlink --scatter=scatter.txt --entry=start64 startup.o vectors.o gic.o timer.o  hello_world.o pl011_uart.o

If you include the flag -C bp.refcounter.non_arch_start_at_default=1, the system counter on the model is enabled. If you run the image now, you will see:

$ FVP_Base_Cortex-A73x2-A53x4 -C bp.refcounter.non_arch_start_at_default=1 -a __image.axf

Previous Next