From 707313cfd90fdb1b594416c07dc81bc9959991e1 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 5 Feb 2023 01:04:13 +0100 Subject: [PATCH 01/29] finish part1 step1 --- Makefile | 7 ++- application.c | 121 +++++++++++++++++++++++++++++++++++++++++++------- semaphore.c | 41 +++++++++++++++++ semaphore.h | 28 ++++++++++++ 4 files changed, 179 insertions(+), 18 deletions(-) create mode 100644 semaphore.c create mode 100644 semaphore.h diff --git a/Makefile b/Makefile index e374748..946b40b 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,8 @@ OBJECTS= $(DEBUGDIR)dispatch.o \ $(DEBUGDIR)stm32f4xx_tim.o \ $(DEBUGDIR)stm32f4xx_usart.o \ $(DEBUGDIR)startup.o \ - $(DEBUGDIR)application.o + $(DEBUGDIR)application.o \ + $(DEBUGDIR)semaphore.o ### ### Main target @@ -100,9 +101,11 @@ $(DEBUGDIR)canTinyTimber.o: canTinyTimber.c canTinyTimber.h $(CC) -c $< -o $@ $(CCFLAGS) $(DEBUGDIR)sciTinyTimber.o: sciTinyTimber.c sciTinyTimber.h $(CC) -c $< -o $@ $(CCFLAGS) +$(DEBUGDIR)semaphore.o: semaphore.c semaphore.h + $(CC) -c $< -o $@ $(CCFLAGS) # User-defined targets -$(DEBUGDIR)application.o: application.c TinyTimber.h sciTinyTimber.h canTinyTimber.h +$(DEBUGDIR)application.o: application.c TinyTimber.h sciTinyTimber.h canTinyTimber.h semaphore.h $(CC) -c $< -o $@ $(CCFLAGS) ### diff --git a/application.c b/application.c index a0aa821..8e46c1e 100644 --- a/application.c +++ b/application.c @@ -3,6 +3,9 @@ #include "canTinyTimber.h" #include #include +#include +#include "semaphore.h" // semaphore + typedef struct { Object super; @@ -10,15 +13,33 @@ typedef struct { char c; } App; -App app = { initObject(), 0, 'X' }; +typedef struct { + Object super; + CallBlock callBlock; + int period; + bool lh; // 1 or 0 + int volume; + int mute; +} ToneGenerator; + +int* dac = (int *)0x4000741C; + + void reader(App*, int); void receiver(App*, int); +void tick(ToneGenerator*, int); +void upVolume(ToneGenerator*, int); +void downVolume(ToneGenerator*, int); +void mute(ToneGenerator*, int); +App app = { initObject(), 0, 'X' }; Serial sci0 = initSerial(SCI_PORT0, &app, reader); - +Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); +ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, 0}; // 500 USEC +// app void receiver(App *self, int unused) { CANMsg msg; CAN_RECEIVE(&can0, &msg); @@ -27,33 +48,101 @@ void receiver(App *self, int unused) { } void reader(App *self, int c) { + SCI_WRITE(&sci0, "Rcv: \'"); SCI_WRITECHAR(&sci0, c); SCI_WRITE(&sci0, "\'\n"); + switch (c) + { + case 30: //up + tg.callBlock.obj = &tg; + tg.callBlock.meth = upVolume; + ASYNC(&muteVolumeSem, Wait, (int)&tg.callBlock); + break; + case 31: //down + tg.callBlock.obj = &tg; + tg.callBlock.meth = downVolume; + ASYNC(&muteVolumeSem, Wait, (int)&tg.callBlock); + + break; + case 'M': // mute/unmute + if (!tg.mute) // mute need go with lock + { + tg.callBlock.obj = &tg; + tg.callBlock.meth = mute; + ASYNC(&muteVolumeSem, Wait, (int)&tg.callBlock); + break; + } + ASYNC(&tg, mute, 0); // ummute with no lock + break; + default: + break; + } } void startApp(App *self, int arg) { - CANMsg msg; - CAN_INIT(&can0); - SCI_INIT(&sci0); + SCI_INIT(&sci0); // ? SCI_WRITE(&sci0, "Hello, hello...\n"); + tick(&tg, 0); - msg.msgId = 1; - msg.nodeId = 1; - msg.length = 6; - msg.buff[0] = 'H'; - msg.buff[1] = 'e'; - msg.buff[2] = 'l'; - msg.buff[3] = 'l'; - msg.buff[4] = 'o'; - msg.buff[5] = 0; - CAN_SEND(&can0, &msg); + } +// tone generator +void tick(ToneGenerator *self, int c) { + if (self->lh) + { + *dac = self->volume; + self->lh = false; + } else { + *dac = 0; + self->lh = true; + } + AFTER(USEC(self->period/2), self, tick, c); + +} + +void upVolume(ToneGenerator *self, int c) { + char tempBuffer[50]; + if (self->volume < 25) + { + self->volume++; + } + sprintf(tempBuffer, "volume: %d\n", self->volume); + SCI_WRITE(&sci0, tempBuffer); + ASYNC(&muteVolumeSem, Signal, 0); +} + +void downVolume(ToneGenerator *self, int c) { + char tempBuffer[50]; + if (self->volume > 1) + { + self->volume--; + } + sprintf(tempBuffer, "volume: %d\n", self->volume); + SCI_WRITE(&sci0, tempBuffer); + ASYNC(&muteVolumeSem, Signal, 0); +} + +void mute(ToneGenerator *self, int c) { + if(!self->mute) { + self->mute = self->volume; + self->volume = 0; + SCI_WRITE(&sci0, "muted\n"); + } else { + self->volume = self->mute; + self->mute = 0; + SCI_WRITE(&sci0, "unmuted\n"); + ASYNC(&muteVolumeSem, Signal, 0); // realse lock + } + +} + + int main() { INSTALL(&sci0, sci_interrupt, SCI_IRQ0); - INSTALL(&can0, can_interrupt, CAN_IRQ0); + TINYTIMBER(&app, startApp, 0); return 0; } diff --git a/semaphore.c b/semaphore.c new file mode 100644 index 0000000..cad0a79 --- /dev/null +++ b/semaphore.c @@ -0,0 +1,41 @@ +#include "TinyTimber.h" +#include "semaphore.h" + +void c_enqueue(Caller c, Caller *queue) { + Caller prev = NULL, q = *queue; + while (q) { // find last element in queue + prev = q; + q = q->next; + } + if (prev == NULL) + *queue = c; // empty queue: put ‘c’ first + else + prev->next = c; // non-empty queue: put ‘c’ last + c->next = NULL; +} + +Caller c_dequeue(Caller *queue) { + Caller c = *queue; + if (c) + *queue = c->next; // remove first element in queue + return c; +} + +void Wait(Semaphore *self, int c) { + Caller wakeup = (Caller) c; // type-cast back from ‘int’ + if (self->value > 0) { + self->value--; + ASYNC(wakeup->obj, wakeup->meth, 0); + } + else + c_enqueue(wakeup, &self->queue); +} + +void Signal(Semaphore *self, int unused) { + if (self->queue) { + Caller wakeup = c_dequeue(&self->queue); + ASYNC(wakeup->obj, wakeup->meth, 0); + } + else + self->value++; +} diff --git a/semaphore.h b/semaphore.h new file mode 100644 index 0000000..c547f8b --- /dev/null +++ b/semaphore.h @@ -0,0 +1,28 @@ +#ifndef _SEMAPHORE_H +#define _SEMAPHORE_H + +#include "TinyTimber.h" + +struct call_block; +typedef struct call_block *Caller; + +typedef struct call_block { + Caller next; // for use in linked lists + Object *obj; + Method meth; +} CallBlock; + +#define initCallBlock() { 0, 0, 0 } + +typedef struct { + Object super; + int value; + Caller queue; +} Semaphore; + +void Wait(Semaphore*, int); +void Signal(Semaphore*, int); + +#define initSemaphore(n) { initObject(), n, 0 } + +#endif From f1dfa3a3da97c0178fa0b877bc3acd892211f7a0 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 5 Feb 2023 15:02:38 +0100 Subject: [PATCH 02/29] part1 step2 --- application.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/application.c b/application.c index 8e46c1e..69ad617 100644 --- a/application.c +++ b/application.c @@ -22,22 +22,34 @@ typedef struct { int mute; } ToneGenerator; +typedef struct { // step 2 + Object super; + int background_loop_range; + +} Loader; + int* dac = (int *)0x4000741C; void reader(App*, int); void receiver(App*, int); + void tick(ToneGenerator*, int); void upVolume(ToneGenerator*, int); void downVolume(ToneGenerator*, int); void mute(ToneGenerator*, int); +void backgroundLoop(Loader*, int); +void increaseLoad(Loader*, int); +void decreaseLoad(Loader*, int); + App app = { initObject(), 0, 'X' }; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, 0}; // 500 USEC +Loader ld = {initObject(), 1000}; // app void receiver(App *self, int unused) { @@ -64,6 +76,12 @@ void reader(App *self, int c) { tg.callBlock.meth = downVolume; ASYNC(&muteVolumeSem, Wait, (int)&tg.callBlock); + break; + case 28: // decrease process load + ASYNC(&ld, decreaseLoad, 0); + break; + case 29: // increase process load + ASYNC(&ld, increaseLoad, 0); break; case 'M': // mute/unmute if (!tg.mute) // mute need go with lock @@ -85,6 +103,7 @@ void startApp(App *self, int arg) { SCI_INIT(&sci0); // ? SCI_WRITE(&sci0, "Hello, hello...\n"); tick(&tg, 0); + backgroundLoop(&ld, 0); } @@ -139,10 +158,36 @@ void mute(ToneGenerator *self, int c) { } +// loader +void backgroundLoop(Loader* self, int c) { + for (size_t i = 0; i < self->background_loop_range; i++) + { + + } + + AFTER(0, self, backgroundLoop, c); +} + +void increaseLoad(Loader* self, int c) { + char tempBuffer[50]; + self->background_loop_range += 500; + sprintf(tempBuffer, "background loop range: %d\n", self->background_loop_range); + SCI_WRITE(&sci0, tempBuffer); +} + +void decreaseLoad(Loader* self, int c) { + char tempBuffer[50]; + if (self->background_loop_range > 500) + { + self->background_loop_range -= 500; + } + sprintf(tempBuffer, "background loop range: %d\n", self->background_loop_range); + SCI_WRITE(&sci0, tempBuffer); + +} int main() { INSTALL(&sci0, sci_interrupt, SCI_IRQ0); - TINYTIMBER(&app, startApp, 0); return 0; } From 09a4c07ed7f5fc1ad6cfe1c70e20e3bae0710dab Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 5 Feb 2023 16:03:03 +0100 Subject: [PATCH 03/29] part1 step3 phase1 --- application.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/application.c b/application.c index 69ad617..9050504 100644 --- a/application.c +++ b/application.c @@ -118,7 +118,7 @@ void tick(ToneGenerator *self, int c) { *dac = 0; self->lh = true; } - AFTER(USEC(self->period/2), self, tick, c); + SEND(USEC(self->period/2), USEC(100), self, tick, c); // step 2 } @@ -165,7 +165,7 @@ void backgroundLoop(Loader* self, int c) { } - AFTER(0, self, backgroundLoop, c); + SEND(USEC(1300),USEC(1300), self, backgroundLoop, c); // step 2 } void increaseLoad(Loader* self, int c) { @@ -177,7 +177,7 @@ void increaseLoad(Loader* self, int c) { void decreaseLoad(Loader* self, int c) { char tempBuffer[50]; - if (self->background_loop_range > 500) + if (self->background_loop_range > 0) { self->background_loop_range -= 500; } From 7172aa1ca0f9fd961b3ce23a862f573c5c93149b Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 5 Feb 2023 16:18:51 +0100 Subject: [PATCH 04/29] part1 s1 s2 s3 done --- application.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/application.c b/application.c index 9050504..648a77f 100644 --- a/application.c +++ b/application.c @@ -20,12 +20,13 @@ typedef struct { bool lh; // 1 or 0 int volume; int mute; + Time deadline; } ToneGenerator; typedef struct { // step 2 Object super; int background_loop_range; - + Time deadline; } Loader; int* dac = (int *)0x4000741C; @@ -39,17 +40,19 @@ void tick(ToneGenerator*, int); void upVolume(ToneGenerator*, int); void downVolume(ToneGenerator*, int); void mute(ToneGenerator*, int); +void enableDeadlineTG(ToneGenerator*, int); void backgroundLoop(Loader*, int); void increaseLoad(Loader*, int); void decreaseLoad(Loader*, int); +void enableDeadlineLD(Loader*, int); App app = { initObject(), 0, 'X' }; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); -ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, 0}; // 500 USEC -Loader ld = {initObject(), 1000}; +ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, 0, USEC(100)}; // 500 USEC +Loader ld = {initObject(), 1000, USEC(1300)}; // app void receiver(App *self, int unused) { @@ -93,6 +96,11 @@ void reader(App *self, int c) { } ASYNC(&tg, mute, 0); // ummute with no lock break; + case 'D': // deadline enable/disable + ASYNC(&tg, enableDeadlineTG, 0); + ASYNC(&ld, enableDeadlineLD, 0); + break; + default: break; } @@ -118,7 +126,7 @@ void tick(ToneGenerator *self, int c) { *dac = 0; self->lh = true; } - SEND(USEC(self->period/2), USEC(100), self, tick, c); // step 2 + SEND(USEC(self->period/2), self->deadline, self, tick, c); // step 2 } @@ -158,6 +166,18 @@ void mute(ToneGenerator *self, int c) { } +void enableDeadlineTG(ToneGenerator *self, int c) { + if (self->deadline == 0) + { + self->deadline = USEC(100); + SCI_WRITE(&sci0, "enable deadline\n"); + } else { + self->deadline = 0; + SCI_WRITE(&sci0, "disable deadline\n"); + } + +} + // loader void backgroundLoop(Loader* self, int c) { for (size_t i = 0; i < self->background_loop_range; i++) @@ -165,7 +185,7 @@ void backgroundLoop(Loader* self, int c) { } - SEND(USEC(1300),USEC(1300), self, backgroundLoop, c); // step 2 + SEND(USEC(1300),self->deadline, self, backgroundLoop, c); // step 2 } void increaseLoad(Loader* self, int c) { @@ -186,6 +206,15 @@ void decreaseLoad(Loader* self, int c) { } +void enableDeadlineLD(Loader *self, int c) { + if (self->deadline == 0) + { + self->deadline = USEC(1300); + } else { + self->deadline = 0; + } +} + int main() { INSTALL(&sci0, sci_interrupt, SCI_IRQ0); TINYTIMBER(&app, startApp, 0); From 4092335170b66f99fab70bbd6db09c885cad3df7 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Wed, 8 Feb 2023 18:40:46 +0100 Subject: [PATCH 05/29] 2.8 --- .application.c.swp | Bin 12288 -> 0 bytes Debug/RTS-Lab.elf | Bin 203748 -> 216348 bytes Debug/RTS-Lab.map | 604 +++++++++++++++++++++++++++++++-------- Debug/RTS-Lab.s19 | 622 +++++++++++++++++++++++++++++------------ Debug/application.o | Bin 13584 -> 18492 bytes Debug/semaphore.o | Bin 0 -> 4628 bytes RTS-Lab.code-workspace | 16 ++ application.c | 4 +- 8 files changed, 962 insertions(+), 284 deletions(-) delete mode 100644 .application.c.swp create mode 100644 Debug/semaphore.o create mode 100644 RTS-Lab.code-workspace diff --git a/.application.c.swp b/.application.c.swp deleted file mode 100644 index 099c73e499f5e61b59460ead696c5bb69f06ec64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2y>HV%7>5sr^8Fz|VqoYIq$WinOS08&US)sUu;nDSMG9Q%?OTqpRWQiTc| z;$voof&Ty&m{^dQnAl(i!2o{%h=JePahjwQ23U|@OHXXSzI*Sz=gvcv)UvbcG(VD= zU^uojHnjb%F+8`K?OM-RQ7M&V_)kYssh-wm&K#IMHC3!Ar&n!$OC}sE3h%n#YL8X4 z>VcA88`Ilu+cI?DYB?EW)xPwA43L4pHL!(EPK;+|mVJr6eCLjHf18l{lL0b72FL&z zAOmE843Ggb@E;lQ+iTcu)VsD*bFOn@`{Qdv)Hpbq7r{EEI0PcfD&;S=e2`HclI2Z=&z}KyeeE~1P zb8rvb1v)qjCc!%JX$xZ?!3XdPJOOt=6V!nKc`y#LU=J7q?>95{4!j1>z+-S1+yIwA z0i?lh@B{Pu4!(ge;3aqnTwnq@ZynG<2FL&zAOmE843GgbKnDJefhERqxWW%yhi7x) zou-yAYU=b!rIH%K|6kMG^L5wH%d6~Yj%`rORV`mCrA7?h$)-6zuUd{TTsLU@Xe zud0=^vZYMjZR{Bq8soFKakZevjgf-S>z0!mXNytO1T&hH8SrtI(c!GsRi}= z>$l0H-sG5=*iR>h%gl)IdyeUtaOlHnWbfz1MDyv%5vJ(tdhe5d#2!>e^ zo%R|WgXP#l%QCymm%-4yO%0mko!j~8v#F$%gPCyC8#2x~!@M|mtudZ{P{MV*D&Xp{EroE3gL z309OBIDse3utqtSOoa8c9LvXTN)B>nrlMg}M{h}-My^9uxR!3q-5z&|A}MKkpqDfw z`*cKwlL>3tA1>2Mh21!l3yL=sRox8hnyFnAhMyY6i<;)i3rW6&yh|L-qD^Qtb(b5_ zwcG(lD{%biHtNc~pe@`S^B3E~6m@JJH!ytpLhiF1!wyWrk9odnwKB~U{UO_`^~Dm< YrCH9RX3f`xn`tJNn-m( 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
KgJi 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 LU97!6N*VFLFfIgL delta 41223 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 K(5BfNLD?Vo!UPxq diff --git a/Debug/RTS-Lab.map b/Debug/RTS-Lab.map index 7ee31e2..919c66e 100644 --- a/Debug/RTS-Lab.map +++ b/Debug/RTS-Lab.map @@ -1,15 +1,65 @@ +Archive member included to satisfy reference by file (symbol) + +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) + Debug/application.o (sprintf) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) (_impure_ptr) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) (_svfprintf_r) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) (_printf_i) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memchr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) (memchr) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memcpy-stub.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) (memcpy) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memmove.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) (memmove) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) (_free_r) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) (_malloc_r) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) (_realloc_r) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sbrkr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) (_sbrk_r) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) (__malloc_lock) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-msizer.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) (_malloc_usable_size_r) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sbrkr.o) (errno) +c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) (__retarget_lock_acquire_recursive) Allocating common symbols Common symbol size file +__lock___atexit_recursive_mutex + 0x1 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__lock___arc4random_mutex + 0x1 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +errno 0x4 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) otable 0xc Debug/TinyTimber.o upcoming 0x4 Debug/TinyTimber.o threads 0x50 Debug/TinyTimber.o +__lock___env_recursive_mutex + 0x1 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__lock___sinit_recursive_mutex + 0x1 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) mtable 0xc Debug/TinyTimber.o +__lock___malloc_recursive_mutex + 0x1 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) thread0 0x14 Debug/TinyTimber.o messages 0x2d0 Debug/TinyTimber.o __heap_end 0x4 Debug/TinyTimber.o +__lock___at_quick_exit_mutex + 0x1 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) stacks 0x8000 Debug/TinyTimber.o +__lock___dd_hash_mutex + 0x1 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__lock___tz_mutex 0x1 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__lock___sfp_recursive_mutex + 0x1 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) Memory Configuration @@ -33,6 +83,7 @@ LOAD Debug/stm32f4xx_tim.o LOAD Debug/stm32f4xx_usart.o LOAD Debug/startup.o LOAD Debug/application.o +LOAD Debug/semaphore.o LOAD c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libstdc++_nano.a LOAD c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libm.a START GROUP @@ -44,7 +95,7 @@ LOAD c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/thumb/v LOAD c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a END GROUP -.text 0x20000000 0x6d70 +.text 0x20000000 0x7e20 0x20000000 . = ALIGN (0x4) *(.start_section) .start_section @@ -344,107 +395,290 @@ END GROUP 0x200066b6 USART_GetITStatus 0x2000676c USART_ClearITPendingBit .text 0x200067a8 0x32c Debug/startup.o - .text 0x20006ad4 0x158 Debug/application.o + .text 0x20006ad4 0x548 Debug/application.o 0x20006ad4 receiver 0x20006b24 reader - 0x20006b6c startApp - 0x20006bec main + 0x20006c98 startApp + 0x20006ce8 tick + 0x20006d50 upVolume + 0x20006db8 downVolume + 0x20006e20 mute + 0x20006e98 enableDeadlineTG + 0x20006ee8 backgroundLoop + 0x20006f28 increaseLoad + 0x20006f70 decreaseLoad + 0x20006fc0 enableDeadlineLD + 0x20006fec main + .text 0x2000701c 0x106 Debug/semaphore.o + 0x2000701c c_enqueue + 0x20007068 c_dequeue + 0x20007092 Wait + 0x200070dc Signal + .text 0x20007122 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) + .text 0x20007122 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) + .text 0x20007122 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) + .text 0x20007122 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) + *fill* 0x20007122 0xe + .text 0x20007130 0xa0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memchr.o) + 0x20007130 memchr + .text 0x200071d0 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memcpy-stub.o) + .text 0x200071d0 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memmove.o) + .text 0x200071d0 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) + .text 0x200071d0 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + .text 0x200071d0 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) + .text 0x200071d0 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sbrkr.o) + .text 0x200071d0 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) + .text 0x200071d0 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-msizer.o) + .text 0x200071d0 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + .text 0x200071d0 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) *(.text.*) + .text._sprintf_r + 0x200071d0 0x38 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) + 0x200071d0 _sprintf_r + 0x200071d0 _siprintf_r + .text.sprintf 0x20007208 0x40 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) + 0x20007208 siprintf + 0x20007208 sprintf + .text.__ssputs_r + 0x20007248 0xb6 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) + 0x20007248 __ssputs_r + .text.__ssprint_r + 0x200072fe 0xf6 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) + 0x200072fe __ssprint_r + .text._svfprintf_r + 0x200073f4 0x200 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) + 0x200073f4 _svfiprintf_r + 0x200073f4 _svfprintf_r + .text._printf_common + 0x200075f4 0xda c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) + 0x200075f4 _printf_common + *fill* 0x200076ce 0x2 + .text._printf_i + 0x200076d0 0x24c c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) + 0x200076d0 _printf_i + .text.memcpy 0x2000791c 0x1c c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memcpy-stub.o) + 0x2000791c memcpy + .text.memmove 0x20007938 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memmove.o) + 0x20007938 memmove + .text._free_r 0x2000796c 0xa0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) + 0x2000796c _free_r + .text._malloc_r + 0x20007a0c 0xb4 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + 0x20007a0c _malloc_r + .text._realloc_r + 0x20007ac0 0x4c c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) + 0x20007ac0 _realloc_r + .text._sbrk_r 0x20007b0c 0x20 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sbrkr.o) + 0x20007b0c _sbrk_r + .text.__malloc_lock + 0x20007b2c 0xc c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) + 0x20007b2c __malloc_lock + .text.__malloc_unlock + 0x20007b38 0xc c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) + 0x20007b38 __malloc_unlock + .text._malloc_usable_size_r + 0x20007b44 0x10 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-msizer.o) + 0x20007b44 _malloc_usable_size_r + .text.cleanup_glue + 0x20007b54 0x1a c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + 0x20007b54 cleanup_glue + *fill* 0x20007b6e 0x2 + .text._reclaim_reent + 0x20007b70 0xb8 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + 0x20007b70 _reclaim_reent + .text.__retarget_lock_init + 0x20007c28 0x2 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + 0x20007c28 __retarget_lock_init + .text.__retarget_lock_init_recursive + 0x20007c2a 0x2 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + 0x20007c2a __retarget_lock_init_recursive + .text.__retarget_lock_close + 0x20007c2c 0x2 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + 0x20007c2c __retarget_lock_close + .text.__retarget_lock_close_recursive + 0x20007c2e 0x2 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + 0x20007c2e __retarget_lock_close_recursive + .text.__retarget_lock_acquire + 0x20007c30 0x2 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + 0x20007c30 __retarget_lock_acquire + .text.__retarget_lock_acquire_recursive + 0x20007c32 0x2 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + 0x20007c32 __retarget_lock_acquire_recursive + .text.__retarget_lock_try_acquire + 0x20007c34 0x4 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + 0x20007c34 __retarget_lock_try_acquire + .text.__retarget_lock_try_acquire_recursive + 0x20007c38 0x4 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + 0x20007c38 __retarget_lock_try_acquire_recursive + .text.__retarget_lock_release + 0x20007c3c 0x2 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + 0x20007c3c __retarget_lock_release + .text.__retarget_lock_release_recursive + 0x20007c3e 0x2 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + 0x20007c3e __retarget_lock_release_recursive *(.rodata) - .rodata 0x20006c2c 0x81 Debug/TinyTimber.o - *fill* 0x20006cad 0x3 - .rodata 0x20006cb0 0x8a Debug/canTinyTimber.o - *fill* 0x20006d3a 0x2 - .rodata 0x20006d3c 0x31 Debug/application.o + .rodata 0x20007c40 0x81 Debug/TinyTimber.o + *fill* 0x20007cc1 0x3 + .rodata 0x20007cc4 0x8a Debug/canTinyTimber.o + *fill* 0x20007d4e 0x2 + .rodata 0x20007d50 0x97 Debug/application.o *(.rodata*) + *fill* 0x20007de7 0x1 + .rodata._global_impure_ptr + 0x20007de8 0x4 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) + 0x20007de8 _global_impure_ptr + .rodata._svfprintf_r.str1.1 + 0x20007dec 0x11 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) + .rodata._printf_i.str1.1 + 0x20007dfd 0x22 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) *(.glue_7) - .glue_7 0x20006d6d 0x0 linker stubs + .glue_7 0x20007e1f 0x0 linker stubs *(.glue_7t) - .glue_7t 0x20006d6d 0x0 linker stubs - 0x20006d70 . = ALIGN (0x4) - *fill* 0x20006d6d 0x3 + .glue_7t 0x20007e1f 0x0 linker stubs + 0x20007e20 . = ALIGN (0x4) + *fill* 0x20007e1f 0x1 -.vfp11_veneer 0x20006d70 0x0 - .vfp11_veneer 0x20006d70 0x0 linker stubs +.vfp11_veneer 0x20007e20 0x0 + .vfp11_veneer 0x20007e20 0x0 linker stubs -.v4_bx 0x20006d70 0x0 - .v4_bx 0x20006d70 0x0 linker stubs +.v4_bx 0x20007e20 0x0 + .v4_bx 0x20007e20 0x0 linker stubs -.iplt 0x20006d70 0x0 - .iplt 0x20006d70 0x0 Debug/dispatch.o +.iplt 0x20007e20 0x0 + .iplt 0x20007e20 0x0 Debug/dispatch.o -.rel.dyn 0x20006d70 0x0 - .rel.iplt 0x20006d70 0x0 Debug/dispatch.o +.rel.dyn 0x20007e20 0x0 + .rel.iplt 0x20007e20 0x0 Debug/dispatch.o -.data 0x20006d70 0x560 - 0x20006d70 . = ALIGN (0x4) +.data 0x20007e20 0x610 + 0x20007e20 . = ALIGN (0x4) *(.data) - .data 0x20006d70 0x84 Debug/dispatch.o - .data 0x20006df4 0x24 Debug/TinyTimber.o - 0x20006df4 hex - 0x20006e08 msgPool - 0x20006e0c threadPool - 0x20006e10 activeStack - 0x20006e14 current - .data 0x20006e18 0x0 Debug/canTinyTimber.o - .data 0x20006e18 0x0 Debug/sciTinyTimber.o - .data 0x20006e18 0x0 Debug/stm32f4xx_can.o - .data 0x20006e18 0x0 Debug/stm32f4xx_dac.o - .data 0x20006e18 0x0 Debug/stm32f4xx_exti.o - .data 0x20006e18 0x0 Debug/stm32f4xx_gpio.o - .data 0x20006e18 0x10 Debug/stm32f4xx_rcc.o - .data 0x20006e28 0x0 Debug/stm32f4xx_syscfg.o - .data 0x20006e28 0x0 Debug/stm32f4xx_tim.o - .data 0x20006e28 0x0 Debug/stm32f4xx_usart.o - .data 0x20006e28 0x0 Debug/startup.o - .data 0x20006e28 0x4a8 Debug/application.o - 0x20006e28 app - 0x20006e38 sci0 - 0x20007258 can0 + .data 0x20007e20 0x84 Debug/dispatch.o + .data 0x20007ea4 0x24 Debug/TinyTimber.o + 0x20007ea4 hex + 0x20007eb8 msgPool + 0x20007ebc threadPool + 0x20007ec0 activeStack + 0x20007ec4 current + .data 0x20007ec8 0x0 Debug/canTinyTimber.o + .data 0x20007ec8 0x0 Debug/sciTinyTimber.o + .data 0x20007ec8 0x0 Debug/stm32f4xx_can.o + .data 0x20007ec8 0x0 Debug/stm32f4xx_dac.o + .data 0x20007ec8 0x0 Debug/stm32f4xx_exti.o + .data 0x20007ec8 0x0 Debug/stm32f4xx_gpio.o + .data 0x20007ec8 0x10 Debug/stm32f4xx_rcc.o + .data 0x20007ed8 0x0 Debug/stm32f4xx_syscfg.o + .data 0x20007ed8 0x0 Debug/stm32f4xx_tim.o + .data 0x20007ed8 0x0 Debug/stm32f4xx_usart.o + .data 0x20007ed8 0x0 Debug/startup.o + .data 0x20007ed8 0x4f4 Debug/application.o + 0x20007ed8 dac + 0x20007edc app + 0x20007eec sci0 + 0x2000830c muteVolumeSem + 0x2000831c can0 + 0x20008394 tg + 0x200083bc ld + .data 0x200083cc 0x0 Debug/semaphore.o + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memchr.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memcpy-stub.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memmove.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sbrkr.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-msizer.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + .data 0x200083cc 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) *(.data.*) - 0x200072d0 . = ALIGN (0x4) + .data._impure_ptr + 0x200083cc 0x4 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) + 0x200083cc _impure_ptr + .data.impure_data + 0x200083d0 0x60 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) + 0x20008430 . = ALIGN (0x4) -.igot.plt 0x200072d0 0x0 - .igot.plt 0x200072d0 0x0 Debug/dispatch.o +.igot.plt 0x20008430 0x0 + .igot.plt 0x20008430 0x0 Debug/dispatch.o -.bss 0x200072d0 0x8370 - 0x200072d0 . = ALIGN (0x4) - 0x200072d0 _sbss = . +.bss 0x20008430 0x8388 + 0x20008430 . = ALIGN (0x4) + 0x20008430 _sbss = . *(.bss) - .bss 0x200072d0 0x0 Debug/dispatch.o - .bss 0x200072d0 0x18 Debug/TinyTimber.o - 0x200072d0 msgQ - 0x200072d4 timerQ - 0x200072d8 runAsHardware - 0x200072dc doIRQSchedule - 0x200072e0 timestamp - 0x200072e4 overflows - .bss 0x200072e8 0x0 Debug/canTinyTimber.o - .bss 0x200072e8 0x0 Debug/sciTinyTimber.o - .bss 0x200072e8 0x0 Debug/stm32f4xx_can.o - .bss 0x200072e8 0x0 Debug/stm32f4xx_dac.o - .bss 0x200072e8 0x0 Debug/stm32f4xx_exti.o - .bss 0x200072e8 0x0 Debug/stm32f4xx_gpio.o - .bss 0x200072e8 0x0 Debug/stm32f4xx_rcc.o - .bss 0x200072e8 0x0 Debug/stm32f4xx_syscfg.o - .bss 0x200072e8 0x0 Debug/stm32f4xx_tim.o - .bss 0x200072e8 0x0 Debug/stm32f4xx_usart.o - .bss 0x200072e8 0x0 Debug/startup.o - .bss 0x200072e8 0x0 Debug/application.o + .bss 0x20008430 0x0 Debug/dispatch.o + .bss 0x20008430 0x18 Debug/TinyTimber.o + 0x20008430 msgQ + 0x20008434 timerQ + 0x20008438 runAsHardware + 0x2000843c doIRQSchedule + 0x20008440 timestamp + 0x20008444 overflows + .bss 0x20008448 0x0 Debug/canTinyTimber.o + .bss 0x20008448 0x0 Debug/sciTinyTimber.o + .bss 0x20008448 0x0 Debug/stm32f4xx_can.o + .bss 0x20008448 0x0 Debug/stm32f4xx_dac.o + .bss 0x20008448 0x0 Debug/stm32f4xx_exti.o + .bss 0x20008448 0x0 Debug/stm32f4xx_gpio.o + .bss 0x20008448 0x0 Debug/stm32f4xx_rcc.o + .bss 0x20008448 0x0 Debug/stm32f4xx_syscfg.o + .bss 0x20008448 0x0 Debug/stm32f4xx_tim.o + .bss 0x20008448 0x0 Debug/stm32f4xx_usart.o + .bss 0x20008448 0x0 Debug/startup.o + .bss 0x20008448 0x0 Debug/application.o + .bss 0x20008448 0x0 Debug/semaphore.o + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memchr.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memcpy-stub.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memmove.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sbrkr.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-msizer.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + .bss 0x20008448 0x0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) *(.bss.*) + .bss.__malloc_free_list + 0x20008448 0x4 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + 0x20008448 __malloc_free_list + .bss.__malloc_sbrk_start + 0x2000844c 0x4 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + 0x2000844c __malloc_sbrk_start *(COMMON) - COMMON 0x200072e8 0x8358 Debug/TinyTimber.o - 0x200072e8 otable - 0x200072f4 upcoming - 0x200072f8 threads - 0x20007348 mtable - 0x20007354 thread0 - 0x20007368 messages - 0x20007638 __heap_end - 0x20007640 stacks - 0x2000f640 . = ALIGN (0x4) - 0x2000f640 _ebss = . - 0x2000f640 PROVIDE (end = _ebss) + COMMON 0x20008450 0x8358 Debug/TinyTimber.o + 0x20008450 otable + 0x2000845c upcoming + 0x20008460 threads + 0x200084b0 mtable + 0x200084bc thread0 + 0x200084d0 messages + 0x200087a0 __heap_end + 0x200087a8 stacks + COMMON 0x200107a8 0x4 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + 0x200107a8 errno + COMMON 0x200107ac 0x9 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + 0x200107ac __lock___atexit_recursive_mutex + 0x200107ad __lock___arc4random_mutex + 0x200107ae __lock___env_recursive_mutex + 0x200107af __lock___sinit_recursive_mutex + 0x200107b0 __lock___malloc_recursive_mutex + 0x200107b1 __lock___at_quick_exit_mutex + 0x200107b2 __lock___dd_hash_mutex + 0x200107b3 __lock___tz_mutex + 0x200107b4 __lock___sfp_recursive_mutex + 0x200107b8 . = ALIGN (0x4) + *fill* 0x200107b5 0x3 + 0x200107b8 _ebss = . + 0x200107b8 PROVIDE (end = _ebss) [!provide] PROVIDE (_end = _ebss) OUTPUT(Debug/RTS-Lab.elf elf32-littlearm) @@ -478,6 +712,38 @@ OUTPUT(Debug/RTS-Lab.elf elf32-littlearm) 0x00000261 0x34 Debug/startup.o .ARM.attributes 0x00000295 0x34 Debug/application.o + .ARM.attributes + 0x000002c9 0x34 Debug/semaphore.o + .ARM.attributes + 0x000002fd 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) + .ARM.attributes + 0x00000331 0x32 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) + .ARM.attributes + 0x00000363 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) + .ARM.attributes + 0x00000397 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) + .ARM.attributes + 0x000003cb 0x1c c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memchr.o) + .ARM.attributes + 0x000003e7 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memcpy-stub.o) + .ARM.attributes + 0x0000041b 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memmove.o) + .ARM.attributes + 0x0000044f 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) + .ARM.attributes + 0x00000483 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + .ARM.attributes + 0x000004b7 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) + .ARM.attributes + 0x000004eb 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sbrkr.o) + .ARM.attributes + 0x0000051f 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) + .ARM.attributes + 0x00000553 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-msizer.o) + .ARM.attributes + 0x00000587 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + .ARM.attributes + 0x000005bb 0x34 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) .comment 0x00000000 0x79 .comment 0x00000000 0x79 Debug/TinyTimber.o @@ -494,8 +760,9 @@ OUTPUT(Debug/RTS-Lab.elf elf32-littlearm) .comment 0x00000079 0x7a Debug/stm32f4xx_usart.o .comment 0x00000079 0x7a Debug/startup.o .comment 0x00000079 0x7a Debug/application.o + .comment 0x00000079 0x7a Debug/semaphore.o -.debug_info 0x00000000 0xa261 +.debug_info 0x00000000 0xa917 .debug_info 0x00000000 0x183c Debug/TinyTimber.o .debug_info 0x0000183c 0xdb4 Debug/canTinyTimber.o .debug_info 0x000025f0 0x9d1 Debug/sciTinyTimber.o @@ -508,9 +775,10 @@ OUTPUT(Debug/RTS-Lab.elf elf32-littlearm) .debug_info 0x00005e8a 0x1e26 Debug/stm32f4xx_tim.o .debug_info 0x00007cb0 0xa68 Debug/stm32f4xx_usart.o .debug_info 0x00008718 0xade Debug/startup.o - .debug_info 0x000091f6 0x106b Debug/application.o + .debug_info 0x000091f6 0x1446 Debug/application.o + .debug_info 0x0000a63c 0x2db Debug/semaphore.o -.debug_abbrev 0x00000000 0x1dc5 +.debug_abbrev 0x00000000 0x1f68 .debug_abbrev 0x00000000 0x4f2 Debug/TinyTimber.o .debug_abbrev 0x000004f2 0x277 Debug/canTinyTimber.o .debug_abbrev 0x00000769 0x273 Debug/sciTinyTimber.o @@ -523,9 +791,10 @@ OUTPUT(Debug/RTS-Lab.elf elf32-littlearm) .debug_abbrev 0x000014fa 0x1c2 Debug/stm32f4xx_tim.o .debug_abbrev 0x000016bc 0x1a8 Debug/stm32f4xx_usart.o .debug_abbrev 0x00001864 0x286 Debug/startup.o - .debug_abbrev 0x00001aea 0x2db Debug/application.o + .debug_abbrev 0x00001aea 0x311 Debug/application.o + .debug_abbrev 0x00001dfb 0x16d Debug/semaphore.o -.debug_aranges 0x00000000 0x1a8 +.debug_aranges 0x00000000 0x1c8 .debug_aranges 0x00000000 0x20 Debug/TinyTimber.o .debug_aranges @@ -552,8 +821,10 @@ OUTPUT(Debug/RTS-Lab.elf elf32-littlearm) 0x00000160 0x28 Debug/startup.o .debug_aranges 0x00000188 0x20 Debug/application.o + .debug_aranges + 0x000001a8 0x20 Debug/semaphore.o -.debug_line 0x00000000 0x3ef8 +.debug_line 0x00000000 0x41ac .debug_line 0x00000000 0x9f9 Debug/TinyTimber.o .debug_line 0x000009f9 0x393 Debug/canTinyTimber.o .debug_line 0x00000d8c 0x257 Debug/sciTinyTimber.o @@ -566,37 +837,40 @@ OUTPUT(Debug/RTS-Lab.elf elf32-littlearm) .debug_line 0x000029ce 0xb05 Debug/stm32f4xx_tim.o .debug_line 0x000034d3 0x4f2 Debug/stm32f4xx_usart.o .debug_line 0x000039c5 0x2eb Debug/startup.o - .debug_line 0x00003cb0 0x248 Debug/application.o + .debug_line 0x00003cb0 0x369 Debug/application.o + .debug_line 0x00004019 0x193 Debug/semaphore.o -.debug_str 0x00000000 0x3453 - .debug_str 0x00000000 0xbc4 Debug/TinyTimber.o +.debug_str 0x00000000 0x3576 + .debug_str 0x00000000 0xbbc Debug/TinyTimber.o 0xc67 (size before relaxing) - .debug_str 0x00000bc4 0x210 Debug/canTinyTimber.o + .debug_str 0x00000bbc 0x210 Debug/canTinyTimber.o 0xa28 (size before relaxing) - .debug_str 0x00000dd4 0x4b Debug/sciTinyTimber.o + .debug_str 0x00000dcc 0x4b Debug/sciTinyTimber.o 0x887 (size before relaxing) - .debug_str 0x00000e1f 0x393 Debug/stm32f4xx_can.o + .debug_str 0x00000e17 0x393 Debug/stm32f4xx_can.o 0x752 (size before relaxing) - .debug_str 0x000011b2 0x26d Debug/stm32f4xx_dac.o + .debug_str 0x000011aa 0x26d Debug/stm32f4xx_dac.o 0x467 (size before relaxing) - .debug_str 0x0000141f 0x19f Debug/stm32f4xx_exti.o + .debug_str 0x00001417 0x19f Debug/stm32f4xx_exti.o 0x360 (size before relaxing) - .debug_str 0x000015be 0x29f Debug/stm32f4xx_gpio.o + .debug_str 0x000015b6 0x29f Debug/stm32f4xx_gpio.o 0x4b7 (size before relaxing) - .debug_str 0x0000185d 0x753 Debug/stm32f4xx_rcc.o + .debug_str 0x00001855 0x753 Debug/stm32f4xx_rcc.o 0x9a9 (size before relaxing) - .debug_str 0x00001fb0 0x14f Debug/stm32f4xx_syscfg.o + .debug_str 0x00001fa8 0x14f Debug/stm32f4xx_syscfg.o 0x322 (size before relaxing) - .debug_str 0x000020ff 0xa58 Debug/stm32f4xx_tim.o + .debug_str 0x000020f7 0xa58 Debug/stm32f4xx_tim.o 0xde4 (size before relaxing) - .debug_str 0x00002b57 0x3f6 Debug/stm32f4xx_usart.o + .debug_str 0x00002b4f 0x3f6 Debug/stm32f4xx_usart.o 0x6a3 (size before relaxing) - .debug_str 0x00002f4d 0x104 Debug/startup.o + .debug_str 0x00002f45 0x104 Debug/startup.o 0x7aa (size before relaxing) - .debug_str 0x00003051 0x402 Debug/application.o - 0x79c (size before relaxing) + .debug_str 0x00003049 0x4fa Debug/application.o + 0x8b3 (size before relaxing) + .debug_str 0x00003543 0x33 Debug/semaphore.o + 0x239 (size before relaxing) -.debug_frame 0x00000000 0x2fb8 +.debug_frame 0x00000000 0x3584 .debug_frame 0x00000000 0x57c Debug/TinyTimber.o .debug_frame 0x0000057c 0x100 Debug/canTinyTimber.o .debug_frame 0x0000067c 0x11c Debug/sciTinyTimber.o @@ -609,7 +883,21 @@ OUTPUT(Debug/RTS-Lab.elf elf32-littlearm) .debug_frame 0x00001af0 0xe54 Debug/stm32f4xx_tim.o .debug_frame 0x00002944 0x490 Debug/stm32f4xx_usart.o .debug_frame 0x00002dd4 0x14c Debug/startup.o - .debug_frame 0x00002f20 0x98 Debug/application.o + .debug_frame 0x00002f20 0x1e4 Debug/application.o + .debug_frame 0x00003104 0xa8 Debug/semaphore.o + .debug_frame 0x000031ac 0x6c c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) + .debug_frame 0x00003218 0x90 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) + .debug_frame 0x000032a8 0x60 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) + .debug_frame 0x00003308 0x28 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memcpy-stub.o) + .debug_frame 0x00003330 0x28 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memmove.o) + .debug_frame 0x00003358 0x38 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) + .debug_frame 0x00003390 0x30 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + .debug_frame 0x000033c0 0x3c c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) + .debug_frame 0x000033fc 0x2c c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sbrkr.o) + .debug_frame 0x00003428 0x30 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) + .debug_frame 0x00003458 0x20 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-msizer.o) + .debug_frame 0x00003478 0x5c c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + .debug_frame 0x000034d4 0xb0 c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) .debug_ranges 0x00000000 0x18 .debug_ranges 0x00000000 0x18 Debug/startup.o @@ -787,6 +1075,8 @@ SYSCFG_EXTILineConfig Debug/stm32f4xx_syscfg.o SYSCFG_GetCompensationCellStatus Debug/stm32f4xx_syscfg.o SYSCFG_MemoryRemapConfig Debug/stm32f4xx_syscfg.o SYSCFG_MemorySwappingBank Debug/stm32f4xx_syscfg.o +Signal Debug/semaphore.o + Debug/application.o TIMER_INIT Debug/TinyTimber.o TIM_ARRPreloadConfig Debug/stm32f4xx_tim.o TIM_BDTRConfig Debug/stm32f4xx_tim.o @@ -922,47 +1212,135 @@ USART_SmartCardCmd Debug/stm32f4xx_usart.o USART_SmartCardNACKCmd Debug/stm32f4xx_usart.o USART_StructInit Debug/stm32f4xx_usart.o USART_WakeUpConfig Debug/stm32f4xx_usart.o +Wait Debug/semaphore.o + Debug/application.o __heap_end Debug/TinyTimber.o +__lock___arc4random_mutex c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__lock___at_quick_exit_mutex c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__lock___atexit_recursive_mutex c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__lock___dd_hash_mutex c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__lock___env_recursive_mutex c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__lock___malloc_recursive_mutex c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) +__lock___sfp_recursive_mutex c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__lock___sinit_recursive_mutex c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__lock___tz_mutex c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__malloc_free_list c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) +__malloc_lock c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) +__malloc_sbrk_start c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) +__malloc_unlock c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) __pendSV_dispatch Debug/TinyTimber.o +__retarget_lock_acquire c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__retarget_lock_acquire_recursive c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) +__retarget_lock_close c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__retarget_lock_close_recursive c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__retarget_lock_init c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__retarget_lock_init_recursive c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__retarget_lock_release c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__retarget_lock_release_recursive c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-mlock.o) +__retarget_lock_try_acquire c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__retarget_lock_try_acquire_recursive c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-lock.o) +__sf_fake_stderr c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) +__sf_fake_stdin c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) +__sf_fake_stdout c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) +__ssprint_r c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) +__ssputs_r c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) __svc_dispatch Debug/TinyTimber.o _ebss Debug/startup.o +_free_r c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-freer.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) +_global_impure_ptr c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) +_impure_ptr c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-impure.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) +_malloc_r c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) +_malloc_usable_size_r c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-msizer.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) +_printf_common c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) +_printf_float c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) +_printf_i c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) +_realloc_r c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) +_reclaim_reent c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) _sbrk Debug/TinyTimber.o + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sbrkr.o) +_sbrk_r c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sbrkr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-mallocr.o) _sbss Debug/startup.o +_siprintf_r c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) +_sprintf_r c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) +_svfiprintf_r c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) +_svfprintf_r c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) activeStack Debug/TinyTimber.o app Debug/application.o async Debug/TinyTimber.o + Debug/semaphore.o + Debug/application.o Debug/sciTinyTimber.o Debug/canTinyTimber.o +backgroundLoop Debug/application.o +c_dequeue Debug/semaphore.o +c_enqueue Debug/semaphore.o can0 Debug/application.o can_init Debug/canTinyTimber.o - Debug/application.o can_interrupt Debug/canTinyTimber.o - Debug/application.o can_receive Debug/canTinyTimber.o Debug/application.o can_send Debug/canTinyTimber.o - Debug/application.o +cleanup_glue c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) cli Debug/TinyTimber.o current Debug/TinyTimber.o Debug/dispatch.o +dac Debug/application.o +decreaseLoad Debug/application.o dequeue Debug/TinyTimber.o dequeue_pool Debug/TinyTimber.o doIRQSchedule Debug/TinyTimber.o Debug/sciTinyTimber.o Debug/canTinyTimber.o +downVolume Debug/application.o +enableDeadlineLD Debug/application.o +enableDeadlineTG Debug/application.o end Debug/TinyTimber.o enqueueByBaseline Debug/TinyTimber.o enqueueByDeadline Debug/TinyTimber.o +errno c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-reent.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sbrkr.o) hex Debug/TinyTimber.o +increaseLoad Debug/application.o insert Debug/TinyTimber.o install Debug/TinyTimber.o Debug/application.o +ld Debug/application.o main Debug/application.o Debug/startup.o +memchr c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memchr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-vfprintf_i.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) +memcpy c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memcpy-stub.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-reallocr.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) +memmove c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-memmove.o) + c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-nano-svfprintf.o) messages Debug/TinyTimber.o msgPool Debug/TinyTimber.o msgQ Debug/TinyTimber.o mtable Debug/TinyTimber.o +mute Debug/application.o +muteVolumeSem Debug/application.o otable Debug/TinyTimber.o overflows Debug/TinyTimber.o pop Debug/TinyTimber.o @@ -980,18 +1358,24 @@ sci_write Debug/sciTinyTimber.o sci_writechar Debug/sciTinyTimber.o Debug/application.o sei Debug/TinyTimber.o +siprintf c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) +sprintf c:/cseapp/codelite/tools/gcc-arm/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/lib/thumb/v7e-m+fp/hard\libc_nano.a(lib_a-sprintf.o) + Debug/application.o stacks Debug/TinyTimber.o startApp Debug/application.o startup Debug/startup.o sync Debug/TinyTimber.o Debug/application.o +tg Debug/application.o thread0 Debug/TinyTimber.o threadPool Debug/TinyTimber.o threads Debug/TinyTimber.o +tick Debug/application.o timerQ Debug/TinyTimber.o timestamp Debug/TinyTimber.o tinytimber Debug/TinyTimber.o Debug/application.o +upVolume Debug/application.o upcoming Debug/TinyTimber.o Debug/dispatch.o vect_CAN1 Debug/TinyTimber.o diff --git a/Debug/RTS-Lab.s19 b/Debug/RTS-Lab.s19 index de801a0..b116762 100644 --- a/Debug/RTS-Lab.s19 +++ b/Debug/RTS-Lab.s19 @@ -1,5 +1,5 @@ S014000044656275672F5254532D4C61622E73313995 -S3152000000000BFDFF814D006F048FD06F0EFFD06F03D +S3152000000000BFDFF814D006F048FD06F0EFFF06F03B S3152000001056BDFEE700BF000000C00120314900E0C8 S315200000203149EFF3088020ED108A7246EFF31183F1 S3152000003020E9FC0F2D4FD7F80080C8F800001EE0FD @@ -13,9 +13,9 @@ S315200000A0D8F8000000F095F8144800F075F8D8F854 S315200000B00000006800F08DF80D4800F06DF8134A36 S315200000C0536843F00063536000BFD8F80000B0E8DF S315200000D0FC0F83F311889646B0EC108A80F30888CB -S315200000E070470000706D0020816D0020146E002086 -S315200000F0F16D0020A26D0020BA6D0020C26D002097 -S31520000100F4720020CB6D0020E06D002000ED00E0B1 +S315200000E070470000207E0020317E0020C47E002044 +S315200000F0A17E0020527E00206A7E0020727E002093 +S315200001005C8400207B7E0020907E002000ED00E0B5 S3152000011080B483B000AF0346FB71FB7903F01F0365 S31520000120012202FA03F1064A97F907305B0942F8E1 S31520000130231000BF0C37BD465DF8047B704700BF17 @@ -33,7 +33,7 @@ S315200001E003F00F027B69591C796110498A5C07F17B S315200001F018010B4403F80C2C7B681B097B607B6879 S31520000200002BECD10AE07B69013B7B6107F10C02F4 S315200002107B6913441B78184600F02EF97B69002B66 -S31520000220F1D100BF00BF1837BD4680BDF46D002058 +S31520000220F1D100BF00BF1837BD4680BDA47E002097 S3152000023080B59EB000AF78607B68002B02DA4FF065 S31520000240FF3300E001233B677B683A6F02FB03F331 S315200002507B6000237B6779681C4B83FB01239A1004 @@ -44,15 +44,15 @@ S315200002907B607B68002BDED13B6F002B0EDA2D2096 S315200002A000F0EAF80AE07B6F013B7B6707F10C025E S315200002B07B6F13441B78184600F0DEF87B6F002B0B S315200002C0F1D100BF00BF7837BD4680BD6766666640 -S315200002D0F46D002080B483B000AF10237B607B6870 +S315200002D0A47E002080B483B000AF10237B607B68AF S315200002E083F3118800BF00BF0C37BD465DF8047B41 S315200002F0704780B483B000AF30237B607B6883F384 S31520000300118800BF00BF0C37BD465DF8047B7047DF S3152000031080B584B000AF78600B48FFF73DFF0B4BEC S315200003201B68002B02D1094B094A1A60074B1B6830 S31520000330FB60064B1A687B681344044A1360FB680B -S3152000034018461037BD4680BD2C6C0020387600201C -S3152000035040F6002080B485B000AF786039603B68F5 +S3152000034018461037BD4680BD407C0020A08700207F +S31520000350B807012080B485B000AF786039603B686B S3152000036003F5F95310337A6813607B681B68BB600A S315200003700023FB600AE0FB689B001A46BB68134417 S315200003801A4600231360FB680133FB60FB68332B9E @@ -79,21 +79,21 @@ S315200004C001221A60104B00221A60104B1B68002B69 S315200004D006D00E4B1B680E4A12680021104698471C S315200004E0084B00221A60084B1B68002B01D000F035 S315200004F05DFA054B00221A6000BF80BD000C00404B -S31520000500E0720020D8720020DC72002048730020A0 -S31520000510E872002080B500AF124804F031F8034697 +S3152000050040840020388400203C840020B0840020D1 +S315200005105084002080B500AF124804F031F803461D S315200005201A46114B1A60114B01221A60104B0022F9 S315200005301A60104B5B68002B06D00E4B5B680E4A88 S315200005405268012110469847084B00221A60084B32 S315200005501B68002B01D000F029FA054B00221A60F7 -S3152000056000BF80BD000C0040E0720020D872002041 -S31520000570DC72002048730020E872002080B500AFAE +S3152000056000BF80BD000C004040840020388400205D +S315200005703C840020B08400205084002080B500AF49 S31520000580124803F0FDFF03461A46114B1A60114B21 S3152000059001221A60104B00221A60104B9B68002B18 S315200005A006D00E4B9B680E4A926802211046984749 S315200005B0084B00221A60084B1B68002B01D000F064 S315200005C0F5F9054B00221A6000BF80BD000C0040E3 -S315200005D0E0720020D8720020DC72002048730020D0 -S315200005E0E872002080B485B000AF786039600023BF +S315200005D040840020388400203C840020B084002001 +S315200005E05084002080B485B000AF78603960002345 S315200005F0FB603B681B68BB6004E0BB68FB60BB68B4 S315200006001B68BB60BB68002B05D0BB689A687B68FB S315200006109B689A42F1DD7B68BA681A60FB68002BFA @@ -108,13 +108,13 @@ S31520000690047B704780B584B000AF78607B681B68A8 S315200006A0FB60FB68002B04D0FB681A687B681A6025 S315200006B00CE00948FFF770FD00220221074802F0EE S315200006C028FE0748FFF768FD30BFFDE7FB681846A0 -S315200006D01037BD4680BD00BF446C00200004024098 -S315200006E0506C002080B584B000AF78607B681B68B2 +S315200006D01037BD4680BD00BF587C00200004024074 +S315200006E0647C002080B584B000AF78607B681B688E S315200006F0FB60FB68002B04D0FB681A687B681A60D5 S315200007000CE00948FFF748FD00220221074802F0C5 S3152000071000FE0748FFF740FD30BFFDE7FB6818469F -S315200007201037BD4680BD00BF446C00200004024047 -S315200007305C6C002080B483B000AF786039603B6881 +S315200007201037BD4680BD00BF587C00200004024023 +S31520000730707C002080B483B000AF786039603B685D S315200007401A687B681A603B687A681A6000BF0C37A3 S31520000750BD465DF8047B704780B483B000AF7860F7 S3152000076039603B681A687B689A603B687A681A60C9 @@ -135,10 +135,10 @@ S315200008401B68002B16D00E4803F09AFE03463B6029 S315200008500C4B1B685B683A689A4204DD0022022131 S315200008600A4802F056FD074B1B685B681946044888 S3152000087004F0C5F900F09AF800BF0837BD4680BDE0 -S31520000880000C0040D4720020D072002000040240E8 -S315200008900346024A136010DFF74600BFF4720020B9 +S31520000880000C004034840020308400200004024004 +S315200008900346024A136010DFF74600BF5C8400203F S315200008A00346054A1360054B5B68044A43F08053B0 -S315200008B05360F74600BF00BFF472002000ED00E051 +S315200008B05360F74600BF00BF5C84002000ED00E0D7 S315200008C080B582B000AF7860094B5B68C3F308033C S315200008D0002B03D17868FFF7DBFF02E07868FFF78B S315200008E0DFFFFFF706FD00BF0837BD4680BD00BF0E @@ -151,15 +151,15 @@ S315200009407B68002BD9D0114B1B689A687B689B6803 S31520000950D31A002BD1DD0F48FFF710FF03460E49AF S315200009601846FFF7F9FE0B4B1B68FB6003E0FB689C S315200009701B691B68FB60FB681B69002BF7D1F868B5 -S31520000980FFF79EFFB9E700BF146E0020D07200204B -S31520000990086E0020106E00200C6E002080B500AF7F +S31520000980FFF79EFFB9E700BFC47E00203084002019 +S31520000990B87E0020C07E0020BC7E002080B500AF3F S315200009A000F004F8FFF7A5FC30BFFBE780B582B066 S315200009B000AF144B1B68DB687B60134B1B68002B56 S315200009C01BD0124B1B68002B17D07B68002B07D03F S315200009D00D4B1B689A687B689B68D31A002B0CDA30 S315200009E00A48FFF7CBFE034606491846FFF7B4FE32 S315200009F0044B1B681846FFF763FF00BF0837BD4648 -S31520000A0080BD00BF106E0020D07200200C6E00202A +S31520000A0080BD00BFC07E002030840020BC7E002038 S31520000A1080B588B000AFF860B9607A603B60EFF3CC S31520000A2012833B613B691B09012B14BF0123002361 S31520000A30DBB2FB77FFF74EFC3A48FFF753FEB8616F @@ -177,9 +177,9 @@ S31520000AE016D0174B1B689A68174B1B68DB689B68E8 S31520000AF0D31A002B0CDA1348FFF740FE034612499F S31520000B001846FFF729FE104B1B681846FFF7D8FE3C S31520000B10FB7F002B01D0FFF7ECFBBB691846203783 -S31520000B20BD4680BD086E0020D8720020146E0020BD -S31520000B30E0720020000C0040D47200200004024025 -S31520000B40D07200200C6E0020106E002080B588B078 +S31520000B20BD4680BDB87E002038840020C47E0020CB +S31520000B3040840020000C0040348400200004024041 +S31520000B4030840020BC7E0020C07E002080B588B086 S31520000B5000AFF860B9607A60EFF312833B613B69BE S31520000B601B09012B14BF01230023DBB2FB76FFF701 S31520000B70B1FBFB681B68FB61FB69002B37D003E0E8 @@ -196,7 +196,7 @@ S31520000C107861FFF75FFBFB6800221A60FB685B6860 S31520000C20FB61FB69002B0BD0FB69012B08D0FB680D S31520000C3000225A60FB6900221A61F869FFF740FE1C S31520000C40FB7E002B01D0FFF754FB7B69184620372B -S31520000C50BD4680BD146E002080B586B000AF78609A +S31520000C50BD4680BDC47E002080B586B000AF7860DA S31520000C60EFF31283FB60FB681B09012B14BF0123E2 S31520000C700023DBB2FB74FFF72DFB1F497868FFF7D3 S31520000C808FFD0346002B06D11C497868FFF788FDA7 @@ -206,22 +206,22 @@ S31520000CB012D07B69DB687A689A420DD17B691A6902 S31520000CC07B68DB689A4207D17B690022DA600C498F S31520000CD07868FFF72FFD05E07B699B687B617B6960 S31520000CE0002BE1D1FB7C002B01D0FFF702FB00BFDC -S31520000CF01837BD4680BD00BFD4720020D0720020B8 -S31520000D00086E0020106E0020146E002080B485B07E +S31520000CF01837BD4680BD00BF3484002030840020D4 +S31520000D00B87E0020C07E0020C47E002080B485B03E S31520000D1000AF7860EFF31283FB60FB681B09012BA1 S31520000D2004D0074B1B68DB685B6801E0054B1B683A S31520000D307A68136000BF1437BD465DF8047B7047A0 -S31520000D40146E0020E072002080B485B000AF786079 +S31520000D40C47E00204084002080B485B000AF786047 S31520000D50EFF31283FB60FB681B09012B04D0084BC1 S31520000D601B68DB685B6801E0064B1B687A681268C3 S31520000D709B1A18461437BD465DF8047B704700BFA2 -S31520000D80146E0020E072002080B584B000AFEFF32F +S31520000D80C47E00204084002080B584B000AFEFF3FD S31520000D9012837B607B681B09012B14BF0123002370 S31520000DA0DBB2FB73FFF796FA0C4803F0E9FB034628 S31520000DB0BB60FB7B002B01D0FFF79BFAFB7B002B54 S31520000DC004D0074B1B68DB685B6801E0054B1B689A S31520000DD0BA68D31A18461037BD4680BD000C0040AD -S31520000DE0146E0020E072002080B582B000AF002390 +S31520000DE0C47E00204084002080B582B000AF00235E S31520000DF07B6012E07B685A1C13465B001344DB00C1 S31520000E00444A991843487A6813465B001344DB002A S31520000E10034419607B6801337B607B681C2BE9DD0A @@ -240,9 +240,9 @@ S31520000ED0144B4FF0FF325A60124B00229A60114B8E S31520000EE000221A610F4B0022DA600F48FFF754F9EF S31520000EF00E48FFF751F90E48FFF74EF90A48FFF75B S31520000F004BF90948FFF748F9FFF76AFA00BF083797 -S31520000F10BD4680BD68730020F87200204076002010 -S31520000F20F508002054730020686C00206C6C0020AB -S31520000F30786C002080B586B000AFF860B9601346A3 +S31520000F10BD4680BDD084002060840020A8870020A4 +S31520000F20F5080020BC8400207C7C0020807C0020EA +S31520000F308C7C002080B586B000AFF860B96013467F S31520000F40FB71FB79022B41D8EFF312833B613B699E S31520000F501B09012B14BF01230023DBB2FB75FFF70E S31520000F60B9F9FB79022B0ED0022B10DC002B02D014 @@ -253,15 +253,15 @@ S31520000FA0FFF7FAF830BFFDE7FB791349FA6841F8F5 S31520000FB02320FB791149BA6841F82320FB680122D6 S31520000FC05A60FB7D002B01D0FFF793F900BF18373D S31520000FD0BD4680BDD4C00120AD04002090C00120B4 -S31520000FE0150500209CC001207D050020446C0020B2 -S31520000FF000040240906C0020E87200204873002014 +S31520000FE0150500209CC001207D050020587C00208E +S31520000FF000040240A47C002050840020B0840020FD S3152000100080B586B002AFF860B9607A60FFF762F902 S31520001010FFF7EAFEBB68002B16D00F4803F0B0FAA4 S3152000102003461A460D4B1A600D4B01221A607B6847 S315200010300093BB68FA6800210020FFF7E9FC084B03 S3152000104000221A60FFF7B2FCFFF7A8FC002318461F -S315200010501037BD4680BD00BF000C0040E072002066 -S31520001060D872002080B483B000AF0346FB71FB79B1 +S315200010501037BD4680BD00BF000C004040840020F4 +S315200010603884002080B483B000AF0346FB71FB793F S3152000107003F01F03012202FA03F1064A97F907300B S315200010805B0942F8231000BF0C37BD465DF8047B90 S31520001090704700BF00E100E080B483B000AF034694 @@ -280,8 +280,8 @@ S31520001150002B02D11048FFF71FF807F10C031946A0 S315200011600E4800F007FB0346002B02D10C48FFF780 S3152000117013F802211420FFF78FFF1420FFF772FFC8 S3152000118001220221034801F0C7F800BF1837BD46E7 -S3152000119080BD00BF00640040B06C002000680040A5 -S315200011A0C86C0020B0B58AB002AF786039607B6821 +S3152000119080BD00BF00640040C47C00200068004081 +S315200011A0DC7C0020B0B58AB002AF786039607B68FD S315200011B09B685A49184601F0CDF80346012B02D008 S315200011C05748FEF7E9FF7B68DB69072B00F39F8012 S315200011D07B689B6807F108020021184600F0A2FEF2 @@ -305,7 +305,7 @@ S315200012E0FFF796FB0F4B01221A607B685B6901337F S315200012F05A4203F0070302F0070258BF53427A68A6 S3152000130053617B68DB695A1C7B68DA6102E0064818 S31520001310FEF742FF00BF2037BD46B0BD03000012D6 -S31520001320E06C0020DC720020086D002090B484B0B0 +S31520001320F47C00203C8400201C7D002090B484B0F6 S3152000133000AF786039607B68DB69002B55DD7B6800 S315200013409A69796813469B0013445B0013440B4447 S3152000135020331A783B681A707B689A697968134635 @@ -328,7 +328,7 @@ S3152000145003F8152C97F82730013387F827303B6897 S315200014609B7897F827209A42E8D307F10803194674 S31520001470386A00F0D7FB0346FB77FB7F042B04D1A9 S315200014800448FEF789FE012300E00023184628378A -S31520001490BD4680BD286D002080B483B000AF0346D2 +S31520001490BD4680BD3C7D002080B483B000AF0346AE S315200014A0FB71FB7903F01F03012202FA03F1064ABE S315200014B097F907305B0942F8231000BF0C37BD4669 S315200014C05DF8047B704700BF00E100E080B483B084 @@ -369,7 +369,7 @@ S315200016E0090258BF53427A6893617B68DB695A1EA8 S315200016F07B68DA617B68DB69002B10D17B689B688D S31520001700002240F22771184604F060FF07E07B684C S315200017109B68002240F22771184604F057FF0023E9 -S3152000172018461037BD4680BDDC72002080B582B0D9 +S3152000172018461037BD4680BD3C84002080B582B067 S3152000173000AF78607B680E4A93420AD101214FF0B0 S31520001740007002F045FB00214FF0007002F040FBD4 S3152000175009E001214FF0806002F03AFB00214FF0B2 @@ -922,7 +922,7 @@ S315200039707B685A687B69DA407B689A600C4B9B6847 S3152000398003F46043BB61BB695B0BBB610B4ABB693C S3152000399013441B78DBB27B617B685A687B69DA400B S315200039A07B68DA6000BF2437BD465DF8047B70472C -S315200039B0003802400024F40000127A00186E00201D +S315200039B0003802400024F40000127A00C87E00205D S315200039C080B485B000AF78600023FB607B6803F489 S315200039D04073B3F5407F11D10F4B9B68FB60FB68AA S315200039E023F4F813FB607B6823F0704323F44073C1 @@ -1707,133 +1707,411 @@ S31520006A80124A02E0002342F8043B114B9A42F9D302 S31520006A9000BFBD465DF8047B704780B500AFFFF7A9 S31520006AA0EDFFFFF781FEFFF786FEFFF719FFFFF7E1 S31520006AB04FFFFFF7B1FFFFF7D5FF00BF80BD80B4C2 -S31520006AC000AF00BFBD465DF8047B7047D072002042 -S31520006AD040F6002080B586B000AF7860396007F1B7 +S31520006AC000AF00BFBD465DF8047B704730840020D0 +S31520006AD0B807012080B586B000AF7860396007F12D S31520006AE00C031A460A490B48FAF730F80A4B1A469D S31520006AF00A490B48FAF72AF807F10C0303331A461A S31520006B0006490748FAF722F800BF1837BD4680BD68 -S31520006B102D130020587200203C6D0020C715002040 -S31520006B20386E002080B582B000AF786039600A4B9D -S31520006B301A460A490A48FAF709F83A6809490848F4 -S31520006B40FAF704F8084B1A4604490548F9F7FEFFF8 -S31520006B5000BF0837BD4680BD506D0020C7150020F8 -S31520006B60386E00201D160020586D002080B586B096 -S31520006B7000AF78603960002215491648F9F7E6FF1C -S31520006B80002215491548F9F7E1FF154B1A46154914 -S31520006B901248F9F7DBFF01233B7301237B7306239E -S31520006BA0BB734823FB7365233B746C237B746C2374 -S31520006BB0BB746F23FB7400233B7507F10C031A4645 -S31520006BC009490448F9F7C2FF00BF1837BD4680BD02 -S31520006BD0ED1000205872002021150020386E00206C -S31520006BE05C6D0020C7150020F713002080B500AF8C -S31520006BF0002208490848FAF79DF901220749084862 -S31520006C00FAF798F9002207490748FAF7F9F9002315 -S31520006C10184680BD53160020386E0020A51100208E -S31520006C20587200206D6B0020286E00204E4F544570 -S31520006C303A205F7362726B20696E20757365210A34 -S31520006C400D00000050414E49432121212000000023 -S31520006C50456D70747920717565756500456D707424 -S31520006C607920706F6F6C00000A0D000054696E79F0 -S31520006C7054696D626572200076322E30366131207D -S31520006C8028323032312D30332D31312900000000A9 -S31520006C9044657669636520495251206E6F7420736E -S31520006CA07570706F72746564202E2E2E00000000A1 -S31520006CB00A0D43414E20233120496E6974206661B6 -S31520006CC0696C6564210A0D0043414E202332204918 -S31520006CD06E6974206661696C6564210A0D00000086 -S31520006CE00A0D537472616E67653A204E6F74206187 -S31520006CF02043414E202331204649464F30204952D9 -S31520006D0051210A0D000000000A0D537472616E674E -S31520006D10653A2043414E202331204649464F3020B4 -S31520006D2046756C6C210A0D0043414E2054784275FD -S31520006D30662066756C6C210A0D00000043616E208A -S31520006D406D73672072656365697665643A20000015 -S31520006D505263763A20270000270A000048656C6CAB -S31520006D606F2C2068656C6C6F2E2E2E0A000000009A -S31520006D70535643616C6C20657863657074696F6ED9 -S31520006D800050656E64535620657863657074696F2C -S31520006D906E002C204558435F52455455524E203D97 -S31520006DA02000202063757272656E74207468726587 -S31520006DB061643A204944203D20002C205350203D38 -S31520006DC020002C202A5350203D200020206E65785C -S31520006DD074207468726561643A204944203D20001D -S31520006DE02C205350203D20002C202A5350203D207B -S31520006DF0000A0D00303132333435363738394142C6 -S31520006E00434445460000000068730020F8720020C5 -S31520006E105473002054730020000000000102030474 -S31520006E200102030406070809000000000000000014 -S31520006E3000000000580000000000000000000000D4 -S31520006E4000100140286E0020256B00200000000065 -S31520006E50000000000000000000000000000000000C -S31520006E6000000000000000000000000000000000FC -S31520006E7000000000000000000000000000000000EC -S31520006E8000000000000000000000000000000000DC -S31520006E9000000000000000000000000000000000CC -S31520006EA000000000000000000000000000000000BC -S31520006EB000000000000000000000000000000000AC -S31520006EC0000000000000000000000000000000009C -S31520006ED0000000000000000000000000000000008C -S31520006EE0000000000000000000000000000000007C -S31520006EF0000000000000000000000000000000006C -S31520006F00000000000000000000000000000000005B -S31520006F10000000000000000000000000000000004B -S31520006F20000000000000000000000000000000003B -S31520006F30000000000000000000000000000000002B -S31520006F40000000000000000000000000000000001B -S31520006F50000000000000000000000000000000000B -S31520006F6000000000000000000000000000000000FB -S31520006F7000000000000000000000000000000000EB -S31520006F8000000000000000000000000000000000DB -S31520006F9000000000000000000000000000000000CB -S31520006FA000000000000000000000000000000000BB -S31520006FB000000000000000000000000000000000AB -S31520006FC0000000000000000000000000000000009B -S31520006FD0000000000000000000000000000000008B -S31520006FE0000000000000000000000000000000007B -S31520006FF0000000000000000000000000000000006B -S31520007000000000000000000000000000000000005A -S31520007010000000000000000000000000000000004A -S31520007020000000000000000000000000000000003A -S31520007030000000000000000000000000000000002A -S31520007040000000000000000000000000000000001A -S31520007050000000000000000000000000000000000A -S3152000706000000000000000000000000000000000FA -S3152000707000000000000000000000000000000000EA -S3152000708000000000000000000000000000000000DA -S3152000709000000000000000000000000000000000CA -S315200070A000000000000000000000000000000000BA -S315200070B000000000000000000000000000000000AA -S315200070C0000000000000000000000000000000009A -S315200070D0000000000000000000000000000000008A -S315200070E0000000000000000000000000000000007A -S315200070F0000000000000000000000000000000006A -S315200071000000000000000000000000000000000059 -S315200071100000000000000000000000000000000049 -S315200071200000000000000000000000000000000039 -S315200071300000000000000000000000000000000029 -S315200071400000000000000000000000000000000019 -S315200071500000000000000000000000000000000009 -S3152000716000000000000000000000000000000000F9 -S3152000717000000000000000000000000000000000E9 -S3152000718000000000000000000000000000000000D9 -S3152000719000000000000000000000000000000000C9 -S315200071A000000000000000000000000000000000B9 -S315200071B000000000000000000000000000000000A9 -S315200071C00000000000000000000000000000000099 -S315200071D00000000000000000000000000000000089 -S315200071E00000000000000000000000000000000079 -S315200071F00000000000000000000000000000000069 -S315200072000000000000000000000000000000000058 -S315200072100000000000000000000000000000000048 -S315200072200000000000000000000000000000000038 -S315200072300000000000000000000000000000000028 -S315200072400000000000000000000000000000000018 -S315200072500000000000000000000000000000000008 -S3152000726000640040286E0020D56A0020000000003F -S3152000727000000000000000000000000000000000E8 -S3152000728000000000000000000000000000000000D8 -S3152000729000000000000000000000000000000000C8 -S315200072A000000000000000000000000000000000B8 -S315200072B000000000000000000000000000000000A8 -S315200072C00000000000000000000000000000000098 +S31520006B102D1300201C830020507D0020C715002047 +S31520006B20EC7E002080B584B002AF78603960494B96 +S31520006B301A4649494948FAF709F83A6848494748F8 +S31520006B40FAF704F8474B1A4643494448F9F7FEFF3B +S31520006B503B684D2B4CD03B684D2B76DC3B681F2B7E +S31520006B6012DC3B681C2B70DB3B681C3B032B6CD870 +S31520006B7001A252F823F000BFCD6B0020DF6B00206E +S31520006B80916B0020AF6B00203B68442B4CD05CE01F +S31520006B90354B354ADA60344B344A1A61344B00930C +S31520006BA0344B354A00210020F9F732FF4EE02E4BB8 +S31520006BB02D4ADA602C4B314A1A612D4B00932D4B0E +S31520006BC02D4A00210020F9F723FF3FE00023009300 +S31520006BD02B4B2C4A00210020F9F71AFF36E0002320 +S31520006BE00093294B274A00210020F9F711FF2DE0B9 +S31520006BF01D4B1B6A002B0ED11B4B1B4ADA601A4B0E +S31520006C00224A1A611A4B00931A4B1B4A0021002074 +S31520006C10F9F7FEFE1AE0002300931C4B124A0021CE +S31520006C200020F9F7F5FE11E000230093184B0E4AD9 +S31520006C3000210020F9F7ECFE00230093154B114AA2 +S31520006C4000210020F9F7E4FE00E000BF00BF08376E +S31520006C50BD4680BD647D0020C7150020EC7E002047 +S31520006C601D1600206C7D002094830020516D00208D +S31520006C709C830020937000200C830020B96D002097 +S31520006C80716F0020BC830020296F0020216E002018 +S31520006C90996E0020C16F002080B582B000AF786069 +S31520006CA0396000220A490B48F9F750FF0A4B1A4669 +S31520006CB00A490848F9F74AFF0021094800F014F864 +S31520006CC00021084800F010F900BF0837BD4680BDF6 +S31520006CD021150020EC7E0020707D0020C7150020A5 +S31520006CE094830020BC83002080B584B002AF7860F6 +S31520006CF039607B681B7E002B08D0124B1B687A6894 +S31520006D00D2691A607B6800221A7606E00D4B1B6852 +S31520006D1000221A607B6801221A767B685B690A4A20 +S31520006D2082FB03129210DB17D01A7B68596A3B68E4 +S31520006D300093064B7A68F9F76BFE00BF0837BD460D +S31520006D4080BD00BFD87E002067666666E96C00209D +S31520006D5080B592B002AF786039607B68DB69182B0A +S31520006D6004DC7B68DB695A1C7B68DA617B68DA693C +S31520006D7007F10C030B49184600F046FA07F10C03FD +S31520006D801A4609490948F9F7E1FE00230093084B02 +S31520006D90084A00210020F9F73BFE00BF4037BD46D8 +S31520006DA080BD00BF847D0020C7150020EC7E00201A +S31520006DB0DD7000200C83002080B592B002AF786091 +S31520006DC039607B68DB69012B04DD7B68DB695A1E31 +S31520006DD07B68DA617B68DA6907F10C030B49184690 +S31520006DE000F012FA07F10C031A4609490948F9F787 +S31520006DF0ADFE00230093084B084A00210020F9F736 +S31520006E0007FE00BF4037BD4680BD00BF847D002001 +S31520006E10C7150020EC7E0020DD7000200C830020AA +S31520006E2080B584B002AF786039607B681B6A002B1E +S31520006E300DD17B68DA697B681A627B680022DA6189 +S31520006E400F4B1A460F491048F9F780FE14E07B686D +S31520006E501A6A7B68DA617B6800221A620B4B1A4633 +S31520006E6008490948F9F772FE00230093084B094A9E +S31520006E7000210020F9F7CCFD00BF0837BD4680BDB4 +S31520006E80907D0020C7150020EC7E0020987D0020F4 +S31520006E90DD7000200C83002080B582B000AF7860C2 +S31520006EA039607B685B6A002B09D17B680A225A62AB +S31520006EB0094B1A4609490A48F9F748FE08E07B6853 +S31520006EC000225A62074B1A4604490548F9F73EFE46 +S31520006ED000BF0837BD4680BDA47D0020C715002011 +S31520006EE0EC7E0020B87D002080B586B002AF7860A9 +S31520006EF039600023FB6002E0FB680133FB607B689E +S31520006F009B681A46FB689342F6D37B68D9683B6830 +S31520006F100093044B7A688220F9F77AFD00BF103778 +S31520006F20BD4680BDE96E002080B590B000AF786088 +S31520006F3039607B689B6803F5FA727B689A607B6888 +S31520006F409A6807F10C030749184600F05DF907F126 +S31520006F500C031A4604490548F9F7F8FD00BF4037E7 +S31520006F60BD4680BDCC7D0020C7150020EC7E0020CC +S31520006F7080B590B000AF786039607B689B68002B45 +S31520006F8005DD7B689B68A3F5FA727B689A607B684F +S31520006F909A6807F10C030749184600F035F907F1FE +S31520006FA00C031A4604490548F9F7D0FD00BF4037BF +S31520006FB0BD4680BDCC7D0020C7150020EC7E00207C +S31520006FC080B483B000AF786039607B68DB68002BC3 +S31520006FD003D17B688222DA6002E07B680022DA60D5 +S31520006FE000BF0C37BD465DF8047B704780B500AF07 +S31520006FF0002206490648F9F79DFF00220549064862 +S31520007000F9F7FEFF0023184680BD00BF5316002067 +S31520007010EC7E0020996C0020DC7E002080B485B0B8 +S3152000702000AF786039600023FB603B681B68BB605B +S3152000703004E0BB68FB60BB681B68BB60BB68002BB9 +S31520007040F7D1FB68002B03D13B687A681A6002E00F +S31520007050FB687A681A607B6800221A6000BF1437C2 +S31520007060BD465DF8047B704780B485B000AF78607C +S315200070707B681B68FB60FB68002B03D0FB681A68E3 +S315200070807B681A60FB6818461437BD465DF8047B9A +S31520007090704780B586B002AF786039603B68FB6088 +S315200070A07B689B68002B0FDD7B689B685A1E7B687C +S315200070B09A60FB685A68FB689B6800210091002152 +S315200070C00020F9F7A5FC05E07B680C331946F86823 +S315200070D0FFF7A4FF00BF1037BD4680BD80B586B040 +S315200070E002AF786039607B68DB68002B10D07B6844 +S315200070F00C331846FFF7B8FFF860FB685A68FB6840 +S315200071009B680021009100210020F9F781FC04E012 +S315200071107B689B685A1C7B689A6000BF1037BD4607 +S3152000712080BD0000000000000000000000000000FC +S3152000713001F0FF01102A2BDB10F0070F08D010F802 +S31520007140013B013A8B422DD010F0070F42B3F6D106 +S31520007150F0B441EA012141EA014122F007047FF01F +S3152000716000070023F0E80256083C85EA010586EA76 +S31520007170010685FA47F5A3FA87F586FA47F6A5FAB2 +S3152000718087F68EB9EED1F0BC01F0FF0102F00702BE +S3152000719032B110F8013B013A83EA010313B1F8D169 +S315200071A00020704701387047002D06BF354603384A +S315200071B0073815F0010F07D1013015F4807F02BF83 +S315200071C0013015F4C03F0130F0BC0138704700BFD4 +S315200071D00CB400B59DB01EAB029106916FF0004134 +S315200071E007910491074953F8042B059102A90193AD +S315200071F000F000F9029B00221A701DB05DF804EB26 +S3152000720002B070470802FFFF0EB400B59CB01DAB5C +S31520007210029006906FF000410948079104910949B0 +S3152000722053F8042B05910068019302A900F0E2F8B7 +S31520007230029B00221A701CB05DF804EB03B0704765 +S31520007240CC8300200802FFFF2DE9F0478E689E427E +S3152000725082460C4690461F4638D88A8912F4906F8B +S3152000726032D025680969A5EB0109656905EB450555 +S3152000727005EBD57501334B446D109D4238BF1D4635 +S31520007280530531D5294600F0C1FB064650B90C23DB +S31520007290CAF80030A38943F04003A3814FF0FF30A2 +S315200072A0BDE8F08721694A4600F038FBA38923F41C +S315200072B0906343F08003A381266165614E44A5EB6C +S315200072C009052660A5603E46BE4200D93E463246A6 +S315200072D02068414600F030FBA36822689B1B32449D +S315200072E0A36022600020DBE72A4600F0E9FB064681 +S315200072F00028E1D12169504600F038FBC7E79368A2 +S315200073002DE9F74F80460C461746002B61D0002307 +S31520007310D2F800A001939B46BBF1000F2BD0A668A4 +S31520007320B34542D3A28912F4906F3ED025682169D5 +S31520007330A5EB0109656905EB450505EBD57509F151 +S3152000734001006D105844854238BF0546530545D582 +S315200073502946404600F05AFB0646A0B90C23C8F839 +S315200073600030A38943F04003A3810023C7E90133FA +S315200073704FF0FF302FE0DAF80030DAF804B001934E +S315200073800AF1080AC8E74A46216900F0C7FAA28925 +S3152000739022F4906242F08002A281266165614E4409 +S315200073A0A5EB09052660A5605E465E4528BF5E46BC +S315200073B032460199206800F0BFFAA268921BA260AB +S315200073C0226832442260BA68A2EB0B03BB60002B12 +S315200073D0D1D10020786003B0BDE8F08F2A46404620 +S315200073E000F06EFB06460028D7D12169404600F002 +S315200073F0BDFAB3E72DE9F04F98468B891B069DB061 +S3152000740007460D4614460ED50B6963B9402100F098 +S31520007410FDFA2860286120B90C233B604FF0FF302D +S31520007420D1E040236B610023099320238DF8293076 +S31520007430CDF80C803023DFF8A8818DF82A304FF064 +S31520007440010923469A4613F8012B0AB1252AF9D1B8 +S31520007450BAEB040B0BD05B46224629463846FFF78B +S31520007460F3FE013000F0AA80099A5A4409929AF84C +S315200074700030002B00F0A28000234FF0FF32CDE930 +S3152000748005230AF1010A049307938DF853301A93C2 +S315200074905446052214F8011B5148FFF749FE049A69 +S315200074A0D8B9D00644BF20238DF85330110744BFE6 +S315200074B02B238DF853309AF800302A2B15D0079AB3 +S315200074C0544600204FF00A0C214611F8013B303B70 +S315200074D0092B4ED9B0B1079214E0A0EB080309FAA4 +S315200074E003F313430493A246D2E7039B191D1B689B +S315200074F00391002BBBBF5B4242F002020793079326 +S31520007500B8BF049223782E2B0CD163782A2B35D141 +S31520007510039B1A1D1B680392002BB8BF4FF0FF3345 +S3152000752002340593DFF8C8A0217803225046FFF7DE +S31520007530FFFD40B14023A0EB0A0003FA00F0049BB4 +S3152000754003430134049314F8011B26488DF82810B0 +S315200075500622FFF7EDFD002838D0234B1BBB039BEB +S31520007560073323F0070308330393099B3344099316 +S3152000757067E70CFB02320C460120A5E70023013405 +S31520007580059319464FF00A0C204610F8012B303A85 +S31520007590092A03D9002BC5D00591C3E70CFB01218D +S315200075A004460123F0E703AB00932A460F4B04A9B8 +S315200075B03846AFF30080421C0646D6D1AB895B061F +S315200075C03FF52CAF09981DB0BDE8F08F03AB0093B3 +S315200075D02A46064B04A9384600F07AF8EBE700BFA6 +S315200075E0EC7D0020F67D002000000000497200207E +S315200075F0F27D00202DE9F047164699468A680B69E8 +S31520007600DDF820809342B8BF1346336091F84320BB +S3152000761007460C460AB1013333602368990642BFF8 +S31520007620336802333360256815F0060506D104F168 +S31520007630190AE36832689B1AAB4226DC94F8432089 +S31520007640131E226818BF012392062BD404F143028D +S3152000765049463846C04701301ED02368E56832685F +S3152000766003F00603042B08BFAD1AA36822690CBFDA +S3152000767025EAE57500259342C4BF9B1AED1800261E +S315200076801A34B5421AD1002008E001235246494651 +S315200076903846C047013003D14FF0FF30BDE8F087B0 +S315200076A00135C6E7E1185A1C302081F843002244F0 +S315200076B094F8451082F843100233C7E70123224687 +S315200076C049463846C0470130E6D00136D9E70000A2 +S315200076D02DE9FF470C469146277E0C99782F804648 +S315200076E09A4604F1430207D8622F0AD8002F00F0E9 +S315200076F0D880582F00F0A38004F1420684F8427007 +S315200077003AE0A7F16303152BF6D801A050F823F031 +S31520007710697700207D770020F9760020F976002011 +S31520007720F9760020F97600207D770020F976002072 +S31520007730F9760020F9760020F97600208978002055 +S31520007740AD7700206B780020F9760020F9760020AE +S31520007750AB780020F9760020AD770020F97600205E +S31520007760F9760020737800200B681A1D1B680A60C2 +S3152000777004F1420684F842300123A3E02568086814 +S315200077802E0600F104030AD505680B60002D03DAE6 +S315200077902D236D4284F843305E480A2319E015F004 +S315200077A0400F05680B6018BF2DB2EFE70B68256800 +S315200077B0181D0860280601D51D6802E06906FBD55C +S315200077C01D8854486F2F0CBF08230A23002184F8F4 +S315200077D043106668A660002EA2BF216821F004012E +S315200077E021600DB9002E4DD01646B5FBF3F103FBF3 +S315200077F01157C75D06F8017D2F46BB420D46F4D9C9 +S31520007800082B0BD12368DF0708D5236961689942C5 +S31520007810DEBF302306F8013C06F1FF36921B2261BB +S31520007820CDF800A04B4603AA21464046FFF7E2FECC +S3152000783001304CD14FF0FF3004B0BDE8F087354819 +S3152000784084F8457023680E681F0656F8045B0E60A0 +S3152000785014D5D90744BF43F0200323601DB92368FC +S3152000786023F0200323601023B0E7236843F020038E +S3152000787023607823284884F84530E3E75E0648BF2E +S31520007880ADB2E6E71646BBE70B68266860691D1DA4 +S315200078900D6035061B6801D5186002E07106FBD520 +S315200078A01880002323611646BAE70B681A1D0A6062 +S315200078B01E68626800213046FFF73AFC08B1801B3B +S315200078C0606063682361002384F84330A8E7236956 +S315200078D0324649464046D0470130ABD023689B0705 +S315200078E013D4E068039B9842B8BF1846A4E7012347 +S315200078F0324649464046D04701309BD00135E368A1 +S3152000790003995B1AAB42F2DCEBE7002504F119067A +S31520007910F5E700BFFD7D00200E7E00200A4491423F +S3152000792000F1FF3300D1704710B511F8014B03F871 +S31520007930014F9142F9D110BD884210B501EB0204E6 +S3152000794002D98442234607D8431EA14208D011F803 +S31520007950012B03F8012FF8E7024401468A4200D1A1 +S3152000796010BD13F8014D02F8014DF7E737B5002990 +S3152000797048D051F8043C0190002BA1F10404B8BF73 +S31520007980E41800F0D3F8204A01981368154633B955 +S315200079906360146003B0BDE8304000F0CDB8A34268 +S315200079A00BD921686218934204BF1A685B6863602A +S315200079B004BF521822602C60ECE71A465B680BB1B4 +S315200079C0A342FAD911685518A5420BD1246821443F +S315200079D05418A3421160DDD11C685B6853602144B2 +S315200079E01160D7E702D90C230360D3E72568611914 +S315200079F08B4204BF19685B68636004BF4919216024 +S31520007A005460C7E703B030BD48840020F8B5CD1CCC +S31520007A1025F0030508350C2D38BF0C25002D06460C +S31520007A2001DBA94203D90C2333600020F8BD00F006 +S31520007A307DF821490A6814469CB9204F3B6823B932 +S31520007A402146304600F062F838602946304600F07C +S31520007A505DF8431C23D10C233360304600F06CF8CC +S31520007A60E3E723685B1B17D40B2B03D923601C4445 +S31520007A70256004E06368A2420CBF0B605360304669 +S31520007A8000F05AF804F10B00231D20F00700C21A5B +S31520007A90CCD01B1AA350C9E722466468CCE7C41C85 +S31520007AA024F00304A042E3D0211A304600F02EF839 +S31520007AB00130DDD1CFE700BF488400204C84002070 +S31520007AC0F8B5074614460E4621B9BDE8F8401146DA +S31520007AD0FFF79CBF22B9FFF749FF25462846F8BD88 +S31520007AE000F030F8A0420FD221463846FFF78EFF2D +S31520007AF005460028F2D031462246FFF70FFF3146D1 +S31520007B003846FFF733FFE9E73546E7E738B5064D50 +S31520007B100023044608462B60F8F7FAFB431C02D1E3 +S31520007B202B6803B1236038BDA8070120014800F067 +S31520007B3080B800BFB0070120014800F080B800BF20 +S31520007B40B007012051F8043C181F002BBCBF0B586E +S31520007B50C018704738B50C460968054609B1FFF7C5 +S31520007B60F9FF21462846BDE83840FFF7FFBE000052 +S31520007B702C4B1B68834270B5044651D0436A43B1EF +S31520007B80DB68002B4AD1636A196811B12046FFF7DA +S31520007B90EDFE616911B12046FFF7E8FE616A11B179 +S31520007BA02046FFF7E3FEA16B11B12046FFF7DEFE6C +S31520007BB0E16B11B12046FFF7D9FE216C11B12046A9 +S31520007BC0FFF7D4FEE16D11B12046FFF7CFFEA16D80 +S31520007BD011B12046FFF7CAFE616B11B12046FFF7AF +S31520007BE0C5FEA369E3B1A36A20469847A16CB9B143 +S31520007BF02046BDE87040FFF7ADBF495941B904356D +S31520007C00636A802DD968F8D12046FFF7AFFEBAE720 +S31520007C100E682046FFF7AAFE3146EFE70025EFE77C +S31520007C2070BD00BFCC8300207047704770477047F7 +S31520007C307047704701207047012070477047704792 +S31520007C404E4F54453A205F7362726B20696E2075E1 +S31520007C507365210A0D00000050414E494321212120 +S31520007C6020000000456D707479207175657565007A +S31520007C70456D70747920706F6F6C00000A0D0000DE +S31520007C8054696E7954696D626572200076322E30A1 +S31520007C903661312028323032312D30332D313129A1 +S31520007CA00000000044657669636520495251206EC4 +S31520007CB06F7420737570706F72746564202E2E2E0B +S31520007CC0000000000A0D43414E20233120496E69F1 +S31520007CD074206661696C6564210A0D0043414E205B +S31520007CE0233220496E6974206661696C6564210AB5 +S31520007CF00D0000000A0D537472616E67653A204EBE +S31520007D006F7420612043414E202331204649464F3F +S31520007D103020495251210A0D000000000A0D5374EB +S31520007D2072616E67653A2043414E202331204649D1 +S31520007D30464F302046756C6C210A0D0043414E207B +S31520007D4054784275662066756C6C210A0D00000019 +S31520007D5043616E206D73672072656365697665641D +S31520007D603A2000005263763A20270000270A0000B6 +S31520007D7048656C6C6F2C2068656C6C6F2E2E2E0AF5 +S31520007D8000000000766F6C756D653A2025640A0048 +S31520007D906D757465640A0000756E6D757465640A88 +S31520007DA000000000656E61626C6520646561646C2C +S31520007DB0696E650A0000000064697361626C652063 +S31520007DC0646561646C696E650A0000006261636BBC +S31520007DD067726F756E64206C6F6F702072616E674C +S31520007DE0653A2025640A0000D0830020232D302BFD +S31520007DF02000686C4C006566674546470030313286 +S31520007E0033343536373839414243444546003031DC +S31520007E10323334353637383961626364656600003B +S31520007E20535643616C6C20657863657074696F6E18 +S31520007E300050656E64535620657863657074696F6B +S31520007E406E002C204558435F52455455524E203DD6 +S31520007E502000202063757272656E742074687265C6 +S31520007E6061643A204944203D20002C205350203D77 +S31520007E7020002C202A5350203D200020206E65789B +S31520007E8074207468726561643A204944203D20005C +S31520007E902C205350203D20002C202A5350203D20BA +S31520007EA0000A0D0030313233343536373839414205 +S31520007EB04344454600000000D08400206084002012 +S31520007EC0BC840020BC8400200000000001020304C2 +S31520007ED001020304060708091C7400400000000084 +S31520007EE00000000000000000580000000000000014 +S31520007EF00000000000100140DC7E0020256B0020E1 +S31520007F00000000000000000000000000000000004B +S31520007F10000000000000000000000000000000003B +S31520007F20000000000000000000000000000000002B +S31520007F30000000000000000000000000000000001B +S31520007F40000000000000000000000000000000000B +S31520007F5000000000000000000000000000000000FB +S31520007F6000000000000000000000000000000000EB +S31520007F7000000000000000000000000000000000DB +S31520007F8000000000000000000000000000000000CB +S31520007F9000000000000000000000000000000000BB +S31520007FA000000000000000000000000000000000AB +S31520007FB0000000000000000000000000000000009B +S31520007FC0000000000000000000000000000000008B +S31520007FD0000000000000000000000000000000007B +S31520007FE0000000000000000000000000000000006B +S31520007FF0000000000000000000000000000000005B +S31520008000000000000000000000000000000000004A +S31520008010000000000000000000000000000000003A +S31520008020000000000000000000000000000000002A +S31520008030000000000000000000000000000000001A +S31520008040000000000000000000000000000000000A +S3152000805000000000000000000000000000000000FA +S3152000806000000000000000000000000000000000EA +S3152000807000000000000000000000000000000000DA +S3152000808000000000000000000000000000000000CA +S3152000809000000000000000000000000000000000BA +S315200080A000000000000000000000000000000000AA +S315200080B0000000000000000000000000000000009A +S315200080C0000000000000000000000000000000008A +S315200080D0000000000000000000000000000000007A +S315200080E0000000000000000000000000000000006A +S315200080F0000000000000000000000000000000005A +S315200081000000000000000000000000000000000049 +S315200081100000000000000000000000000000000039 +S315200081200000000000000000000000000000000029 +S315200081300000000000000000000000000000000019 +S315200081400000000000000000000000000000000009 +S3152000815000000000000000000000000000000000F9 +S3152000816000000000000000000000000000000000E9 +S3152000817000000000000000000000000000000000D9 +S3152000818000000000000000000000000000000000C9 +S3152000819000000000000000000000000000000000B9 +S315200081A000000000000000000000000000000000A9 +S315200081B00000000000000000000000000000000099 +S315200081C00000000000000000000000000000000089 +S315200081D00000000000000000000000000000000079 +S315200081E00000000000000000000000000000000069 +S315200081F00000000000000000000000000000000059 +S315200082000000000000000000000000000000000048 +S315200082100000000000000000000000000000000038 +S315200082200000000000000000000000000000000028 +S315200082300000000000000000000000000000000018 +S315200082400000000000000000000000000000000008 +S3152000825000000000000000000000000000000000F8 +S3152000826000000000000000000000000000000000E8 +S3152000827000000000000000000000000000000000D8 +S3152000828000000000000000000000000000000000C8 +S3152000829000000000000000000000000000000000B8 +S315200082A000000000000000000000000000000000A8 +S315200082B00000000000000000000000000000000098 +S315200082C00000000000000000000000000000000088 +S315200082D00000000000000000000000000000000078 +S315200082E00000000000000000000000000000000068 +S315200082F00000000000000000000000000000000058 +S315200083000000000000000000000000000000000047 +S315200083100000000001000000000000000000000036 +S315200083200000000000640040DC7E0020D56A0020AA +S315200083300000000000000000000000000000000017 +S315200083400000000000000000000000000000000007 +S3152000835000000000000000000000000000000000F7 +S3152000836000000000000000000000000000000000E7 +S3152000837000000000000000000000000000000000D7 +S3152000838000000000000000000000000000000000C7 +S3152000839000000000000000000000000000000000B7 +S315200083A00000000000000000F401000001000000B1 +S315200083B005000000000000000A0000000000000088 +S315200083C000000000E803000082000000D0830020A7 +S315200083D00000000000000000000000000000000077 +S315200083E00000000000000000000000000000000067 +S315200083F00000000000000000000000000000000057 +S315200084000000000000000000000000000000000046 +S315200084100000000000000000000000000000000036 +S315200084200000000000000000000000000000000026 S70520000000DA diff --git a/Debug/application.o b/Debug/application.o index 35d734321a2c95bb9d7a4622f2e9f2951dba9412..d79de3ed3c1faa82c6c5c266e3e62041a07aeadc 100644 GIT binary patch literal 18492 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 ViWJWu&(f88KSg{z&w9nv`)|hElg
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 = true; } - SEND(USEC(self->period/2), self->deadline, self, tick, c); // step 2 + SEND(USEC(self->period), self->deadline, self, tick, c); // step 2 } From a47b9c2f659c9343da418459bd50ff49e6f90943 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Thu, 9 Feb 2023 00:09:17 +0100 Subject: [PATCH 06/29] debug --- application.c | 67 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/application.c b/application.c index 63af4ee..6d98daf 100644 --- a/application.c +++ b/application.c @@ -5,7 +5,22 @@ #include #include #include "semaphore.h" // semaphore - +#define TRUE 1 +#define FALSE 0 + +/* + * D : enable/disable deadline + * + * M: mute/unmute + * + * up arrow: increase volume + * + * down arrow: decrease volume + * + * left arrow: decrease background load + * + * right arrow: increase background load + */ typedef struct { Object super; @@ -41,6 +56,8 @@ void upVolume(ToneGenerator*, int); void downVolume(ToneGenerator*, int); void mute(ToneGenerator*, int); void enableDeadlineTG(ToneGenerator*, int); +void lockRequest(ToneGenerator*, int); +int checkMuted(ToneGenerator*, int); void backgroundLoop(Loader*, int); void increaseLoad(Loader*, int); @@ -51,7 +68,7 @@ App app = { initObject(), 0, 'X' }; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); -ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, 0, USEC(100)}; // 500 USEC 650USEC 931USEC +ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100)}; // 500 USEC 650USEC 931USEC Loader ld = {initObject(), 1000, USEC(1300)}; // app @@ -70,15 +87,10 @@ void reader(App *self, int c) { switch (c) { case 30: //up - tg.callBlock.obj = &tg; - tg.callBlock.meth = upVolume; - ASYNC(&muteVolumeSem, Wait, (int)&tg.callBlock); + ASYNC(&tg, lockRequest, (int)upVolume); break; case 31: //down - tg.callBlock.obj = &tg; - tg.callBlock.meth = downVolume; - ASYNC(&muteVolumeSem, Wait, (int)&tg.callBlock); - + ASYNC(&tg, lockRequest, (int)downVolume); break; case 28: // decrease process load ASYNC(&ld, decreaseLoad, 0); @@ -87,14 +99,13 @@ void reader(App *self, int c) { ASYNC(&ld, increaseLoad, 0); break; case 'M': // mute/unmute - if (!tg.mute) // mute need go with lock + if (SYNC(&tg, checkMuted, 0)) // sycn will return a value { - tg.callBlock.obj = &tg; - tg.callBlock.meth = mute; - ASYNC(&muteVolumeSem, Wait, (int)&tg.callBlock); - break; - } - ASYNC(&tg, mute, 0); // ummute with no lock + ASYNC(&tg, lockRequest, (int)mute); + } else { + ASYNC(&tg, mute, 0); + } + break; case 'D': // deadline enable/disable ASYNC(&tg, enableDeadlineTG, 0); @@ -110,10 +121,9 @@ void startApp(App *self, int arg) { SCI_INIT(&sci0); // ? SCI_WRITE(&sci0, "Hello, hello...\n"); - tick(&tg, 0); - backgroundLoop(&ld, 0); + ASYNC(&tg, tick, 0); // follow correct paradigm + ASYNC(&ld, backgroundLoop, 0); // - } // tone generator @@ -159,7 +169,7 @@ void mute(ToneGenerator *self, int c) { SCI_WRITE(&sci0, "muted\n"); } else { self->volume = self->mute; - self->mute = 0; + self->mute = FALSE; SCI_WRITE(&sci0, "unmuted\n"); ASYNC(&muteVolumeSem, Signal, 0); // realse lock } @@ -178,6 +188,23 @@ void enableDeadlineTG(ToneGenerator *self, int c) { } +void lockRequest(ToneGenerator* self, int c) { + self->callBlock.obj = self; + self->callBlock.meth = (Method)c; + ASYNC(&muteVolumeSem, Wait, (int)&self->callBlock); + SCI_WRITE(&sci0, "lock\n"); +} + + +int checkMuted(ToneGenerator* self, int c) { + if (!self->mute) + { + return TRUE; + } else { + return FALSE; + } +} + // loader void backgroundLoop(Loader* self, int c) { for (size_t i = 0; i < self->background_loop_range; i++) From 902d5f2f06b27b782bba123af4fdc8df91581ca6 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sat, 18 Feb 2023 02:10:42 +0100 Subject: [PATCH 07/29] part1 done --- application.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/application.c b/application.c index 6d98daf..9e5c3eb 100644 --- a/application.c +++ b/application.c @@ -44,10 +44,17 @@ typedef struct { // step 2 Time deadline; } Loader; -int* dac = (int *)0x4000741C; +typedef struct { + Time start; + Time totalMeasuredTime; + Time largestMeasuredTime; + int timeSamples; +} WCETSampler; +int* dac = (int *)0x4000741C; +/////////////////////////////////////////////////////////// void reader(App*, int); void receiver(App*, int); @@ -64,13 +71,20 @@ void increaseLoad(Loader*, int); void decreaseLoad(Loader*, int); void enableDeadlineLD(Loader*, int); +void wcetBegin(WCETSampler*); +void wcetEnd(WCETSampler*); + +/////////////////////////////////////////////////////////// App app = { initObject(), 0, 'X' }; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100)}; // 500 USEC 650USEC 931USEC Loader ld = {initObject(), 1000, USEC(1300)}; +WCETSampler wcettg = {0,0,0,0}; +WCETSampler wcetld = {0,0,0,0}; +/////////////////////////////////////////////////////////// // app void receiver(App *self, int unused) { CANMsg msg; @@ -122,13 +136,17 @@ void startApp(App *self, int arg) { SCI_INIT(&sci0); // ? SCI_WRITE(&sci0, "Hello, hello...\n"); ASYNC(&tg, tick, 0); // follow correct paradigm - ASYNC(&ld, backgroundLoop, 0); // + // ASYNC(&ld, backgroundLoop, 0); // } +/////////////////////////////////////////////////////////// // tone generator void tick(ToneGenerator *self, int c) { - if (self->lh) + wcetBegin(&wcettg); + for (size_t i = 0; i < 100; i++) + { + if (self->lh) { *dac = self->volume; self->lh = false; @@ -136,8 +154,13 @@ void tick(ToneGenerator *self, int c) { *dac = 0; self->lh = true; } + } + + + wcetEnd(&wcettg); SEND(USEC(self->period), self->deadline, self, tick, c); // step 2 + } void upVolume(ToneGenerator *self, int c) { @@ -192,7 +215,6 @@ void lockRequest(ToneGenerator* self, int c) { self->callBlock.obj = self; self->callBlock.meth = (Method)c; ASYNC(&muteVolumeSem, Wait, (int)&self->callBlock); - SCI_WRITE(&sci0, "lock\n"); } @@ -205,13 +227,15 @@ int checkMuted(ToneGenerator* self, int c) { } } +/////////////////////////////////////////////////////////// // loader void backgroundLoop(Loader* self, int c) { + // wcetBegin(&wcetld); for (size_t i = 0; i < self->background_loop_range; i++) { } - + // wcetEnd(&wcetld); SEND(USEC(1300),self->deadline, self, backgroundLoop, c); // step 2 } @@ -242,6 +266,38 @@ void enableDeadlineLD(Loader *self, int c) { } } +/////////////////////////////////////////////////////////// +void wcetBegin(WCETSampler* self) { + self->start = CURRENT_OFFSET(); +} + +void wcetEnd(WCETSampler* self) { + Time end = CURRENT_OFFSET(); + if(self->timeSamples < 500) { + self->timeSamples += 1; + + Time elapsed = end - self->start; + self->totalMeasuredTime += elapsed; + if(elapsed > self->largestMeasuredTime) { + self->largestMeasuredTime = elapsed; + } + } else { + if (self->timeSamples == 500) { + const int STRLEN = 100; + char s[STRLEN]; + + long worst = USEC_OF(self->largestMeasuredTime); + long average = USEC_OF(self->totalMeasuredTime) / self->timeSamples; + + snprintf(s, STRLEN, "Worst: %ld\nAverage: %ld\nSamples: %d", worst, average, self->timeSamples); + SCI_WRITE(&sci0, s); + + self->timeSamples += 1; + } + } +} + +/////////////////////////////////////////////////////////// int main() { INSTALL(&sci0, sci_interrupt, SCI_IRQ0); TINYTIMBER(&app, startApp, 0); From e4527a6e0e0daaac8ca685af11605642045d1cc8 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sat, 18 Feb 2023 02:19:38 +0100 Subject: [PATCH 08/29] start --- application.c | 74 +++++++++++++++++++++++---------------------------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/application.c b/application.c index 9e5c3eb..86f3426 100644 --- a/application.c +++ b/application.c @@ -38,18 +38,18 @@ typedef struct { Time deadline; } ToneGenerator; -typedef struct { // step 2 +typedef struct { Object super; int background_loop_range; Time deadline; } Loader; -typedef struct { - Time start; - Time totalMeasuredTime; - Time largestMeasuredTime; - int timeSamples; -} WCETSampler; +// typedef struct { +// Time start; +// Time totalMeasuredTime; +// Time largestMeasuredTime; +// int timeSamples; +// } WCETSampler; int* dac = (int *)0x4000741C; @@ -136,14 +136,13 @@ void startApp(App *self, int arg) { SCI_INIT(&sci0); // ? SCI_WRITE(&sci0, "Hello, hello...\n"); ASYNC(&tg, tick, 0); // follow correct paradigm - // ASYNC(&ld, backgroundLoop, 0); // + ASYNC(&ld, backgroundLoop, 0); } /////////////////////////////////////////////////////////// // tone generator void tick(ToneGenerator *self, int c) { - wcetBegin(&wcettg); for (size_t i = 0; i < 100; i++) { if (self->lh) @@ -155,9 +154,6 @@ void tick(ToneGenerator *self, int c) { self->lh = true; } } - - - wcetEnd(&wcettg); SEND(USEC(self->period), self->deadline, self, tick, c); // step 2 @@ -230,12 +226,10 @@ int checkMuted(ToneGenerator* self, int c) { /////////////////////////////////////////////////////////// // loader void backgroundLoop(Loader* self, int c) { - // wcetBegin(&wcetld); for (size_t i = 0; i < self->background_loop_range; i++) { } - // wcetEnd(&wcetld); SEND(USEC(1300),self->deadline, self, backgroundLoop, c); // step 2 } @@ -267,35 +261,35 @@ void enableDeadlineLD(Loader *self, int c) { } /////////////////////////////////////////////////////////// -void wcetBegin(WCETSampler* self) { - self->start = CURRENT_OFFSET(); -} - -void wcetEnd(WCETSampler* self) { - Time end = CURRENT_OFFSET(); - if(self->timeSamples < 500) { - self->timeSamples += 1; - - Time elapsed = end - self->start; - self->totalMeasuredTime += elapsed; - if(elapsed > self->largestMeasuredTime) { - self->largestMeasuredTime = elapsed; - } - } else { - if (self->timeSamples == 500) { - const int STRLEN = 100; - char s[STRLEN]; +// void wcetBegin(WCETSampler* self) { +// self->start = CURRENT_OFFSET(); +// } + +// void wcetEnd(WCETSampler* self) { +// Time end = CURRENT_OFFSET(); +// if(self->timeSamples < 500) { +// self->timeSamples += 1; + +// Time elapsed = end - self->start; +// self->totalMeasuredTime += elapsed; +// if(elapsed > self->largestMeasuredTime) { +// self->largestMeasuredTime = elapsed; +// } +// } else { +// if (self->timeSamples == 500) { +// const int STRLEN = 100; +// char s[STRLEN]; - long worst = USEC_OF(self->largestMeasuredTime); - long average = USEC_OF(self->totalMeasuredTime) / self->timeSamples; +// long worst = USEC_OF(self->largestMeasuredTime); +// long average = USEC_OF(self->totalMeasuredTime) / self->timeSamples; - snprintf(s, STRLEN, "Worst: %ld\nAverage: %ld\nSamples: %d", worst, average, self->timeSamples); - SCI_WRITE(&sci0, s); +// snprintf(s, STRLEN, "Worst: %ld\nAverage: %ld\nSamples: %d", worst, average, self->timeSamples); +// SCI_WRITE(&sci0, s); - self->timeSamples += 1; - } - } -} +// self->timeSamples += 1; +// } +// } +// } /////////////////////////////////////////////////////////// int main() { From 6f83294e851cd3557f46c2328b725350fa8558c3 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sat, 18 Feb 2023 23:12:40 +0100 Subject: [PATCH 09/29] except spec6 --- application.c | 187 ++++++++++++++++++++++++++------------------------ 1 file changed, 98 insertions(+), 89 deletions(-) diff --git a/application.c b/application.c index 86f3426..c79218e 100644 --- a/application.c +++ b/application.c @@ -25,7 +25,8 @@ typedef struct { Object super; int count; - char c; + int index; + char buffer[50]; } App; typedef struct { @@ -38,21 +39,21 @@ typedef struct { Time deadline; } ToneGenerator; -typedef struct { - Object super; - int background_loop_range; - Time deadline; -} Loader; -// typedef struct { -// Time start; -// Time totalMeasuredTime; -// Time largestMeasuredTime; -// int timeSamples; -// } WCETSampler; +typedef struct { + Object super; + int key; + int tempo; + int frequency_index; +} MusicPlayer; int* dac = (int *)0x4000741C; +int frequency_indices[32] = {0,2,4,0,0,2,4,0,4,5,7,4,5,7,7,9,7,5,4,0,7,9,7,5,4,0,0,-5,0,0,-5,0}; +int periods[] = {2024,1911,1803,1702,1607,1516,1431,1351,1275,1203,1136,1072,1012,955,901,851,803,758,715,675,637,601,568,536,506}; +bool keybool = false; +bool tempobool = false; + /////////////////////////////////////////////////////////// void reader(App*, int); @@ -65,24 +66,23 @@ void mute(ToneGenerator*, int); void enableDeadlineTG(ToneGenerator*, int); void lockRequest(ToneGenerator*, int); int checkMuted(ToneGenerator*, int); +void muteGap(ToneGenerator*, int); +void unMuteGap(ToneGenerator*, int); +void changeTone(ToneGenerator*, int); -void backgroundLoop(Loader*, int); -void increaseLoad(Loader*, int); -void decreaseLoad(Loader*, int); -void enableDeadlineLD(Loader*, int); - -void wcetBegin(WCETSampler*); -void wcetEnd(WCETSampler*); +void play(MusicPlayer*, int); +void changeKey(MusicPlayer*, int); +void changeTempo(MusicPlayer*, int); /////////////////////////////////////////////////////////// -App app = { initObject(), 0, 'X' }; +App app = { initObject(), 0 }; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100)}; // 500 USEC 650USEC 931USEC -Loader ld = {initObject(), 1000, USEC(1300)}; -WCETSampler wcettg = {0,0,0,0}; -WCETSampler wcetld = {0,0,0,0}; +MusicPlayer mp = {initObject(), 0, 120, 0}; + + /////////////////////////////////////////////////////////// // app @@ -94,23 +94,55 @@ void receiver(App *self, int unused) { } void reader(App *self, int c) { - + int bufferValue; + char tempBuffer[50]; SCI_WRITE(&sci0, "Rcv: \'"); SCI_WRITECHAR(&sci0, c); SCI_WRITE(&sci0, "\'\n"); switch (c) { + case '0' ... '9': + case '-': + self->buffer[self->index++] = c; + break; + case 'e': + self->buffer[self->index] = '\0'; + self->index = 0; + bufferValue = atoi(self->buffer); + sprintf(tempBuffer, "Entered integer: %d \n", bufferValue); + SCI_WRITE(&sci0, tempBuffer); + if (keybool) { + if (bufferValue<-5 || bufferValue > 5) + { + SCI_WRITE(&sci0, " -5<=key<=5, try again!\n"); + break; + } + ASYNC(&mp, changeKey, bufferValue); + break; + } + if (tempobool) { + if (bufferValue< 60 || bufferValue > 240) + { + SCI_WRITE(&sci0, " 60<=tempo<=240, try again!\n"); + break; + } + ASYNC(&mp, changeTempo, bufferValue); + break; + } + break; case 30: //up ASYNC(&tg, lockRequest, (int)upVolume); break; case 31: //down ASYNC(&tg, lockRequest, (int)downVolume); break; - case 28: // decrease process load - ASYNC(&ld, decreaseLoad, 0); + case 'K': // change key + SCI_WRITE(&sci0, "Please input the key(-5~5) you want:\n"); + keybool = true; // next input interger is saved as the key break; - case 29: // increase process load - ASYNC(&ld, increaseLoad, 0); + case 'T': // change Tempo + SCI_WRITE(&sci0, "Please input the tempo(60~240) you want:\n"); + tempobool = true; // next input interger is saved as the tempo break; case 'M': // mute/unmute if (SYNC(&tg, checkMuted, 0)) // sycn will return a value @@ -122,8 +154,6 @@ void reader(App *self, int c) { break; case 'D': // deadline enable/disable - ASYNC(&tg, enableDeadlineTG, 0); - ASYNC(&ld, enableDeadlineLD, 0); break; default: @@ -135,8 +165,8 @@ void startApp(App *self, int arg) { SCI_INIT(&sci0); // ? SCI_WRITE(&sci0, "Hello, hello...\n"); - ASYNC(&tg, tick, 0); // follow correct paradigm - ASYNC(&ld, backgroundLoop, 0); + ASYNC(&tg, tick, 0); // follow correct paradigm + ASYNC(&mp, play, 0); } @@ -223,73 +253,52 @@ int checkMuted(ToneGenerator* self, int c) { } } -/////////////////////////////////////////////////////////// -// loader -void backgroundLoop(Loader* self, int c) { - for (size_t i = 0; i < self->background_loop_range; i++) - { - - } - SEND(USEC(1300),self->deadline, self, backgroundLoop, c); // step 2 +void muteGap(ToneGenerator* self, int c) { + self->mute = self->volume; + self->volume = 0; } -void increaseLoad(Loader* self, int c) { - char tempBuffer[50]; - self->background_loop_range += 500; - sprintf(tempBuffer, "background loop range: %d\n", self->background_loop_range); - SCI_WRITE(&sci0, tempBuffer); +void unMuteGap(ToneGenerator* self, int c) { + self->volume = self->mute; + self->mute = FALSE; } -void decreaseLoad(Loader* self, int c) { - char tempBuffer[50]; - if (self->background_loop_range > 0) - { - self->background_loop_range -= 500; - } - sprintf(tempBuffer, "background loop range: %d\n", self->background_loop_range); - SCI_WRITE(&sci0, tempBuffer); - +void changeTone(ToneGenerator* self, int c) { + self->period = c; } -void enableDeadlineLD(Loader *self, int c) { - if (self->deadline == 0) - { - self->deadline = USEC(1300); - } else { - self->deadline = 0; + + + + +/////////////////////////////////////////////////////////// +// music player +void play(MusicPlayer* self, int c) { + int frequency_index; + int period; + if (self->frequency_index==32){ + self->frequency_index = 0; } + SYNC(&tg, muteGap, 0); + frequency_index = frequency_indices[self->frequency_index] + self->key; + period = periods[frequency_index+10]; + self->frequency_index++; + SYNC(&tg, changeTone, period); + AFTER(MSEC(50), &tg, unMuteGap, 0); + SEND(MSEC(60000 / self->tempo), USEC(100), self, play, 0); } +void changeKey(MusicPlayer* self, int c) { + keybool = false; + self->key = c; +} + +void changeTempo(MusicPlayer* self, int c) { + tempobool = false; + self->tempo = c; +} /////////////////////////////////////////////////////////// -// void wcetBegin(WCETSampler* self) { -// self->start = CURRENT_OFFSET(); -// } - -// void wcetEnd(WCETSampler* self) { -// Time end = CURRENT_OFFSET(); -// if(self->timeSamples < 500) { -// self->timeSamples += 1; - -// Time elapsed = end - self->start; -// self->totalMeasuredTime += elapsed; -// if(elapsed > self->largestMeasuredTime) { -// self->largestMeasuredTime = elapsed; -// } -// } else { -// if (self->timeSamples == 500) { -// const int STRLEN = 100; -// char s[STRLEN]; - -// long worst = USEC_OF(self->largestMeasuredTime); -// long average = USEC_OF(self->totalMeasuredTime) / self->timeSamples; - -// snprintf(s, STRLEN, "Worst: %ld\nAverage: %ld\nSamples: %d", worst, average, self->timeSamples); -// SCI_WRITE(&sci0, s); - -// self->timeSamples += 1; -// } -// } -// } + /////////////////////////////////////////////////////////// int main() { From 40edce8859a68e7b2827534d18cadc876e892697 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 19 Feb 2023 00:26:45 +0100 Subject: [PATCH 10/29] part2S2 done --- application.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/application.c b/application.c index c79218e..c149c4f 100644 --- a/application.c +++ b/application.c @@ -37,6 +37,7 @@ typedef struct { int volume; int mute; Time deadline; + bool muted; } ToneGenerator; @@ -79,7 +80,7 @@ App app = { initObject(), 0 }; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); -ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100)}; // 500 USEC 650USEC 931USEC +ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100), false}; // 500 USEC 650USEC 931USEC MusicPlayer mp = {initObject(), 0, 120, 0}; @@ -215,10 +216,12 @@ void mute(ToneGenerator *self, int c) { if(!self->mute) { self->mute = self->volume; self->volume = 0; + self->muted = true; SCI_WRITE(&sci0, "muted\n"); } else { self->volume = self->mute; self->mute = FALSE; + self->muted = false; SCI_WRITE(&sci0, "unmuted\n"); ASYNC(&muteVolumeSem, Signal, 0); // realse lock } @@ -254,13 +257,19 @@ int checkMuted(ToneGenerator* self, int c) { } void muteGap(ToneGenerator* self, int c) { - self->mute = self->volume; - self->volume = 0; + if(!self->muted) { + self->mute = self->volume; + self->volume = 0; + } } + void unMuteGap(ToneGenerator* self, int c) { - self->volume = self->mute; - self->mute = FALSE; + if(!self->muted) { + self->volume = self->mute; + self->mute = FALSE; + } + } void changeTone(ToneGenerator* self, int c) { From de579971442cf9c3800f6bba03686d8dcca698cf Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Wed, 22 Feb 2023 17:59:53 +0100 Subject: [PATCH 11/29] 2.22 --- application.c | 48 ++++++++++++++++-------------------------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/application.c b/application.c index c149c4f..29a59a1 100644 --- a/application.c +++ b/application.c @@ -4,24 +4,25 @@ #include #include #include -#include "semaphore.h" // semaphore +#include "semaphore.h" #define TRUE 1 #define FALSE 0 /* - * D : enable/disable deadline + * K: change key * * M: mute/unmute * + * T: change tempo + * * up arrow: increase volume * * down arrow: decrease volume * - * left arrow: decrease background load - * - * right arrow: increase background load + * Integer: end with 'e' */ + typedef struct { Object super; int count; @@ -48,7 +49,7 @@ typedef struct { int frequency_index; } MusicPlayer; - +/////////////////////////////////////////////////////////// int* dac = (int *)0x4000741C; int frequency_indices[32] = {0,2,4,0,0,2,4,0,4,5,7,4,5,7,7,9,7,5,4,0,7,9,7,5,4,0,0,-5,0,0,-5,0}; int periods[] = {2024,1911,1803,1702,1607,1516,1431,1351,1275,1203,1136,1072,1012,955,901,851,803,758,715,675,637,601,568,536,506}; @@ -64,7 +65,6 @@ void tick(ToneGenerator*, int); void upVolume(ToneGenerator*, int); void downVolume(ToneGenerator*, int); void mute(ToneGenerator*, int); -void enableDeadlineTG(ToneGenerator*, int); void lockRequest(ToneGenerator*, int); int checkMuted(ToneGenerator*, int); void muteGap(ToneGenerator*, int); @@ -112,6 +112,7 @@ void reader(App *self, int c) { bufferValue = atoi(self->buffer); sprintf(tempBuffer, "Entered integer: %d \n", bufferValue); SCI_WRITE(&sci0, tempBuffer); + // change key if (keybool) { if (bufferValue<-5 || bufferValue > 5) { @@ -121,6 +122,7 @@ void reader(App *self, int c) { ASYNC(&mp, changeKey, bufferValue); break; } + // change tempo if (tempobool) { if (bufferValue< 60 || bufferValue > 240) { @@ -154,9 +156,6 @@ void reader(App *self, int c) { } break; - case 'D': // deadline enable/disable - break; - default: break; } @@ -166,7 +165,7 @@ void startApp(App *self, int arg) { SCI_INIT(&sci0); // ? SCI_WRITE(&sci0, "Hello, hello...\n"); - ASYNC(&tg, tick, 0); // follow correct paradigm + ASYNC(&tg, tick, 0); ASYNC(&mp, play, 0); } @@ -174,9 +173,8 @@ void startApp(App *self, int arg) { /////////////////////////////////////////////////////////// // tone generator void tick(ToneGenerator *self, int c) { - for (size_t i = 0; i < 100; i++) - { - if (self->lh) + + if (self->lh) { *dac = self->volume; self->lh = false; @@ -184,15 +182,15 @@ void tick(ToneGenerator *self, int c) { *dac = 0; self->lh = true; } - } - SEND(USEC(self->period), self->deadline, self, tick, c); // step 2 + + SEND(USEC(self->period), self->deadline, self, tick, c); } void upVolume(ToneGenerator *self, int c) { char tempBuffer[50]; - if (self->volume < 25) + if (self->volume < 50) { self->volume++; } @@ -228,17 +226,6 @@ void mute(ToneGenerator *self, int c) { } -void enableDeadlineTG(ToneGenerator *self, int c) { - if (self->deadline == 0) - { - self->deadline = USEC(100); - SCI_WRITE(&sci0, "enable deadline\n"); - } else { - self->deadline = 0; - SCI_WRITE(&sci0, "disable deadline\n"); - } - -} void lockRequest(ToneGenerator* self, int c) { self->callBlock.obj = self; @@ -277,9 +264,6 @@ void changeTone(ToneGenerator* self, int c) { } - - - /////////////////////////////////////////////////////////// // music player void play(MusicPlayer* self, int c) { @@ -306,7 +290,7 @@ void changeTempo(MusicPlayer* self, int c) { tempobool = false; self->tempo = c; } -/////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////// From a9c688e39c0498672a9f9e6ab0a75267dbd4191e Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Wed, 22 Feb 2023 18:31:21 +0100 Subject: [PATCH 12/29] part2s2 d --- application.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/application.c b/application.c index 29a59a1..15b246e 100644 --- a/application.c +++ b/application.c @@ -53,6 +53,10 @@ typedef struct { int* dac = (int *)0x4000741C; int frequency_indices[32] = {0,2,4,0,0,2,4,0,4,5,7,4,5,7,7,9,7,5,4,0,7,9,7,5,4,0,0,-5,0,0,-5,0}; int periods[] = {2024,1911,1803,1702,1607,1516,1431,1351,1275,1203,1136,1072,1012,955,901,851,803,758,715,675,637,601,568,536,506}; +char tempos[] = {'a','a','a','a','a','a','a','a','a','a', + 'b','a','a','b','c','c','c','c','a','a', + 'c','c','c','c','a','a','a','a','b','a', + 'a','b'}; bool keybool = false; bool tempobool = false; @@ -269,16 +273,24 @@ void changeTone(ToneGenerator* self, int c) { void play(MusicPlayer* self, int c) { int frequency_index; int period; + double tempoFactor; if (self->frequency_index==32){ self->frequency_index = 0; } + if (tempos[self->frequency_index] == 'b') { + tempoFactor = 2.0; + } else if (tempos[self->frequency_index] == 'c'){ + tempoFactor = 0.5; + } else { + tempoFactor = 1.0; + } SYNC(&tg, muteGap, 0); frequency_index = frequency_indices[self->frequency_index] + self->key; period = periods[frequency_index+10]; self->frequency_index++; SYNC(&tg, changeTone, period); AFTER(MSEC(50), &tg, unMuteGap, 0); - SEND(MSEC(60000 / self->tempo), USEC(100), self, play, 0); + SEND(MSEC((int)60000 / self->tempo * tempoFactor), USEC(100), self, play, 0); } void changeKey(MusicPlayer* self, int c) { From 13738db2c9086cb0d31b481349469803cadf2c2b Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sat, 25 Feb 2023 18:44:54 +0100 Subject: [PATCH 13/29] s3 start --- application.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/application.c b/application.c index 15b246e..1a0a0e1 100644 --- a/application.c +++ b/application.c @@ -9,6 +9,8 @@ #define FALSE 0 /* + * S: start/stop the playing of melody + * * K: change key * * M: mute/unmute @@ -47,6 +49,7 @@ typedef struct { int key; int tempo; int frequency_index; + int start; } MusicPlayer; /////////////////////////////////////////////////////////// @@ -78,6 +81,9 @@ void changeTone(ToneGenerator*, int); void play(MusicPlayer*, int); void changeKey(MusicPlayer*, int); void changeTempo(MusicPlayer*, int); +int checkStart(MusicPlayer*, int); +void start(MusicPlayer*, int); +void stop(MusicPlayer*, int); /////////////////////////////////////////////////////////// App app = { initObject(), 0 }; @@ -85,7 +91,7 @@ Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100), false}; // 500 USEC 650USEC 931USEC -MusicPlayer mp = {initObject(), 0, 120, 0}; +MusicPlayer mp = {initObject(), 0, 120, 0, TRUE}; @@ -160,15 +166,34 @@ void reader(App *self, int c) { } break; + case 'S': + if(SYNC(&mp, checkStart, 0)) { + ASYNC(&mp, stop, 0); + } else { + ASYNC(&mp, start, 0); + } default: break; } } void startApp(App *self, int arg) { - - SCI_INIT(&sci0); // ? + CANMsg msg; + + SCI_INIT(&sci0); + CAN_INIT(&can0); SCI_WRITE(&sci0, "Hello, hello...\n"); + + msg.msgId = 1; + msg.nodeId = 1; + msg.length = 6; + msg.buff[0] = 'H'; + msg.buff[1] = 'e'; + msg.buff[2] = 'l'; + msg.buff[3] = 'l'; + msg.buff[4] = 'o'; + msg.buff[5] = 0; + CAN_SEND(&can0, &msg); ASYNC(&tg, tick, 0); ASYNC(&mp, play, 0); @@ -274,6 +299,7 @@ void play(MusicPlayer* self, int c) { int frequency_index; int period; double tempoFactor; + if (self->frequency_index==32){ self->frequency_index = 0; } @@ -303,11 +329,35 @@ void changeTempo(MusicPlayer* self, int c) { self->tempo = c; } +int checkStart(MusicPlayer* self, int c) { + return self->start; +} +void start(MusicPlayer* self, int c) { + self->start = TRUE; + self->frequency_index = 0; + if (SYNC(&tg, checkMuted, 0)) // sycn will return a value + { + ASYNC(&tg, lockRequest, (int)mute); + } else { + ASYNC(&tg, mute, 0); + } +} +void stop(MusicPlayer* self, int c) { + self->start = FALSE; + if (SYNC(&tg, checkMuted, 0)) // sycn will return a value + { + ASYNC(&tg, lockRequest, (int)mute); + } else { + ASYNC(&tg, mute, 0); + } + +} /////////////////////////////////////////////////////////// int main() { INSTALL(&sci0, sci_interrupt, SCI_IRQ0); + INSTALL(&can0, can_interrupt, CAN_IRQ0); TINYTIMBER(&app, startApp, 0); return 0; } From ddbe9b958ea8a401561bc289a7e9fd846bc7457c Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sat, 25 Feb 2023 23:27:03 +0100 Subject: [PATCH 14/29] start --- application.c | 75 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/application.c b/application.c index 1a0a0e1..9de5a79 100644 --- a/application.c +++ b/application.c @@ -7,6 +7,8 @@ #include "semaphore.h" #define TRUE 1 #define FALSE 0 +#define CONDUCTOER 1 +#define MUSICIAN 2 /* * S: start/stop the playing of melody @@ -50,6 +52,7 @@ typedef struct { int tempo; int frequency_index; int start; + int mod; } MusicPlayer; /////////////////////////////////////////////////////////// @@ -84,6 +87,7 @@ void changeTempo(MusicPlayer*, int); int checkStart(MusicPlayer*, int); void start(MusicPlayer*, int); void stop(MusicPlayer*, int); +int returnMod(MusicPlayer*, int); /////////////////////////////////////////////////////////// App app = { initObject(), 0 }; @@ -91,7 +95,7 @@ Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100), false}; // 500 USEC 650USEC 931USEC -MusicPlayer mp = {initObject(), 0, 120, 0, TRUE}; +MusicPlayer mp = {initObject(), 0, 120, 0, TRUE, CONDUCTOER}; @@ -100,8 +104,17 @@ MusicPlayer mp = {initObject(), 0, 120, 0, TRUE}; void receiver(App *self, int unused) { CANMsg msg; CAN_RECEIVE(&can0, &msg); - SCI_WRITE(&sci0, "Can msg received: "); - SCI_WRITE(&sci0, msg.buff); + char tempBuffer[50]; + int mod = SYNC(&mp, returnMod, 0); + int msg_id = msg.msgId; + if (mod == CONDUCTOER) { + SCI_WRITE(&sci0, "Can msg received: "); + SCI_WRITE(&sci0, msg.buff); + sprintf(tempBuffer, ": %d\n", (int)msg.msgId-9); + SCI_WRITE(&sci0, tempBuffer); + } else { + + } } void reader(App *self, int c) { @@ -110,7 +123,11 @@ void reader(App *self, int c) { SCI_WRITE(&sci0, "Rcv: \'"); SCI_WRITECHAR(&sci0, c); SCI_WRITE(&sci0, "\'\n"); - switch (c) + int mod = SYNC(&mp, returnMod, 0); + CANMsg msg; + if (mod == CONDUCTOER) { + + switch (c) { case '0' ... '9': case '-': @@ -118,6 +135,11 @@ void reader(App *self, int c) { break; case 'e': self->buffer[self->index] = '\0'; + msg.length = self->index; + msg.nodeId = 1; + for (int i = 0; i < self->index; i++) { + msg.buff[i] = self->buffer[i]; + } self->index = 0; bufferValue = atoi(self->buffer); sprintf(tempBuffer, "Entered integer: %d \n", bufferValue); @@ -130,6 +152,8 @@ void reader(App *self, int c) { break; } ASYNC(&mp, changeKey, bufferValue); + msg.msgId = 1; + break; } // change tempo @@ -140,8 +164,10 @@ void reader(App *self, int c) { break; } ASYNC(&mp, changeTempo, bufferValue); + msg.msgId = 2; break; } + CAN_SEND(&can0, &msg); break; case 30: //up ASYNC(&tg, lockRequest, (int)upVolume); @@ -175,6 +201,10 @@ void reader(App *self, int c) { default: break; } + } else { + + } + } void startApp(App *self, int arg) { @@ -184,18 +214,19 @@ void startApp(App *self, int arg) { CAN_INIT(&can0); SCI_WRITE(&sci0, "Hello, hello...\n"); - msg.msgId = 1; - msg.nodeId = 1; - msg.length = 6; - msg.buff[0] = 'H'; - msg.buff[1] = 'e'; - msg.buff[2] = 'l'; - msg.buff[3] = 'l'; - msg.buff[4] = 'o'; - msg.buff[5] = 0; - CAN_SEND(&can0, &msg); + // msg.msgId = 1; + // msg.nodeId = 1; + // msg.length = 6; + // msg.buff[0] = 'H'; + // msg.buff[1] = 'e'; + // msg.buff[2] = 'l'; + // msg.buff[3] = 'l'; + // msg.buff[4] = 'o'; + // msg.buff[5] = 0; + // CAN_SEND(&can0, &msg); ASYNC(&tg, tick, 0); ASYNC(&mp, play, 0); + ASYNC(&mp, stop, 0); } @@ -240,16 +271,22 @@ void downVolume(ToneGenerator *self, int c) { } void mute(ToneGenerator *self, int c) { - if(!self->mute) { + if(!self->muted) { self->mute = self->volume; self->volume = 0; self->muted = true; SCI_WRITE(&sci0, "muted\n"); } else { - self->volume = self->mute; + if (self->mute == 0) + { + self->volume = 20; + } else { + self->volume = self->mute; + } self->mute = FALSE; self->muted = false; SCI_WRITE(&sci0, "unmuted\n"); + ASYNC(&muteVolumeSem, Signal, 0); // realse lock } @@ -264,7 +301,7 @@ void lockRequest(ToneGenerator* self, int c) { int checkMuted(ToneGenerator* self, int c) { - if (!self->mute) + if (!self->muted) { return TRUE; } else { @@ -354,6 +391,10 @@ void stop(MusicPlayer* self, int c) { } } + +int returnMod(MusicPlayer* self, int c) { + return self->mod; +} /////////////////////////////////////////////////////////// int main() { INSTALL(&sci0, sci_interrupt, SCI_IRQ0); From e091fe2699fa05768193fd2a6cc8a022ade20e54 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 26 Feb 2023 00:27:16 +0100 Subject: [PATCH 15/29] s3 --- application.c | 151 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 108 insertions(+), 43 deletions(-) diff --git a/application.c b/application.c index 9de5a79..892e8e5 100644 --- a/application.c +++ b/application.c @@ -29,9 +29,9 @@ typedef struct { Object super; - int count; int index; char buffer[50]; + int mod; } App; typedef struct { @@ -52,7 +52,7 @@ typedef struct { int tempo; int frequency_index; int start; - int mod; + } MusicPlayer; /////////////////////////////////////////////////////////// @@ -71,6 +71,7 @@ bool tempobool = false; void reader(App*, int); void receiver(App*, int); + void tick(ToneGenerator*, int); void upVolume(ToneGenerator*, int); void downVolume(ToneGenerator*, int); @@ -87,15 +88,14 @@ void changeTempo(MusicPlayer*, int); int checkStart(MusicPlayer*, int); void start(MusicPlayer*, int); void stop(MusicPlayer*, int); -int returnMod(MusicPlayer*, int); /////////////////////////////////////////////////////////// -App app = { initObject(), 0 }; +App app = { initObject(), 0 , {}, CONDUCTOER}; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100), false}; // 500 USEC 650USEC 931USEC -MusicPlayer mp = {initObject(), 0, 120, 0, TRUE, CONDUCTOER}; +MusicPlayer mp = {initObject(), 0, 120, 0, TRUE}; @@ -105,29 +105,70 @@ void receiver(App *self, int unused) { CANMsg msg; CAN_RECEIVE(&can0, &msg); char tempBuffer[50]; - int mod = SYNC(&mp, returnMod, 0); int msg_id = msg.msgId; - if (mod == CONDUCTOER) { - SCI_WRITE(&sci0, "Can msg received: "); - SCI_WRITE(&sci0, msg.buff); - sprintf(tempBuffer, ": %d\n", (int)msg.msgId-9); - SCI_WRITE(&sci0, tempBuffer); - } else { - + int bufferValue = atoi(msg.buff); + switch (msg_id) { + case 1: // change key + sprintf(tempBuffer, "Can received key value: %d\n", bufferValue); + SCI_WRITE(&sci0, tempBuffer); + if (self->mod == MUSICIAN) { + ASYNC(&mp, changeKey, bufferValue); + } + break; + case 2: // change tempo + sprintf(tempBuffer, "Can received tempo value: %d\n", bufferValue); + SCI_WRITE(&sci0, tempBuffer); + if (self->mod == MUSICIAN) { + ASYNC(&mp, changeTempo, bufferValue); + } + break; + case 3: // mute + SCI_WRITE(&sci0, "Can received mute/unmute signal.\n"); + if (self->mod == MUSICIAN) { + if (SYNC(&tg, checkMuted, 0)) // sycn will return a value + { + ASYNC(&tg, lockRequest, (int)mute); + } else { + ASYNC(&tg, mute, 0); + } + } + break; + case 4: // increase volume + SCI_WRITE(&sci0, "Can received increase vol signal.\n"); + if (self->mod == MUSICIAN) { + ASYNC(&tg, lockRequest, (int)upVolume); + } + break; + case 5: // decrease volume + SCI_WRITE(&sci0, "Can received decrease vol signal.\n"); + if (self->mod == MUSICIAN) { + ASYNC(&tg, lockRequest, (int)downVolume); + } + + break; + case 6: + SCI_WRITE(&sci0, "Can received start/stop signal.\n"); + if (self->mod == MUSICIAN) { + if(SYNC(&mp, checkStart, 0)) { + ASYNC(&mp, stop, 0); + } else { + ASYNC(&mp, start, 0); + } + } + default: + break; } } void reader(App *self, int c) { int bufferValue; char tempBuffer[50]; + CANMsg msg; SCI_WRITE(&sci0, "Rcv: \'"); SCI_WRITECHAR(&sci0, c); SCI_WRITE(&sci0, "\'\n"); - int mod = SYNC(&mp, returnMod, 0); - CANMsg msg; - if (mod == CONDUCTOER) { - - switch (c) + msg.nodeId = 1; + switch (c) { case '0' ... '9': case '-': @@ -136,7 +177,6 @@ void reader(App *self, int c) { case 'e': self->buffer[self->index] = '\0'; msg.length = self->index; - msg.nodeId = 1; for (int i = 0; i < self->index; i++) { msg.buff[i] = self->buffer[i]; } @@ -151,10 +191,11 @@ void reader(App *self, int c) { SCI_WRITE(&sci0, " -5<=key<=5, try again!\n"); break; } - ASYNC(&mp, changeKey, bufferValue); + if (self->mod == CONDUCTOER) { + ASYNC(&mp, changeKey, bufferValue); + } + keybool = false; msg.msgId = 1; - - break; } // change tempo if (tempobool) { @@ -163,17 +204,29 @@ void reader(App *self, int c) { SCI_WRITE(&sci0, " 60<=tempo<=240, try again!\n"); break; } - ASYNC(&mp, changeTempo, bufferValue); + if (self->mod == CONDUCTOER) { + ASYNC(&mp, changeTempo, bufferValue); + } + tempobool = false; msg.msgId = 2; - break; } CAN_SEND(&can0, &msg); break; case 30: //up - ASYNC(&tg, lockRequest, (int)upVolume); + msg.length = 0; + msg.msgId = 4; + if (self->mod == CONDUCTOER) { + ASYNC(&tg, lockRequest, (int)upVolume); + } + CAN_SEND(&can0, &msg); break; case 31: //down - ASYNC(&tg, lockRequest, (int)downVolume); + msg.length = 0; + msg.msgId = 5; + if (self->mod == CONDUCTOER) { + ASYNC(&tg, lockRequest, (int)downVolume); + } + CAN_SEND(&can0, &msg); break; case 'K': // change key SCI_WRITE(&sci0, "Please input the key(-5~5) you want:\n"); @@ -184,31 +237,46 @@ void reader(App *self, int c) { tempobool = true; // next input interger is saved as the tempo break; case 'M': // mute/unmute - if (SYNC(&tg, checkMuted, 0)) // sycn will return a value - { - ASYNC(&tg, lockRequest, (int)mute); - } else { - ASYNC(&tg, mute, 0); + msg.length = 0; + msg.msgId = 3; + if (self->mod == CONDUCTOER) { + if (SYNC(&tg, checkMuted, 0)) // sycn will return a value + { + ASYNC(&tg, lockRequest, (int)mute); + } else { + ASYNC(&tg, mute, 0); + } } - + CAN_SEND(&can0, &msg); break; case 'S': - if(SYNC(&mp, checkStart, 0)) { - ASYNC(&mp, stop, 0); + msg.length = 0; + msg.msgId = 6; + if (self->mod == CONDUCTOER) { + if(SYNC(&mp, checkStart, 0)) { + ASYNC(&mp, stop, 0); + } else { + ASYNC(&mp, start, 0); + } + } + CAN_SEND(&can0, &msg); + break; + case 'C': + if (self->mod == CONDUCTOER) { + self->mod = MUSICIAN; + SCI_WRITE(&sci0, "change to musician mod\n"); } else { - ASYNC(&mp, start, 0); + self->mod = CONDUCTOER; + SCI_WRITE(&sci0, "Change to conductoer mod\n"); } + break; default: break; } - } else { - - } - + } void startApp(App *self, int arg) { - CANMsg msg; SCI_INIT(&sci0); CAN_INIT(&can0); @@ -392,9 +460,6 @@ void stop(MusicPlayer* self, int c) { } -int returnMod(MusicPlayer* self, int c) { - return self->mod; -} /////////////////////////////////////////////////////////// int main() { INSTALL(&sci0, sci_interrupt, SCI_IRQ0); From 28fb4bf8675f147f6bf6bdade0e70ab4228adab5 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 26 Feb 2023 00:34:01 +0100 Subject: [PATCH 16/29] makefile --- Makefile | 7 +++++-- sioTinyTimber.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ sioTinyTimber.h | 35 +++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 sioTinyTimber.c create mode 100644 sioTinyTimber.h diff --git a/Makefile b/Makefile index 946b40b..fbe373f 100644 --- a/Makefile +++ b/Makefile @@ -55,7 +55,8 @@ OBJECTS= $(DEBUGDIR)dispatch.o \ $(DEBUGDIR)stm32f4xx_usart.o \ $(DEBUGDIR)startup.o \ $(DEBUGDIR)application.o \ - $(DEBUGDIR)semaphore.o + $(DEBUGDIR)semaphore.o \ + $(DEBUGDIR)sioTinyTimber.o \ ### ### Main target @@ -103,9 +104,11 @@ $(DEBUGDIR)sciTinyTimber.o: sciTinyTimber.c sciTinyTimber.h $(CC) -c $< -o $@ $(CCFLAGS) $(DEBUGDIR)semaphore.o: semaphore.c semaphore.h $(CC) -c $< -o $@ $(CCFLAGS) +$(DEBUGDIR)sioTinyTimber.o: sioTinyTimber.c sioTinyTimber.h + $(CC) -c $< -o $@ $(CCFLAGS) # User-defined targets -$(DEBUGDIR)application.o: application.c TinyTimber.h sciTinyTimber.h canTinyTimber.h semaphore.h +$(DEBUGDIR)application.o: application.c TinyTimber.h sciTinyTimber.h canTinyTimber.h semaphore.h sioTinyTimber.h $(CC) -c $< -o $@ $(CCFLAGS) ### diff --git a/sioTinyTimber.c b/sioTinyTimber.c new file mode 100644 index 0000000..973d0a2 --- /dev/null +++ b/sioTinyTimber.c @@ -0,0 +1,52 @@ +#include "TinyTimber.h" +#include "sioTinyTimber.h" + +void sio_init(SysIO *self, int unused) { + + GPIO_WriteBit(GPIOB, GPIO_Pin_0, (BitAction) 0); // Green LED On + + NVIC_SetPriority( EXTI9_5_IRQn, __IRQ_PRIORITY); + NVIC_EnableIRQ( EXTI9_5_IRQn ); +} + +int sio_read(SysIO *self, int unused) { + return GPIO_ReadInputDataBit(self->port, GPIO_Pin_7); +} + +void sio_write(SysIO *self, int val) { + GPIO_WriteBit(self->port, GPIO_Pin_0, (BitAction) val); +} + +void sio_toggle(SysIO *self, int unused) { + GPIO_ToggleBits(self->port, GPIO_Pin_0); +} + +void sio_trig(SysIO *self, int rise) { + EXTI_InitTypeDef EXTI_InitStructure; + + EXTI_StructInit( &EXTI_InitStructure); + EXTI_InitStructure.EXTI_Line = EXTI_Line7; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = rise ? EXTI_Trigger_Rising : EXTI_Trigger_Falling; + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init( &EXTI_InitStructure); +} + +void DUMP(char *s); + +int sio_interrupt(SysIO *self, int unused) { + if (EXTI_GetITStatus(EXTI_Line7) == SET) { +// DUMP("\n\rYey! A GPIOB bit7 IRQ!\n\r"); + + EXTI_ClearITPendingBit(EXTI_Line7); // remove interrupt request + + if (self->obj) { + ASYNC(self->obj, self->meth, 0); + doIRQSchedule = 1; + } + } else { + DUMP("\n\rStrange: Not a GPIOB bit7 IRQ!\n\r"); + } + + return 0; +} diff --git a/sioTinyTimber.h b/sioTinyTimber.h new file mode 100644 index 0000000..5199fd8 --- /dev/null +++ b/sioTinyTimber.h @@ -0,0 +1,35 @@ +#ifndef SIO_TINYT_H +#define SIO_TINYT_H + +#include "stm32f4xx.h" +#include "stm32f4xx_gpio.h" +#include "stm32f4xx_exti.h" + +typedef struct { + Object super; + GPIO_TypeDef *port; + Object *obj; + Method meth; +} SysIO; + +#define initSysIO(port, obj, meth) \ + { initObject(), port, (Object*)obj, (Method)meth } + +#define SIO_PORT0 (GPIO_TypeDef *)(GPIOB) +#define SIO_IRQ0 IRQ_EXTI9_5 + +void sio_init(SysIO *sio, int unused); +int sio_read(SysIO *sio, int unused); +void sio_write(SysIO *sio, int val); +void sio_toggle(SysIO *sio, int unused); +void sio_trig(SysIO *sio, int rise); + +#define SIO_INIT(sio) SYNC(sio, sio_init, 0) +#define SIO_READ(sio) SYNC(sio, sio_read, 0) +#define SIO_WRITE(sio,val) SYNC(sio, sio_write, val) +#define SIO_TOGGLE(sio) SYNC(sio, sio_toggle, 0) +#define SIO_TRIG(sio,rise) SYNC(sio, sio_trig, rise) + +int sio_interrupt(SysIO *self, int unused); + +#endif From ddbe6c814173b5540c21fa3615f9ebb7221ea09f Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 26 Feb 2023 01:12:10 +0100 Subject: [PATCH 17/29] clean --- application.c | 192 +++++++++++++++++++------------------------------- 1 file changed, 72 insertions(+), 120 deletions(-) diff --git a/application.c b/application.c index 892e8e5..65c3d07 100644 --- a/application.c +++ b/application.c @@ -5,10 +5,9 @@ #include #include #include "semaphore.h" +#include "sioTinyTimber.h" #define TRUE 1 #define FALSE 0 -#define CONDUCTOER 1 -#define MUSICIAN 2 /* * S: start/stop the playing of melody @@ -31,7 +30,6 @@ typedef struct { Object super; int index; char buffer[50]; - int mod; } App; typedef struct { @@ -70,6 +68,7 @@ bool tempobool = false; /////////////////////////////////////////////////////////// void reader(App*, int); void receiver(App*, int); +void buttonF(App*, int); void tick(ToneGenerator*, int); @@ -90,10 +89,11 @@ void start(MusicPlayer*, int); void stop(MusicPlayer*, int); /////////////////////////////////////////////////////////// -App app = { initObject(), 0 , {}, CONDUCTOER}; +App app = { initObject(), 0 , {}}; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted -Can can0 = initCan(CAN_PORT0, &app, receiver); +Can can0 = initCan(CAN_PORT0, &app, receiver); +SysIO button = initSysIO(SIO_PORT0, &app, buttonF); ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100), false}; // 500 USEC 650USEC 931USEC MusicPlayer mp = {initObject(), 0, 120, 0, TRUE}; @@ -102,72 +102,70 @@ MusicPlayer mp = {initObject(), 0, 120, 0, TRUE}; /////////////////////////////////////////////////////////// // app void receiver(App *self, int unused) { - CANMsg msg; - CAN_RECEIVE(&can0, &msg); - char tempBuffer[50]; - int msg_id = msg.msgId; - int bufferValue = atoi(msg.buff); - switch (msg_id) { - case 1: // change key - sprintf(tempBuffer, "Can received key value: %d\n", bufferValue); - SCI_WRITE(&sci0, tempBuffer); - if (self->mod == MUSICIAN) { - ASYNC(&mp, changeKey, bufferValue); - } - break; - case 2: // change tempo - sprintf(tempBuffer, "Can received tempo value: %d\n", bufferValue); - SCI_WRITE(&sci0, tempBuffer); - if (self->mod == MUSICIAN) { - ASYNC(&mp, changeTempo, bufferValue); - } - break; - case 3: // mute - SCI_WRITE(&sci0, "Can received mute/unmute signal.\n"); - if (self->mod == MUSICIAN) { - if (SYNC(&tg, checkMuted, 0)) // sycn will return a value - { - ASYNC(&tg, lockRequest, (int)mute); - } else { - ASYNC(&tg, mute, 0); - } - } - break; - case 4: // increase volume - SCI_WRITE(&sci0, "Can received increase vol signal.\n"); - if (self->mod == MUSICIAN) { - ASYNC(&tg, lockRequest, (int)upVolume); - } - break; - case 5: // decrease volume - SCI_WRITE(&sci0, "Can received decrease vol signal.\n"); - if (self->mod == MUSICIAN) { - ASYNC(&tg, lockRequest, (int)downVolume); - } + // CANMsg msg; + // CAN_RECEIVE(&can0, &msg); + // char tempBuffer[50]; + // int msg_id = msg.msgId; + // int bufferValue = atoi(msg.buff); + // switch (msg_id) { + // case 1: // change key + // sprintf(tempBuffer, "Can received key value: %d\n", bufferValue); + // SCI_WRITE(&sci0, tempBuffer); + // if (self->mod == MUSICIAN) { + // ASYNC(&mp, changeKey, bufferValue); + // } + // break; + // case 2: // change tempo + // sprintf(tempBuffer, "Can received tempo value: %d\n", bufferValue); + // SCI_WRITE(&sci0, tempBuffer); + // if (self->mod == MUSICIAN) { + // ASYNC(&mp, changeTempo, bufferValue); + // } + // break; + // case 3: // mute + // SCI_WRITE(&sci0, "Can received mute/unmute signal.\n"); + // if (self->mod == MUSICIAN) { + // if (SYNC(&tg, checkMuted, 0)) // sycn will return a value + // { + // ASYNC(&tg, lockRequest, (int)mute); + // } else { + // ASYNC(&tg, mute, 0); + // } + // } + // break; + // case 4: // increase volume + // SCI_WRITE(&sci0, "Can received increase vol signal.\n"); + // if (self->mod == MUSICIAN) { + // ASYNC(&tg, lockRequest, (int)upVolume); + // } + // break; + // case 5: // decrease volume + // SCI_WRITE(&sci0, "Can received decrease vol signal.\n"); + // if (self->mod == MUSICIAN) { + // ASYNC(&tg, lockRequest, (int)downVolume); + // } - break; - case 6: - SCI_WRITE(&sci0, "Can received start/stop signal.\n"); - if (self->mod == MUSICIAN) { - if(SYNC(&mp, checkStart, 0)) { - ASYNC(&mp, stop, 0); - } else { - ASYNC(&mp, start, 0); - } - } - default: - break; - } + // break; + // case 6: + // SCI_WRITE(&sci0, "Can received start/stop signal.\n"); + // if (self->mod == MUSICIAN) { + // if(SYNC(&mp, checkStart, 0)) { + // ASYNC(&mp, stop, 0); + // } else { + // ASYNC(&mp, start, 0); + // } + // } + // default: + // break; + // } } void reader(App *self, int c) { int bufferValue; char tempBuffer[50]; - CANMsg msg; SCI_WRITE(&sci0, "Rcv: \'"); SCI_WRITECHAR(&sci0, c); SCI_WRITE(&sci0, "\'\n"); - msg.nodeId = 1; switch (c) { case '0' ... '9': @@ -176,10 +174,6 @@ void reader(App *self, int c) { break; case 'e': self->buffer[self->index] = '\0'; - msg.length = self->index; - for (int i = 0; i < self->index; i++) { - msg.buff[i] = self->buffer[i]; - } self->index = 0; bufferValue = atoi(self->buffer); sprintf(tempBuffer, "Entered integer: %d \n", bufferValue); @@ -191,11 +185,7 @@ void reader(App *self, int c) { SCI_WRITE(&sci0, " -5<=key<=5, try again!\n"); break; } - if (self->mod == CONDUCTOER) { - ASYNC(&mp, changeKey, bufferValue); - } - keybool = false; - msg.msgId = 1; + ASYNC(&mp, changeKey, bufferValue); } // change tempo if (tempobool) { @@ -204,29 +194,14 @@ void reader(App *self, int c) { SCI_WRITE(&sci0, " 60<=tempo<=240, try again!\n"); break; } - if (self->mod == CONDUCTOER) { - ASYNC(&mp, changeTempo, bufferValue); - } - tempobool = false; - msg.msgId = 2; + ASYNC(&mp, changeTempo, bufferValue); } - CAN_SEND(&can0, &msg); break; case 30: //up - msg.length = 0; - msg.msgId = 4; - if (self->mod == CONDUCTOER) { - ASYNC(&tg, lockRequest, (int)upVolume); - } - CAN_SEND(&can0, &msg); + ASYNC(&tg, lockRequest, (int)upVolume); break; case 31: //down - msg.length = 0; - msg.msgId = 5; - if (self->mod == CONDUCTOER) { - ASYNC(&tg, lockRequest, (int)downVolume); - } - CAN_SEND(&can0, &msg); + ASYNC(&tg, lockRequest, (int)downVolume); break; case 'K': // change key SCI_WRITE(&sci0, "Please input the key(-5~5) you want:\n"); @@ -237,38 +212,20 @@ void reader(App *self, int c) { tempobool = true; // next input interger is saved as the tempo break; case 'M': // mute/unmute - msg.length = 0; - msg.msgId = 3; - if (self->mod == CONDUCTOER) { if (SYNC(&tg, checkMuted, 0)) // sycn will return a value { ASYNC(&tg, lockRequest, (int)mute); } else { ASYNC(&tg, mute, 0); } - } - CAN_SEND(&can0, &msg); break; case 'S': - msg.length = 0; - msg.msgId = 6; - if (self->mod == CONDUCTOER) { + if(SYNC(&mp, checkStart, 0)) { ASYNC(&mp, stop, 0); } else { ASYNC(&mp, start, 0); } - } - CAN_SEND(&can0, &msg); - break; - case 'C': - if (self->mod == CONDUCTOER) { - self->mod = MUSICIAN; - SCI_WRITE(&sci0, "change to musician mod\n"); - } else { - self->mod = CONDUCTOER; - SCI_WRITE(&sci0, "Change to conductoer mod\n"); - } break; default: break; @@ -276,28 +233,22 @@ void reader(App *self, int c) { } + void startApp(App *self, int arg) { SCI_INIT(&sci0); - CAN_INIT(&can0); + CAN_INIT(&can0); + SIO_INIT(&button); SCI_WRITE(&sci0, "Hello, hello...\n"); - - // msg.msgId = 1; - // msg.nodeId = 1; - // msg.length = 6; - // msg.buff[0] = 'H'; - // msg.buff[1] = 'e'; - // msg.buff[2] = 'l'; - // msg.buff[3] = 'l'; - // msg.buff[4] = 'o'; - // msg.buff[5] = 0; - // CAN_SEND(&can0, &msg); ASYNC(&tg, tick, 0); ASYNC(&mp, play, 0); ASYNC(&mp, stop, 0); } +void buttonF(App* self, int c) { + SCI_WRITE(&sci0, "button \n"); +} /////////////////////////////////////////////////////////// // tone generator void tick(ToneGenerator *self, int c) { @@ -464,6 +415,7 @@ void stop(MusicPlayer* self, int c) { int main() { INSTALL(&sci0, sci_interrupt, SCI_IRQ0); INSTALL(&can0, can_interrupt, CAN_IRQ0); + INSTALL(&button, sio_interrupt, SIO_IRQ0); TINYTIMBER(&app, startApp, 0); return 0; } From 57bb3305c96c9777a51c09719e4c83a2e715fba8 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 26 Feb 2023 01:34:35 +0100 Subject: [PATCH 18/29] button --- application.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/application.c b/application.c index 65c3d07..ffc68df 100644 --- a/application.c +++ b/application.c @@ -53,6 +53,10 @@ typedef struct { } MusicPlayer; +typedef struct { + Object super; + +} Button; /////////////////////////////////////////////////////////// int* dac = (int *)0x4000741C; int frequency_indices[32] = {0,2,4,0,0,2,4,0,4,5,7,4,5,7,7,9,7,5,4,0,7,9,7,5,4,0,0,-5,0,0,-5,0}; @@ -68,7 +72,8 @@ bool tempobool = false; /////////////////////////////////////////////////////////// void reader(App*, int); void receiver(App*, int); -void buttonF(App*, int); + +void press(Button*, int); void tick(ToneGenerator*, int); @@ -93,7 +98,8 @@ App app = { initObject(), 0 , {}}; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); -SysIO button = initSysIO(SIO_PORT0, &app, buttonF); +Button bt = {initObject()}; +SysIO button = initSysIO(SIO_PORT0, &bt, press); ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100), false}; // 500 USEC 650USEC 931USEC MusicPlayer mp = {initObject(), 0, 120, 0, TRUE}; @@ -246,9 +252,7 @@ void startApp(App *self, int arg) { } -void buttonF(App* self, int c) { - SCI_WRITE(&sci0, "button \n"); -} + /////////////////////////////////////////////////////////// // tone generator void tick(ToneGenerator *self, int c) { @@ -410,6 +414,10 @@ void stop(MusicPlayer* self, int c) { } } +/////////////////////////////////////////////////////////// +void press(Button* self, int c) { + SCI_WRITE(&sci0, "button \n"); +} /////////////////////////////////////////////////////////// int main() { From 6c23dec5c6dc2f9a0f5f5ba735630cb9c701b3db Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 26 Feb 2023 17:51:51 +0100 Subject: [PATCH 19/29] ok --- application.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/application.c b/application.c index ffc68df..1668107 100644 --- a/application.c +++ b/application.c @@ -8,6 +8,8 @@ #include "sioTinyTimber.h" #define TRUE 1 #define FALSE 0 +#define HOLD 0 +#define MOMENTARY 1 /* * S: start/stop the playing of melody @@ -55,7 +57,11 @@ typedef struct { typedef struct { Object super; - + Timer timer; + Time last; + int count; + int mod; + Time smaples[3]; } Button; /////////////////////////////////////////////////////////// int* dac = (int *)0x4000741C; @@ -74,6 +80,8 @@ void reader(App*, int); void receiver(App*, int); void press(Button*, int); +void check1Sec(Button*, int); +int timeToBPM(Time); void tick(ToneGenerator*, int); @@ -98,7 +106,7 @@ App app = { initObject(), 0 , {}}; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); -Button bt = {initObject()}; +Button bt = {initObject(), initTimer(), 0, 0, MOMENTARY, {}}; SysIO button = initSysIO(SIO_PORT0, &bt, press); ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100), false}; // 500 USEC 650USEC 931USEC MusicPlayer mp = {initObject(), 0, 120, 0, TRUE}; @@ -416,9 +424,87 @@ void stop(MusicPlayer* self, int c) { } /////////////////////////////////////////////////////////// void press(Button* self, int c) { - SCI_WRITE(&sci0, "button \n"); + char tempBuffer[50]; + + if (self->mod == MOMENTARY) { + SCI_WRITE(&sci0, "button pressed\n"); + if(self->count == 0) { + T_RESET(&self->timer); + self->count += 1; + + return; + } + + Time now = T_SAMPLE(&self->timer); + Time sinceLast = now - self->last; + if (sinceLast < MSEC(100)) { + SCI_WRITE(&sci0, "Ignoring contact bounce\n"); + return; + } + self->last = now; + + sprintf(tempBuffer, "msec: %ld\n", sinceLast/100); + SCI_WRITE(&sci0, tempBuffer); + + self->smaples[self->count - 1] = sinceLast/100; + self->count++; + if (self->count == 4) { + self->count = 0; + self->last = 0; + Time average = 0; + snprintf(tempBuffer, 100, " %ld. %ld.%ld. \n", self->smaples[0], self->smaples[1], self->smaples[2]); + SCI_WRITE(&sci0, tempBuffer); + if (self->smaples[1]-self->smaples[0] < 200 && self->smaples[2]-self->smaples[1] < 200) { + for (size_t i = 0; i < 3; i++) + { + average += self->smaples[i]; + } + average /= 3; + int bpm = timeToBPM(average); + if (bpm >= 30 && bpm <= 300) { + snprintf(tempBuffer, 100, "Nice beat. Setting BPM to %d.\n", bpm); + SYNC(&mp, changeTempo, bpm); + SCI_WRITE(&sci0, tempBuffer); + } else { + snprintf(tempBuffer, 100, "BPM: %d out of range [30..300]\n", bpm); + SCI_WRITE(&sci0, tempBuffer); + } + } else { + SCI_WRITE(&sci0, "not comparable length \n"); + return; + } + + } + AFTER(SEC(1), &bt, check1Sec, self->count); + } else { + SCI_WRITE(&sci0, "button released\n"); + self->count++; + Time now = T_SAMPLE(&self->timer); + Time sinceLast = now - self->last; + self->last = now; + sprintf(tempBuffer, "sec: %ld\n", sinceLast/100000); + SCI_WRITE(&sci0, tempBuffer); + SIO_TRIG(&button, 0); + self->mod = MOMENTARY; + + } + +} + +void check1Sec(Button* self, int c) { + if (c == self->count && SIO_READ(&button)==0) { + SCI_WRITE(&sci0, "holding more than 1 sec, switch to PRESS-AND-HOLD\n"); + self->mod = HOLD; + SIO_TRIG(&button, 1); + } + } +int timeToBPM(Time time) { + return (60.0 / time) * 1000; +} + + /////////////////////////////////////////////////////////// int main() { INSTALL(&sci0, sci_interrupt, SCI_IRQ0); From c4cc95000d59e852329cfae510dfd365e7376b91 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 26 Feb 2023 17:59:16 +0100 Subject: [PATCH 20/29] nice --- application.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/application.c b/application.c index 1668107..4634a70 100644 --- a/application.c +++ b/application.c @@ -478,12 +478,20 @@ void press(Button* self, int c) { AFTER(SEC(1), &bt, check1Sec, self->count); } else { SCI_WRITE(&sci0, "button released\n"); - self->count++; + // self->count++; Time now = T_SAMPLE(&self->timer); Time sinceLast = now - self->last; self->last = now; - sprintf(tempBuffer, "sec: %ld\n", sinceLast/100000); - SCI_WRITE(&sci0, tempBuffer); + if (sinceLast/100000 < 2) { + sprintf(tempBuffer, "sec: %ld < 2, hold button 2 sec to reset\n", sinceLast/100000); + SCI_WRITE(&sci0, tempBuffer); + } else { + SCI_WRITE(&sci0, "reset tempo \n"); + self->count = 0; + self->last = 0; + ASYNC(&mp, changeTempo, 120); + } + SIO_TRIG(&button, 0); self->mod = MOMENTARY; From ca8595a790ae7dc38b69a1c36cb3cfe61c074ac9 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 26 Feb 2023 18:21:05 +0100 Subject: [PATCH 21/29] s4 temp + led --- application.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/application.c b/application.c index 4634a70..b32121c 100644 --- a/application.c +++ b/application.c @@ -63,6 +63,8 @@ typedef struct { int mod; Time smaples[3]; } Button; + + /////////////////////////////////////////////////////////// int* dac = (int *)0x4000741C; int frequency_indices[32] = {0,2,4,0,0,2,4,0,4,5,7,4,5,7,7,9,7,5,4,0,7,9,7,5,4,0,0,-5,0,0,-5,0}; @@ -273,7 +275,6 @@ void tick(ToneGenerator *self, int c) { *dac = 0; self->lh = true; } - SEND(USEC(self->period), self->deadline, self, tick, c); @@ -384,6 +385,8 @@ void play(MusicPlayer* self, int c) { self->frequency_index++; SYNC(&tg, changeTone, period); AFTER(MSEC(50), &tg, unMuteGap, 0); + SIO_TOGGLE(&button); + AFTER(MSEC((int)30000 / self->tempo * tempoFactor), &button, sio_toggle, 0); SEND(MSEC((int)60000 / self->tempo * tempoFactor), USEC(100), self, play, 0); } From 85591269ce7a1bab984e5a94ae96066cb7dff634 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Wed, 1 Mar 2023 18:51:34 +0100 Subject: [PATCH 22/29] 3.1 --- application.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/application.c b/application.c index b32121c..7337126 100644 --- a/application.c +++ b/application.c @@ -490,6 +490,8 @@ void press(Button* self, int c) { SCI_WRITE(&sci0, tempBuffer); } else { SCI_WRITE(&sci0, "reset tempo \n"); + sprintf(tempBuffer, "sec: %ld\n", sinceLast/100000); + SCI_WRITE(&sci0, tempBuffer); self->count = 0; self->last = 0; ASYNC(&mp, changeTempo, 120); From 9d72eb6495542e67d25ca1f1e828b18ebc2ec851 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Thu, 2 Mar 2023 20:08:39 +0100 Subject: [PATCH 23/29] debug --- application.c | 136 ++++++++++++++++++++++---------------------------- 1 file changed, 61 insertions(+), 75 deletions(-) diff --git a/application.c b/application.c index 7337126..e3d04f4 100644 --- a/application.c +++ b/application.c @@ -12,6 +12,8 @@ #define MOMENTARY 1 /* + * User Button: Tap tempo + * * S: start/stop the playing of melody * * K: change key @@ -43,6 +45,7 @@ typedef struct { int mute; Time deadline; bool muted; + int start; } ToneGenerator; @@ -65,6 +68,7 @@ typedef struct { } Button; + /////////////////////////////////////////////////////////// int* dac = (int *)0x4000741C; int frequency_indices[32] = {0,2,4,0,0,2,4,0,4,5,7,4,5,7,7,9,7,5,4,0,7,9,7,5,4,0,0,-5,0,0,-5,0}; @@ -77,6 +81,7 @@ bool keybool = false; bool tempobool = false; + /////////////////////////////////////////////////////////// void reader(App*, int); void receiver(App*, int); @@ -84,6 +89,7 @@ void receiver(App*, int); void press(Button*, int); void check1Sec(Button*, int); int timeToBPM(Time); +bool checkComparable(Time, Time, Time); void tick(ToneGenerator*, int); @@ -95,6 +101,8 @@ int checkMuted(ToneGenerator*, int); void muteGap(ToneGenerator*, int); void unMuteGap(ToneGenerator*, int); void changeTone(ToneGenerator*, int); +void startTG(ToneGenerator*, int); +void stopTG(ToneGenerator*, int); void play(MusicPlayer*, int); void changeKey(MusicPlayer*, int); @@ -103,6 +111,8 @@ int checkStart(MusicPlayer*, int); void start(MusicPlayer*, int); void stop(MusicPlayer*, int); + + /////////////////////////////////////////////////////////// App app = { initObject(), 0 , {}}; Serial sci0 = initSerial(SCI_PORT0, &app, reader); @@ -110,70 +120,16 @@ Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); Button bt = {initObject(), initTimer(), 0, 0, MOMENTARY, {}}; SysIO button = initSysIO(SIO_PORT0, &bt, press); -ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100), false}; // 500 USEC 650USEC 931USEC +ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100), false,TRUE}; // 500 USEC 650USEC 931USEC MusicPlayer mp = {initObject(), 0, 120, 0, TRUE}; + /////////////////////////////////////////////////////////// // app void receiver(App *self, int unused) { - // CANMsg msg; - // CAN_RECEIVE(&can0, &msg); - // char tempBuffer[50]; - // int msg_id = msg.msgId; - // int bufferValue = atoi(msg.buff); - // switch (msg_id) { - // case 1: // change key - // sprintf(tempBuffer, "Can received key value: %d\n", bufferValue); - // SCI_WRITE(&sci0, tempBuffer); - // if (self->mod == MUSICIAN) { - // ASYNC(&mp, changeKey, bufferValue); - // } - // break; - // case 2: // change tempo - // sprintf(tempBuffer, "Can received tempo value: %d\n", bufferValue); - // SCI_WRITE(&sci0, tempBuffer); - // if (self->mod == MUSICIAN) { - // ASYNC(&mp, changeTempo, bufferValue); - // } - // break; - // case 3: // mute - // SCI_WRITE(&sci0, "Can received mute/unmute signal.\n"); - // if (self->mod == MUSICIAN) { - // if (SYNC(&tg, checkMuted, 0)) // sycn will return a value - // { - // ASYNC(&tg, lockRequest, (int)mute); - // } else { - // ASYNC(&tg, mute, 0); - // } - // } - // break; - // case 4: // increase volume - // SCI_WRITE(&sci0, "Can received increase vol signal.\n"); - // if (self->mod == MUSICIAN) { - // ASYNC(&tg, lockRequest, (int)upVolume); - // } - // break; - // case 5: // decrease volume - // SCI_WRITE(&sci0, "Can received decrease vol signal.\n"); - // if (self->mod == MUSICIAN) { - // ASYNC(&tg, lockRequest, (int)downVolume); - // } - - // break; - // case 6: - // SCI_WRITE(&sci0, "Can received start/stop signal.\n"); - // if (self->mod == MUSICIAN) { - // if(SYNC(&mp, checkStart, 0)) { - // ASYNC(&mp, stop, 0); - // } else { - // ASYNC(&mp, start, 0); - // } - // } - // default: - // break; - // } + } void reader(App *self, int c) { @@ -263,10 +219,14 @@ void startApp(App *self, int arg) { } + + /////////////////////////////////////////////////////////// // tone generator void tick(ToneGenerator *self, int c) { - + if (!self->start) { + return; + } if (self->lh) { *dac = self->volume; @@ -361,6 +321,18 @@ void changeTone(ToneGenerator* self, int c) { self->period = c; } +void startTG(ToneGenerator* self, int c) { + self->start = TRUE; + +} + +void stopTG(ToneGenerator* self, int c) { + self->start = FALSE; + +} + + + /////////////////////////////////////////////////////////// // music player @@ -368,7 +340,9 @@ void play(MusicPlayer* self, int c) { int frequency_index; int period; double tempoFactor; - + if (!self->start) { + return; + } if (self->frequency_index==32){ self->frequency_index = 0; } @@ -406,25 +380,25 @@ int checkStart(MusicPlayer* self, int c) { void start(MusicPlayer* self, int c) { self->start = TRUE; - self->frequency_index = 0; - if (SYNC(&tg, checkMuted, 0)) // sycn will return a value - { - ASYNC(&tg, lockRequest, (int)mute); - } else { - ASYNC(&tg, mute, 0); - } + ASYNC(&tg, startTG, 0); + ASYNC(&tg, tick, 0); + ASYNC(&mp, play, 0); + SCI_WRITE(&sci0, "startMp\n"); + } void stop(MusicPlayer* self, int c) { + self->frequency_index = 0; self->start = FALSE; - if (SYNC(&tg, checkMuted, 0)) // sycn will return a value - { - ASYNC(&tg, lockRequest, (int)mute); - } else { - ASYNC(&tg, mute, 0); - } - + ASYNC(&tg, stopTG, 0); + SCI_WRITE(&sci0, "stopMp\n"); + } + + + + +// Button /////////////////////////////////////////////////////////// void press(Button* self, int c) { char tempBuffer[50]; @@ -434,7 +408,7 @@ void press(Button* self, int c) { if(self->count == 0) { T_RESET(&self->timer); self->count += 1; - + AFTER(SEC(1), &bt, check1Sec, self->count); return; } @@ -457,7 +431,7 @@ void press(Button* self, int c) { Time average = 0; snprintf(tempBuffer, 100, " %ld. %ld.%ld. \n", self->smaples[0], self->smaples[1], self->smaples[2]); SCI_WRITE(&sci0, tempBuffer); - if (self->smaples[1]-self->smaples[0] < 200 && self->smaples[2]-self->smaples[1] < 200) { + if (checkComparable(self->smaples[0], self->smaples[1], self->smaples[2])) { for (size_t i = 0; i < 3; i++) { average += self->smaples[i]; @@ -517,6 +491,18 @@ int timeToBPM(Time time) { return (60.0 / time) * 1000; } +bool checkComparable(Time a, Time b, Time c) { + int sum = abs(a-b) + abs(a-c) + abs(b-c); + if (sum<300) + { + return true; + } else { + return false; + } + +} + + /////////////////////////////////////////////////////////// int main() { From a3bd816bbb3624384d2d349bcad59bc153af59ea Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Wed, 8 Mar 2023 20:50:20 +0100 Subject: [PATCH 24/29] well done --- application.c | 64 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/application.c b/application.c index e3d04f4..4486265 100644 --- a/application.c +++ b/application.c @@ -11,10 +11,12 @@ #define HOLD 0 #define MOMENTARY 1 + + /* * User Button: Tap tempo * - * S: start/stop the playing of melody + * S: start/stop the playing of melody * * K: change key * @@ -67,6 +69,14 @@ typedef struct { Time smaples[3]; } Button; +typedef struct +{ + Object super; + int tempo; + int start; +} LED; + + /////////////////////////////////////////////////////////// @@ -88,7 +98,7 @@ void receiver(App*, int); void press(Button*, int); void check1Sec(Button*, int); -int timeToBPM(Time); +int timeToBPM(Time); bool checkComparable(Time, Time, Time); @@ -107,10 +117,15 @@ void stopTG(ToneGenerator*, int); void play(MusicPlayer*, int); void changeKey(MusicPlayer*, int); void changeTempo(MusicPlayer*, int); -int checkStart(MusicPlayer*, int); +int checkStart(MusicPlayer*, int); void start(MusicPlayer*, int); void stop(MusicPlayer*, int); +void blink(LED*, int); +void changeLed(LED*, int); +void startled(LED*, int); +void stopled(LED*, int); + /////////////////////////////////////////////////////////// @@ -122,6 +137,7 @@ Button bt = {initObject(), initTimer(), 0, 0, MOMENTARY, {}}; SysIO button = initSysIO(SIO_PORT0, &bt, press); ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100), false,TRUE}; // 500 USEC 650USEC 931USEC MusicPlayer mp = {initObject(), 0, 120, 0, TRUE}; +LED led = {initObject(), 120, TRUE}; @@ -215,6 +231,10 @@ void startApp(App *self, int arg) { ASYNC(&tg, tick, 0); ASYNC(&mp, play, 0); ASYNC(&mp, stop, 0); + SIO_TOGGLE(&button); + + + } @@ -359,8 +379,8 @@ void play(MusicPlayer* self, int c) { self->frequency_index++; SYNC(&tg, changeTone, period); AFTER(MSEC(50), &tg, unMuteGap, 0); - SIO_TOGGLE(&button); - AFTER(MSEC((int)30000 / self->tempo * tempoFactor), &button, sio_toggle, 0); + // SIO_TOGGLE(&button); + // AFTER(MSEC((int)30000 / self->tempo ), &button, sio_toggle, 0); SEND(MSEC((int)60000 / self->tempo * tempoFactor), USEC(100), self, play, 0); } @@ -372,6 +392,7 @@ void changeKey(MusicPlayer* self, int c) { void changeTempo(MusicPlayer* self, int c) { tempobool = false; self->tempo = c; + ASYNC(&led, changeLed, c); } int checkStart(MusicPlayer* self, int c) { @@ -380,9 +401,11 @@ int checkStart(MusicPlayer* self, int c) { void start(MusicPlayer* self, int c) { self->start = TRUE; + ASYNC(&led, startled, 0); ASYNC(&tg, startTG, 0); ASYNC(&tg, tick, 0); - ASYNC(&mp, play, 0); + ASYNC(&mp, play, 0); + ASYNC(&led, blink, 0); SCI_WRITE(&sci0, "startMp\n"); } @@ -391,7 +414,9 @@ void stop(MusicPlayer* self, int c) { self->frequency_index = 0; self->start = FALSE; ASYNC(&tg, stopTG, 0); + ASYNC(&led, stopled, 0); SCI_WRITE(&sci0, "stopMp\n"); + } @@ -455,7 +480,7 @@ void press(Button* self, int c) { AFTER(SEC(1), &bt, check1Sec, self->count); } else { SCI_WRITE(&sci0, "button released\n"); - // self->count++; + Time now = T_SAMPLE(&self->timer); Time sinceLast = now - self->last; self->last = now; @@ -502,7 +527,32 @@ bool checkComparable(Time a, Time b, Time c) { } +/////////////////////////////////////////////////////////// + +void blink(LED* self, int c) { + if (!self->start) { + SIO_WRITE(&button, 1); + return; + } + SIO_TOGGLE(&button); + AFTER(MSEC((int)30000 / self->tempo ), &button, sio_toggle, 0); + SEND(MSEC((int)60000 / self->tempo ), USEC(100), self, blink, 0); +} + +void changeLed(LED* self, int c) { + self->tempo = c; +} +void startled(LED* self, int c) { + self->start = TRUE; + + +} + +void stopled(LED* self, int c) { + self->start = FALSE; + +} /////////////////////////////////////////////////////////// int main() { From 758632aa352f2833fd652b4e9b1391979e76fab7 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Tue, 4 Apr 2023 16:39:21 +0200 Subject: [PATCH 25/29] init --- application.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 7 deletions(-) diff --git a/application.c b/application.c index 4486265..1335898 100644 --- a/application.c +++ b/application.c @@ -10,6 +10,8 @@ #define FALSE 0 #define HOLD 0 #define MOMENTARY 1 +#define CONDUCTOER 1 +#define MUSICIAN 2 @@ -36,6 +38,7 @@ typedef struct { Object super; int index; char buffer[50]; + int mod; } App; typedef struct { @@ -129,7 +132,7 @@ void stopled(LED*, int); /////////////////////////////////////////////////////////// -App app = { initObject(), 0 , {}}; +App app = { initObject(), 0 , {}, CONDUCTOER}; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Can can0 = initCan(CAN_PORT0, &app, receiver); @@ -145,15 +148,72 @@ LED led = {initObject(), 120, TRUE}; /////////////////////////////////////////////////////////// // app void receiver(App *self, int unused) { - + CANMsg msg; + CAN_RECEIVE(&can0, &msg); + char tempBuffer[50]; + int msg_id = msg.msgId; + int bufferValue = atoi(msg.buff); + switch (msg_id) { + case 1: // change key + sprintf(tempBuffer, "Can received key value: %d\n", bufferValue); + SCI_WRITE(&sci0, tempBuffer); + if (self->mod == MUSICIAN) { + ASYNC(&mp, changeKey, bufferValue); + } + break; + case 2: // change tempo + sprintf(tempBuffer, "Can received tempo value: %d\n", bufferValue); + SCI_WRITE(&sci0, tempBuffer); + if (self->mod == MUSICIAN) { + ASYNC(&mp, changeTempo, bufferValue); + } + break; + case 3: // mute + SCI_WRITE(&sci0, "Can received mute/unmute signal.\n"); + if (self->mod == MUSICIAN) { + if (SYNC(&tg, checkMuted, 0)) // sycn will return a value + { + ASYNC(&tg, lockRequest, (int)mute); + } else { + ASYNC(&tg, mute, 0); + } + } + break; + case 4: // increase volume + SCI_WRITE(&sci0, "Can received increase vol signal.\n"); + if (self->mod == MUSICIAN) { + ASYNC(&tg, lockRequest, (int)upVolume); + } + break; + case 5: // decrease volume + SCI_WRITE(&sci0, "Can received decrease vol signal.\n"); + if (self->mod == MUSICIAN) { + ASYNC(&tg, lockRequest, (int)downVolume); + } + + break; + case 6: + SCI_WRITE(&sci0, "Can received start/stop signal.\n"); + if (self->mod == MUSICIAN) { + if(SYNC(&mp, checkStart, 0)) { + ASYNC(&mp, stop, 0); + } else { + ASYNC(&mp, start, 0); + } + } + default: + break; + } } void reader(App *self, int c) { int bufferValue; char tempBuffer[50]; + CANMsg msg; SCI_WRITE(&sci0, "Rcv: \'"); SCI_WRITECHAR(&sci0, c); SCI_WRITE(&sci0, "\'\n"); + msg.nodeId = 1; switch (c) { case '0' ... '9': @@ -173,7 +233,11 @@ void reader(App *self, int c) { SCI_WRITE(&sci0, " -5<=key<=5, try again!\n"); break; } - ASYNC(&mp, changeKey, bufferValue); + if (self->mod == CONDUCTOER) { + ASYNC(&mp, changeKey, bufferValue); + } + keybool = false; + msg.msgId = 1; } // change tempo if (tempobool) { @@ -182,14 +246,29 @@ void reader(App *self, int c) { SCI_WRITE(&sci0, " 60<=tempo<=240, try again!\n"); break; } - ASYNC(&mp, changeTempo, bufferValue); + if (self->mod == CONDUCTOER) { + ASYNC(&mp, changeTempo, bufferValue); + } + tempobool = false; + msg.msgId = 2; } + CAN_SEND(&can0, &msg); break; case 30: //up - ASYNC(&tg, lockRequest, (int)upVolume); + msg.length = 0; + msg.msgId = 4; + if (self->mod == CONDUCTOER) { + ASYNC(&tg, lockRequest, (int)upVolume); + } + CAN_SEND(&can0, &msg); break; case 31: //down - ASYNC(&tg, lockRequest, (int)downVolume); + msg.length = 0; + msg.msgId = 5; + if (self->mod == CONDUCTOER) { + ASYNC(&tg, lockRequest, (int)downVolume); + } + CAN_SEND(&can0, &msg); break; case 'K': // change key SCI_WRITE(&sci0, "Please input the key(-5~5) you want:\n"); @@ -200,20 +279,39 @@ void reader(App *self, int c) { tempobool = true; // next input interger is saved as the tempo break; case 'M': // mute/unmute + msg.length = 0; + msg.msgId = 3; + if (self->mod == CONDUCTOER) { if (SYNC(&tg, checkMuted, 0)) // sycn will return a value { ASYNC(&tg, lockRequest, (int)mute); } else { ASYNC(&tg, mute, 0); } + } + + CAN_SEND(&can0, &msg); break; case 'S': - + msg.length = 0; + msg.msgId = 6; + if (self->mod == CONDUCTOER) { if(SYNC(&mp, checkStart, 0)) { ASYNC(&mp, stop, 0); } else { ASYNC(&mp, start, 0); } + } + CAN_SEND(&can0, &msg); + break; + case 'C': + if (self->mod == CONDUCTOER) { + self->mod = MUSICIAN; + SCI_WRITE(&sci0, "change to musician mod\n"); + } else { + self->mod = CONDUCTOER; + SCI_WRITE(&sci0, "Change to conductoer mod\n"); + } break; default: break; From 5658e02c5f2d567d8b95e23fcadc7241c61f7c61 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 23 Apr 2023 20:30:29 +0200 Subject: [PATCH 26/29] p5 almost done --- application.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 144 insertions(+), 5 deletions(-) diff --git a/application.c b/application.c index 1335898..c7cb3ec 100644 --- a/application.c +++ b/application.c @@ -34,11 +34,25 @@ */ +#define MAX_SIZE 100 + +typedef struct { + int items[MAX_SIZE]; + int front; + int rear; +} Queue; + typedef struct { Object super; + CallBlock callBlock; int index; char buffer[50]; int mod; + int msgid; + Time delta; + Timer timer; + Queue q; + Time lastConsume; } App; typedef struct { @@ -79,6 +93,14 @@ typedef struct int start; } LED; +typedef struct { + Object super; + CallBlock callblock; + Time delta; + Timer timer; + Time lastConsume; +} Regulator; + @@ -92,12 +114,17 @@ char tempos[] = {'a','a','a','a','a','a','a','a','a','a', 'a','b'}; bool keybool = false; bool tempobool = false; +bool deltabool = false; /////////////////////////////////////////////////////////// void reader(App*, int); void receiver(App*, int); +void newrec(App*, int); +void foo(App*, int); +void changeDelta(App*, int); +void consumer(App*, int); void press(Button*, int); void check1Sec(Button*, int); @@ -129,24 +156,87 @@ void changeLed(LED*, int); void startled(LED*, int); void stopled(LED*, int); - +void initQueue(Queue* q); +void enqueue(Queue* q, int item); +int dequeueMY(Queue* q); +int isEmpty(Queue* q); +int isFull(Queue* q); /////////////////////////////////////////////////////////// -App app = { initObject(), 0 , {}, CONDUCTOER}; +App app = { initObject(), initCallBlock(),0 , {}, CONDUCTOER, 0, SEC(1),initTimer(), {}, 0}; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted -Can can0 = initCan(CAN_PORT0, &app, receiver); +Semaphore bufferlock = initSemaphore(1);/// +Can can0 = initCan(CAN_PORT0, &app, newrec); Button bt = {initObject(), initTimer(), 0, 0, MOMENTARY, {}}; SysIO button = initSysIO(SIO_PORT0, &bt, press); ToneGenerator tg = {initObject(),initCallBlock(), 500, true, 5, FALSE, USEC(100), false,TRUE}; // 500 USEC 650USEC 931USEC MusicPlayer mp = {initObject(), 0, 120, 0, TRUE}; LED led = {initObject(), 120, TRUE}; +Regulator reg = {initObject(), initCallBlock(), SEC(1),initTimer(), 0}; +void initQueue(Queue* q) { + q->front = 0; + q->rear = -1; +} + +void enqueue(Queue* q, int item) { + if (isFull(q)) { + SCI_WRITE(&sci0, "Error: Queue is full, discard the msg\n"); + return; + } + q->rear++; + q->items[q->rear] = item; +} + +int dequeueMY(Queue* q) { + if (isEmpty(q)) { + // SCI_WRITE(&sci0, "Error: Queue is empty\n"); + return -1; + } + int item = q->items[q->front]; + q->front++; + return item; +} + +int isEmpty(Queue* q) { + return q->front > q->rear; +} + +int isFull(Queue* q) { + return q->rear == MAX_SIZE - 1; +} +/// + + /////////////////////////////////////////////////////////// // app +void newrec(App *self, int unused) { + CANMsg msg; + CAN_RECEIVE(&can0, &msg); + char tempBuffer[50]; + int msg_id = msg.msgId; + SCI_WRITE(&sci0, "---------------------------------------------------\n"); + + Time now = T_SAMPLE(&self->timer); + if (now - self->lastConsume > self->delta && isEmpty(&self->q) ) { // deliver immediately + sprintf(tempBuffer, "msg id: %d\n", msg_id); + SCI_WRITE(&sci0, tempBuffer); + sprintf(tempBuffer, "since start: %d\n", now / 100000); + SCI_WRITE(&sci0, tempBuffer); + self->lastConsume = now; + } else { // add to buffer + enqueue(&self->q, msg_id); + SCI_WRITE(&sci0, "interval time > delta and buffer is not empty, add to buffer \n"); + + } + + +} + void receiver(App *self, int unused) { CANMsg msg; CAN_RECEIVE(&can0, &msg); @@ -252,7 +342,16 @@ void reader(App *self, int c) { tempobool = false; msg.msgId = 2; } - CAN_SEND(&can0, &msg); + if (deltabool) { + if (bufferValue != 1 && bufferValue != 2 && bufferValue != 5) { + SCI_WRITE(&sci0, " 1,2, 5s, try again!\n"); + break; + } + deltabool = false; + ASYNC(&app, changeDelta, bufferValue); + deltabool = false; + } + // CAN_SEND(&can0, &msg); break; case 30: //up msg.length = 0; @@ -313,19 +412,59 @@ void reader(App *self, int c) { SCI_WRITE(&sci0, "Change to conductoer mod\n"); } break; + case 'O': + ASYNC(&app, foo, 0); + break; + case 'D': // change delta + SCI_WRITE(&sci0, "Please input the delta(1s,2s,5s) you want:\n"); + deltabool = true; + break; default: break; } } +void changeDelta(App *self, int c) { + self->delta = SEC(c); + SCI_WRITE(&sci0, "change delta successfully\n"); +} +void foo(App *self, int c) { + CANMsg msg; + msg.nodeId = 1; + msg.length = 0; + msg.msgId = self->msgid; + self->msgid++; + CAN_SEND(&can0, &msg); + +} +void consumer(App *self, int c) { + char tempBuffer[50]; + if (!isEmpty(&self->q)) { + Time now = T_SAMPLE(&self->timer); + int msg_id = dequeueMY(&self->q); + sprintf(tempBuffer, "msg id: %d\n", msg_id); + SCI_WRITE(&sci0, tempBuffer); + sprintf(tempBuffer, "since start: %d\n", now / 100000); + SCI_WRITE(&sci0, tempBuffer); + self->lastConsume = now; + } else { + SCI_WRITE(&sci0, "buffer is empty \n"); + } + SEND(self->delta, USEC(10), self, consumer, 0); +} void startApp(App *self, int arg) { - + T_RESET(&self->timer); ///////// + initQueue(&self->q); + // char t[50]; SCI_INIT(&sci0); CAN_INIT(&can0); SIO_INIT(&button); SCI_WRITE(&sci0, "Hello, hello...\n"); + // sprintf(t, "f %d, r %d", self->q.front, self->q.rear); + // SCI_WRITE(&sci0, t); + ASYNC(self, consumer, 0); ASYNC(&tg, tick, 0); ASYNC(&mp, play, 0); ASYNC(&mp, stop, 0); From c7f08218d04d6fc8fe799595cfc108abe25b9597 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Sun, 23 Apr 2023 21:00:33 +0200 Subject: [PATCH 27/29] p5 almost done, not thread safe --- application.c | 83 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/application.c b/application.c index c7cb3ec..d5730ef 100644 --- a/application.c +++ b/application.c @@ -34,12 +34,11 @@ */ -#define MAX_SIZE 100 +#define QUEUE_SIZE 100 typedef struct { - int items[MAX_SIZE]; - int front; - int rear; + int queue[QUEUE_SIZE]; + int front, rear; } Queue; typedef struct { @@ -53,6 +52,7 @@ typedef struct { Timer timer; Queue q; Time lastConsume; + bool burst; } App; typedef struct { @@ -125,6 +125,7 @@ void newrec(App*, int); void foo(App*, int); void changeDelta(App*, int); void consumer(App*, int); +void burst(App*, int); void press(Button*, int); void check1Sec(Button*, int); @@ -157,13 +158,13 @@ void startled(LED*, int); void stopled(LED*, int); void initQueue(Queue* q); -void enqueue(Queue* q, int item); +int enqueue(Queue* q, int item); int dequeueMY(Queue* q); int isEmpty(Queue* q); -int isFull(Queue* q); + /////////////////////////////////////////////////////////// -App app = { initObject(), initCallBlock(),0 , {}, CONDUCTOER, 0, SEC(1),initTimer(), {}, 0}; +App app = { initObject(), initCallBlock(),0 , {}, CONDUCTOER, 0, SEC(1),initTimer(), {}, 0, false}; Serial sci0 = initSerial(SCI_PORT0, &app, reader); Semaphore muteVolumeSem = initSemaphore(1); // lock the tg when is muted Semaphore bufferlock = initSemaphore(1);/// @@ -179,35 +180,33 @@ Regulator reg = {initObject(), initCallBlock(), SEC(1),initTimer(), 0}; void initQueue(Queue* q) { - q->front = 0; - q->rear = -1; + q->front = q->rear = 0; } - -void enqueue(Queue* q, int item) { - if (isFull(q)) { - SCI_WRITE(&sci0, "Error: Queue is full, discard the msg\n"); - return; +int enqueue(Queue* q, int value) { + int next_rear = (q->rear + 1) % QUEUE_SIZE; + if (next_rear == q->front) { + SCI_WRITE(&sci0, "Queue is full!, discard the msg\n"); + return -1; + } else { + q->queue[q->rear] = value; + q->rear = next_rear; + return 0; } - q->rear++; - q->items[q->rear] = item; } int dequeueMY(Queue* q) { - if (isEmpty(q)) { - // SCI_WRITE(&sci0, "Error: Queue is empty\n"); - return -1; + if (q->front == q->rear) { + + return -1; // Or some other value to indicate an error + } else { + int value = q->queue[q->front]; + q->front = (q->front + 1) % QUEUE_SIZE; + return value; } - int item = q->items[q->front]; - q->front++; - return item; } int isEmpty(Queue* q) { - return q->front > q->rear; -} - -int isFull(Queue* q) { - return q->rear == MAX_SIZE - 1; + return q->front == q->rear; } /// @@ -229,8 +228,11 @@ void newrec(App *self, int unused) { SCI_WRITE(&sci0, tempBuffer); self->lastConsume = now; } else { // add to buffer - enqueue(&self->q, msg_id); - SCI_WRITE(&sci0, "interval time > delta and buffer is not empty, add to buffer \n"); + int a = enqueue(&self->q, msg_id); + if (a == 0) { + SCI_WRITE(&sci0, "interval time > delta and buffer is not empty, add to buffer \n"); + } + } @@ -419,11 +421,34 @@ void reader(App *self, int c) { SCI_WRITE(&sci0, "Please input the delta(1s,2s,5s) you want:\n"); deltabool = true; break; + case 'B': // enter burst mode + self->burst = false; + SCI_WRITE(&sci0, "enter burst mode \n"); + ASYNC(&app, burst, 0); + break; + case 'X': + self->burst = true; + SCI_WRITE(&sci0, "quit burst mode \n"); + break; default: break; } } + +void burst(App *self, int c) { + if (self->burst) { + return; + } + CANMsg msg; + msg.nodeId = 1; + msg.msgId = self->msgid; + msg.length = 0; + self->msgid++; + CAN_SEND(&can0, &msg); + + SEND(MSEC(500), USEC(10), self, burst, 0); +} void changeDelta(App *self, int c) { self->delta = SEC(c); SCI_WRITE(&sci0, "change delta successfully\n"); From d2420eb996accf2ded1a22bb0a06fbd29f4697ce Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Mon, 24 Apr 2023 20:49:57 +0200 Subject: [PATCH 28/29] debug --- application.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/application.c b/application.c index d5730ef..4dc9730 100644 --- a/application.c +++ b/application.c @@ -125,7 +125,9 @@ void newrec(App*, int); void foo(App*, int); void changeDelta(App*, int); void consumer(App*, int); +void trueConsumer(App*, int); void burst(App*, int); +void bufferLockRequest(App*, int); void press(Button*, int); void check1Sec(Button*, int); @@ -465,6 +467,23 @@ void foo(App *self, int c) { } void consumer(App *self, int c) { + // char tempBuffer[50]; + // if (!isEmpty(&self->q)) { + // Time now = T_SAMPLE(&self->timer); + // int msg_id = dequeueMY(&self->q); + // sprintf(tempBuffer, "msg id: %d\n", msg_id); + // SCI_WRITE(&sci0, tempBuffer); + // sprintf(tempBuffer, "since start: %d\n", now / 100000); + // SCI_WRITE(&sci0, tempBuffer); + // self->lastConsume = now; + // } else { + // SCI_WRITE(&sci0, "buffer is empty \n"); + // } + ASYNC(self, bufferLockRequest, (int)trueConsumer); + +} + +void trueConsumer(App *self, int c) { char tempBuffer[50]; if (!isEmpty(&self->q)) { Time now = T_SAMPLE(&self->timer); @@ -477,8 +496,9 @@ void consumer(App *self, int c) { } else { SCI_WRITE(&sci0, "buffer is empty \n"); } + ASYNC(&bufferlock, Signal, 0); SEND(self->delta, USEC(10), self, consumer, 0); -} +} void startApp(App *self, int arg) { T_RESET(&self->timer); ///////// initQueue(&self->q); @@ -500,7 +520,11 @@ void startApp(App *self, int arg) { } - +void bufferLockRequest(App* self, int c) { + self->callBlock.obj = self; + self->callBlock.meth = (Method)c; + ASYNC(&bufferlock, Wait, (int)&self->callBlock); +} /////////////////////////////////////////////////////////// From bbc9d6c304d65510ccfd81f420b34540e3369e84 Mon Sep 17 00:00:00 2001 From: Ping Zheng Date: Mon, 24 Apr 2023 21:44:22 +0200 Subject: [PATCH 29/29] p5 done. Update semaphore package --- application.c | 30 +++++++++++++++++++++++++++--- canTinyTimber.c | 4 ++-- semaphore.c | 2 +- semaphore.h | 1 + 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/application.c b/application.c index 4dc9730..c5df72d 100644 --- a/application.c +++ b/application.c @@ -101,7 +101,10 @@ typedef struct { Time lastConsume; } Regulator; - +typedef struct { + int c; + Method m; +} amessage; /////////////////////////////////////////////////////////// @@ -128,6 +131,7 @@ void consumer(App*, int); void trueConsumer(App*, int); void burst(App*, int); void bufferLockRequest(App*, int); +void producer2(App*, int); void press(Button*, int); void check1Sec(Button*, int); @@ -229,6 +233,11 @@ void newrec(App *self, int unused) { sprintf(tempBuffer, "since start: %d\n", now / 100000); SCI_WRITE(&sci0, tempBuffer); self->lastConsume = now; + } else if (isEmpty(&self->q)) { // In this case, there will be chance that producer and consumer change buffer in parallel. To avoid competition, use lock. + amessage* a = malloc(sizeof(amessage)); + a->c = msg_id; + a->m = producer2; + ASYNC(self, bufferLockRequest, (int) a); // TinyTimber parameters constrain..., we can only use int. The semaphore package is changed. } else { // add to buffer int a = enqueue(&self->q, msg_id); if (a == 0) { @@ -241,6 +250,15 @@ void newrec(App *self, int unused) { } +void producer2(App *self, int c) { + int a = enqueue(&self->q, c); + if (a == 0) { + SCI_WRITE(&sci0, "interval time > delta and buffer is not empty, add to buffer \n"); + } + + ASYNC(&bufferlock, Signal, 0); +} + void receiver(App *self, int unused) { CANMsg msg; CAN_RECEIVE(&can0, &msg); @@ -479,7 +497,10 @@ void consumer(App *self, int c) { // } else { // SCI_WRITE(&sci0, "buffer is empty \n"); // } - ASYNC(self, bufferLockRequest, (int)trueConsumer); + amessage* a = malloc(sizeof(amessage)); + a->c = 0; + a->m = trueConsumer; + ASYNC(self, bufferLockRequest, (int) a); } @@ -521,8 +542,11 @@ void startApp(App *self, int arg) { } void bufferLockRequest(App* self, int c) { + amessage* a = c; self->callBlock.obj = self; - self->callBlock.meth = (Method)c; + self->callBlock.meth = a->m; + self->callBlock.p = a->c; + free(a); ASYNC(&bufferlock, Wait, (int)&self->callBlock); } diff --git a/canTinyTimber.c b/canTinyTimber.c index af3edc7..7e8fe1a 100644 --- a/canTinyTimber.c +++ b/canTinyTimber.c @@ -1,7 +1,7 @@ #include "TinyTimber.h" #include "canTinyTimber.h" -//#define __CAN_LOOPBACK // Note: requires physical loopback between CAN 1 and 2 jacks +#define __CAN_LOOPBACK // Note: requires physical loopback between CAN 1 and 2 jacks void DUMP(char *s); @@ -17,7 +17,7 @@ void can_init(Can *self, int unused) { DUMP("NOTE: CAN running in loopback mode!\n\r"); #endif -//#define __CAN_TxAck // if defined: single transmission, can_send() will wait for message error or acknowledgement +#define __CAN_TxAck // if defined: single transmission, can_send() will wait for message error or acknowledgement // default: automatic retransmission, can_send() will not wait for message error or acknowledgement CAN_StructInit(&CAN_InitStructure); diff --git a/semaphore.c b/semaphore.c index cad0a79..bb9e9dc 100644 --- a/semaphore.c +++ b/semaphore.c @@ -25,7 +25,7 @@ void Wait(Semaphore *self, int c) { Caller wakeup = (Caller) c; // type-cast back from ‘int’ if (self->value > 0) { self->value--; - ASYNC(wakeup->obj, wakeup->meth, 0); + ASYNC(wakeup->obj, wakeup->meth, wakeup->p); } else c_enqueue(wakeup, &self->queue); diff --git a/semaphore.h b/semaphore.h index c547f8b..0d318ca 100644 --- a/semaphore.h +++ b/semaphore.h @@ -10,6 +10,7 @@ typedef struct call_block { Caller next; // for use in linked lists Object *obj; Method meth; + int p; // parameter } CallBlock; #define initCallBlock() { 0, 0, 0 }