
An earlier blog post showed multi-threading on the TI MSP432. Recently I have been working on an STM32L031 Nucleo board with the Keil ARM-MDK environment. I wanted to demonstrate multi-threading and so ported the code from the MSP432 to the L031. A section of the main.c file looks like this:
#define STACK_SIZE 128
__attribute__((noreturn)) void threadA(void);
__attribute__((noreturn)) void threadB(void);
__attribute__((noreturn)) void threadC(void);
static uint32_t StackA[STACK_SIZE];
static uint32_t StackB[STACK_SIZE];
static uint32_t StackC[STACK_SIZE];
void threadA()
{
while (1)
{
static int State = 0;
if (State == 0)
{
GPIOA->ODR &=~(1u << 0);
State = 1;
}
else
{
GPIOA->ODR |= (1 << 0);
State = 0;
}
delay(100000);
}
}
int main()
{
// Initialize I/O ports
RCC->IOPENR = 1; // Enable GPIOA
pinMode(GPIOA,0,1); // Make GPIOA Bit 0 an output
pinMode(GPIOA,1,1); // Make GPIOA Bit 1 an output
pinMode(GPIOA,2,1); // Make GPIOA Bit 2 an output
initClock(); // Set the MCU running at 16MHz
createThread(threadA,StackA, STACK_SIZE);
createThread(threadB,StackB, STACK_SIZE);
createThread(threadC,StackC, STACK_SIZE);
startSwitcher();
}
Three threads are created in this example and they each change the state of a bit on Port A. I should have used the BSRR register to set and clear the bits but for the purposes of getting the ideas behind multi-threading across this was sufficient. The createThread function takes three arguments: The thread’s start address, a pointer to the thread’s stack and the size of this stack. Stacks for the threads are simply declared as arrays of uint32_t’s.
The startSwitcher function starts the SysTick timer running, does some stack adjustments and enables interrupts. It does not return. The SysTick handler is written in assembler and it performs the context switch between threads.
Source code is available on github. I did not include the project (uvproj) files as they contain lots of path information that would not transfer to other systems. If you want to try this for yourself just create a project for the STM32L031 Nucleo in Keil and add the files from github. You should first remove the other source files in your project.