Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: ELEC350-Practicals-FZ429
Fork of Task617Solution-mbedos-FZ429 by
Revision 8:ad00c9036add, committed 2017-11-09
- Comitter:
- noutram
- Date:
- Thu Nov 09 14:43:39 2017 +0000
- Parent:
- 7:bd75e7717b58
- Commit message:
- Demonstration of a spin lock
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ELEC350-Practicals-FZ429.lib Thu Nov 09 14:43:39 2017 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/teams/University-of-Plymouth-Stage-2-and-3/code/ELEC350-Practicals-FZ429/#6f9f2e93a0be
--- a/main.cpp Tue Oct 31 15:40:25 2017 +0000
+++ b/main.cpp Thu Nov 09 14:43:39 2017 +0000
@@ -1,84 +1,117 @@
#include "mbed.h"
-#include "rtos.h"
#include "string.h"
#include <stdio.h>
#include <ctype.h>
+#include "sample_hardware.hpp"
-#define DELAY 200
+
+#define RED_DONE 1
+#define YELLOW_DONE 2
+
-DigitalOut onBoardLED(LED1);
-DigitalOut redLED(PE_15);
-DigitalOut yellowLED(PB_10);
-DigitalOut greenLED(PB_11);
+//Function declarations
+void countUP();
+void countDOWN();
+extern "C" void spinlock(volatile int *arg);
+extern "C" void spinunlock(volatile int *arg);
-DigitalIn onBoardSwitch(USER_BUTTON);
-DigitalIn SW1(PE_12);
-DigitalIn SW2(PE_14);
+//MUTEX Lock
+Mutex countLock;
+volatile int _spinLock = 1;
//Thread ID for the Main function (CMSIS API)
osThreadId tidMain;
-//Thread sychronisation primatives
-Mutex lock1;
-Mutex lock2;
-unsigned long sw1Count = 0;
-unsigned long sw2Count = 0;
+//Stared mutable state
+volatile int count = 0;
-void thread1()
+// *************************************************************
+// * TRY THIS WITH AND WITHOUT UNCOMMENTING THE FOLLOWING LINE *
+// * Note the speed difference for this particular case.
+// *************************************************************
+
+//#define SPIN
+
+void inline increment()
{
- printf("Entering thread 1\n");
- while (true) {
- yellowLED = 1;
-
- //Start critical section
- lock1.lock();
-
- sw1Count++;
- printf("\nCount1 = %lu", sw1Count);
-
- Thread::wait(1); //1ms
-
- //End critical section
- lock1.unlock();
-
- if (SW1 == 1) {
- lock2.lock();
- sw2Count--;
- lock2.unlock();
- }
-
- yellowLED = 0;
- Thread::wait(DELAY);
- }
+ //**** Take lock ****
+ #ifdef SPIN
+ spinlock(&_spinLock);
+ #else
+ countLock.lock();
+ #endif
+
+ count++;
+
+ //**** Release lock ****
+ #ifdef SPIN
+ spinunlock(&_spinLock);
+ #else
+ countLock.unlock();
+ #endif
}
-void thread2()
+
+
+void inline decrement()
+{
+ //**** Take lock ****
+ #ifdef SPIN
+ spinlock(&_spinLock);
+ #else
+ countLock.lock();
+ #endif
+
+ count--;
+
+ //**** Release lock ****
+ #ifdef SPIN
+ spinunlock(&_spinLock);
+ #else
+ countLock.unlock();
+ #endif
+}
+//Threads
+void countUP()
{
- printf("Entering thread 2\n");
- while (true) {
- redLED = 1;
-
- //Start critical section
- lock2.lock();
-
- sw2Count++;
- printf("\nCount2 = %lu", sw2Count);
-
- Thread::wait(1); //1ms
+ redLED = 1;
+
+ for (unsigned int n=0; n<100000; n++) {
+ increment();
+ increment();
+ increment();
+ increment();
+ increment();
+ increment();
+ increment();
+ increment();
+ increment();
+ increment();
+ }
+
+ redLED = 0;
+ osSignalSet(tidMain, RED_DONE); //Signal main thread we are done
+}
+
+void countDOWN()
+{
+ yellowLED = 1;
+
+ for (unsigned int n=0; n<100000; n++) {
+ decrement();
+ decrement();
+ decrement();
+ decrement();
+ decrement();
+ decrement();
+ decrement();
+ decrement();
+ decrement();
+ decrement();
+ }
- //End critical section
- lock2.unlock();
-
- if (SW2 == 1) {
- lock1.lock();
- sw1Count--;
- lock1.unlock();
- }
-
- redLED = 0;
- Thread::wait(DELAY);
-
- }
+ yellowLED = 0;
+ osSignalSet(tidMain, YELLOW_DONE); //Signal main thread we are done
}
@@ -86,22 +119,36 @@
int main() {
redLED = 0;
yellowLED = 0;
- greenLED = 0;
-
- //Main thread ID
- tidMain = Thread::gettid();
+ greenLED = 1;
//Threads
- Thread t1, t2;
+ Thread t1;
+ Thread t2;
+ tidMain = Thread::gettid();
- t1.start(thread1);
- t2.start(thread2);
-
- printf("Main Thread\n");
- while (true) {
- Thread::wait(osWaitForever);
+ //Press the switch to run concurrently
+ if (onBoardSwitch == 1) {
+ printf("Running sequntially\n");
+ countUP();
+ countDOWN();
+ } else {
+ printf("Running concurrently\n");
+ t1.start(countUP);
+ t2.start(countDOWN);
+
+ //Wait for the ALL_ON signal
+ Thread::signal_wait(RED_DONE,osWaitForever);
+ Thread::signal_wait(YELLOW_DONE,osWaitForever);
}
+ printf("Final result = %d\n", count);
+ if (count == 0) {
+ greenLED = 0;
+ }
+
+ while(true);
}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/myasm.s Thu Nov 09 14:43:39 2017 +0000 @@ -0,0 +1,29 @@ + AREA asm_func, CODE, READONLY +; Export my_asm function location so that C compiler can find it and link + EXPORT myasm +myasm + + ; Write assmebler here + MOV R1, #0x20000000 + BX R1 ; THIS IS BAD + BX LR + + EXPORT spinlock +spinlock + LDREX R1,[R0] ;Read counter + SUBS R1, #1 ;Subtract 1 + ITT PL ;IF True True >= 0 + STREXPL R2,R1,[R0] ;TRY UPDATE + CMPPL R2,#0 ;SUCCEED? + BNE spinlock + BX LR + + EXPORT spinunlock +spinunlock + LDREX R1,[R0] + ADD R1,#1 + STREX R2,R1,[R0] + CMP R2,#0 + BNE spinunlock + BX LR + END \ No newline at end of file
