A user-space program should take you a long way. But much depends on how critical the timing is in your application. If timing is critical, you might want to research real time operating systems (RTOS). There are also ways to make Linux more friendly towards real time applications. See this real time question.
If you don't have very strict timing demands, you could do something like this. This is pseudo-code, but I am vaguely thinking about Python.
while 1:
read_SPI_input()
calculate_something()
write_SPI_output()
sleep(1) #pause 1 second
A important point is that sleep() might not pause for exactly the time you specify. On unixes, sleep is typically guaranteed to pause for at least the time given. Also note that the operating system may pause the execution of your program at any point. The more loaded the system is, the more likely this is to happen.
For slightly more precision, taking into account the time spent in the reading, calculating
and writing steps:
nextTime = getCurrentTime() + 1
while 1:
read_SPI_input()
calculate_something()
write_SPI_output()
delta = nextTime - getCurrentTime()
nextTime += 1
sleep(delta) #sleep so that the loop takes 1 s in total
If delta < 0, one event has already been missed. This should be handled somehow.
Python's sleep accepts a floating point number. In C it demands an integer number of seconds. However, C has a usleep function for microseconds.
For the SPI part see here, and for GPIO, both are Python-oriented. Otherwise search this site, there have been several GPIO and SPI questions.