Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
Building a COFFEE POT simulation to run under CCES IDE
Learning just enough Blackfin ASM to be able to turn on the Water
ASSUMPTION – You already have the C++ version of this code working
ENCM511 ‐‐ Basic Assembly language concepts 1
Hint: Closing all projects except the one you are working on
• CCES assumes all projects are active, and will slow you down by rebuilding projects that share header files unnecessarily
• CCES may try to load the wrong .dxe when you do F5• How much C++ code do we need to translate into Assembly code – for practice – for speed – to make hardware interfacing easier
ENCM511 ‐‐ Basic Assembly language concepts 2
ENCM511 ‐‐ Basic Assembly language concepts 3
Add new file to the project
Modify DoSimulationCPP( ) to conditionally call C++
or assembly code
HINT: Check TurnOnWater_CPP( ) works as using it for ASM code template
Check C++ code worked
CODE DESIGN DEFECT
I forgot about the “auto‐turn‐off” safety feature added to the water pump flow control register
CC to SelfSame thing with heat register
ENCM511 ‐‐ Basic Assembly language concepts 4
PSP with just‐in‐time questions
• Think about things to think about when doing code review
• Did we type the function name correctly?• Did we add a prototype so Compiler will work correctly?• How do you add a ASM prototype to C++?• How do you generate an ASM stub function so linker will work correctly?
• How do you pass parameters from C++ into ASM?• WAIL ‐‐ How do you return values from ASM back to C++
ENCM511 ‐‐ Basic Assembly language concepts 5
First step – Build the project with empty ASM file – Check that complaint
is the one you expected• Note – We should be doing all of this during our code review and not wasting time this way
ENCM511 ‐‐ Basic Assembly language concepts 6
Function complained about does not have mistyped name
Complaint expected
“undefined”No prototype
Add ASM prototype to MyCoffeePotFunctions.hBuild. Expect LINKER error NOT compiler
• Oops – forgot to turn on the board
• Oops – Cut‐and‐pasted wrong thing
• Third time correct
ENCM511 ‐‐ Basic Assembly language concepts 7
Question to ponder (QTP)
Why “extern C”
Cut‐and‐past working C++ codeto use as comments
• Highlight all text – tab a couple of times, insert //
• Do the ASM stuff we know always needed• Indicate registers used to pass in parameters (ALWAYS R0 (inpar1) and R1 (inPar2)
• Add JUST ENOUGH CODE to create an assembly language stub routine that returns to C++
• Compile and check that linksENCM511 ‐‐ Basic Assembly language concepts 8
Blackfin C++ coding
convention to use these registers
Course requirement that you document
this knowledge
Pt means pointer –not typo
Check for correct2015 bit names
Linker message indicates a simple errorSimple defects mean NO CODE REVIEW DONEWHAT SYNTAX DEFECT UPSET THE LINKER?
ENCM511 ‐‐ Basic Assembly language concepts 9
Need leading _
Tackle the code a little bit of a time• Place “temp” short int currentRegisterValue (use section data1);• Call to C++ function that is stored in a file that is external to this
.asm looks easy. The file “builds”, but the project does “not link”
ENCM511 ‐‐ Basic Assembly language concepts 10
The problem is a property of C++ called name‐mangling
• C++ compiler turns functions into assembly code and then into machine code• C++ allows “overloading” of functions such as
void FooFunctionAdd(int A, int B); orvoid FooFunctionAdd(float A, float B);
• Each of these functions MUST have a unique name at the assembly code level like ‐‐(DNTMT)FooFunctionAdd_2ints // FooFunctionAdd(int A, int B); FooFunctionAdd_2floats // FooFunctionAdd(float A, float B);
• DIFFERENT FOR EVERY DEVELOPMENT ENVIRONMENT
• Fake name‐mangling like this is okay in this course during quizzes and exams
• Need Personal Software Process to find “Real name mangling” for void UpdateSimulationDisplay(void); so can call from Assembly code
Otherwise will not be able to call “C++” code from Assembly Code THIS WOULD FAIL THE 2nd Rule of Assembly Language programing
If you have the misfortune to have to work in assembly code – get back to C++ functions as often as you can! Unless you need to make your code really fast to meet customer requirements.
ENCM511 ‐‐ Basic Assembly language concepts 11
My approach• Use Settings to Remove the code that generated the UpdateSimulator( ) function (a library)
• Rebuild the project and see what all the other C++ functions calling C++ UpdateSimulator( ) cause the linker to complain about
• VDSP linker – had a more easily understood name‐mangling scheme
• CCES linker seems to a non‐obvious approach– So – cut‐and‐paste name from the error message
ENCM511 ‐‐ Basic Assembly language concepts 12
• __Z23Add_CoffeePotiPc (int , pointer to char)• __Z23UpdateSimulationDisplayv (void)• Why are some things __Z24? WSWC (at the moment)
– Why ask or worry? ‐‐We have a process
ENCM511 ‐‐ Basic Assembly language concepts 13
Generate pointers to useful thingsSimple error #19 show NO CODE REVIEW done
• Don’t ignore assembler error warnings. They quickly turn into assembler defects and are difficult to fix.
• You code P2 to point to updatedRegisterValue (Can’t use P3 – Why?)ENCM511 ‐‐ Basic Assembly language
concepts 14
Blackfin (like MIPS) is RISC processorIt has a LOAD / STORE memory architecture
• LOAD from memory location into data registerREAD a memory value into data registerR0 = [P0]; ALLOWED ‐‐ byte4 – signed long int or unsigned long int
• STORE from data register into memory locationWRITE a data register value into memory[P0] = R0; ALLOWED
• LOAD from memory location into data registerREAD a memory value into data registerR0 = W[P0] (Z); ALLOWED ‐‐ byte2 – unsigned short int with zero sign extension
• MOVE register to registerR1 = R0; ALLOWED or P1 = P2
• MOVE constant to data register (when the wind blows from the East)R1 = 3; ALLOWED MOST OF THE TIME (If number small enough)
• MOVE memory value to a different memory location[P0] = [P1]; NOT‐ALLOWED
• MOVE constant to memory location[P0] = 2; NOT‐ALLOWED
ENCM511 ‐‐ Basic Assembly language concepts 15
How do you move parts of a memory structure? coffeePt_BaseAddress‐>controlRegister
P0.L = Lo(baseAddress); P0.H = Hi(baseAddress);#define CONTROLREGISTER_OFFSET 0 // Must be in BYTES
R2 = [P0 + CONTROLREGISTER_OFFSET]; (if int)R2 = W[P0 + CONTROLREGISTER_OFFSET]; (if short int)R2 = B[P0 + CONTROLREGISTER_OFFSET]; (if char)
Assembly does not care if C++ short int orC++ unsigned short int unless you want to care ‐‐ Processor uses same instruction
It is your job to use the value properly when coding
Peripheral device register name
Byte Offset(From device base address)
Size Actual address
coffeePot1_BaseAddress = Add_CoffeePotToSystem_PlugAndPlay(COFFEEPOT1);Suppose gives ‐‐ coffeePot1_BaseAddress = 0x1000 (No idea what actual system will give as a value)
controlRegister 0x00 16 bits – 2 byte 0x1000
ENCM511 ‐‐ Basic Assembly language concepts 16
First attempt to translate C++ into assembly codeMore simple syntax errors mean
IMPROPER CODE REVIEW
• #define temp_R3Means define temp_R3 as nothingObviously not what was intended
ENCM511 ‐‐ Basic Assembly language concepts 17
WATCH‐OUTCode review reveals that should be using W[Px] as accessing 16 bit registers and memory locations
Don’t ignore assembly error messagesThey will quickly turn into defects
ENCM511 ‐‐ Basic Assembly language concepts 18WATCH‐OUT
CHECK C++ CODE FOR WHAT 2015 BITS ARE CALLED
Cut and paste #define from C++ include file CoffeePot_SimulatorFunctions.h
WEIRD ‐‐ Source code assembles for all constants BUT ONE
ENCM511 ‐‐ Basic Assembly language concepts 19
Actually we have designed in a coded defect, which led us to accidently find that we can’t do R1x = (1 << 15) type syntax
If we can correctly reviewed the code and not made the design
defect, this error message would have surprized us later in the course
What is design mistake (defect)?
PSP ‐‐ “OUT‐OF‐RANGE” meansBIGGER THAN 16 Bits which means
Load top and then bottom sixteen bits
I allow this syntaxduring exams andquizzes aseasier to markand assemblerSHOULD ALLOW ITENCM511 ‐‐ Basic Assembly language
concepts 20We have fixed the SYNTAX DEFECT (CODE REVIEW), but have still left behind the DESIGN DEFECT (DESIGN REVIEW)
Why is 1 << 15 = 0x8000 (16 bits)bigger than 16 bits?
• Answer• R0 = (1 << 2) means put 16 bit value 0x0004 into 32 bit register R0 which the processor can do using zero sign extension (signed operation) or by zero padding (unsigned operation)
• R0 = (1 << 15) means put 16 bit value 0x8000 into 32 bit register R0 but processor can’t do it without deciding to use one sign extension (signed operation) or by zero padding (unsigned operation)
ENCM511 ‐‐ Basic Assembly language concepts 21
When we try to finish the code we start finding major code defects in what we thought was “good code”
• Problem – we used [P0 + 7] = R1; (which stores a 32‐bit int)• But the water register is unsigned char (8‐bits) so we must use
B[P0 + 7] = R1; • Which also means that we must use W[P0 + CONTROLREGISTEROFFSET]
since that register is a short int (16‐bit) • And also define currentRegisterValue as .byte2 and do W[P1] and W[P2]ENCM511 ‐‐ Basic Assembly language
concepts 22
The follow code is CLOSE to correctfor use in individual Assignment 1
ENCM511 ‐‐ Basic Assembly language concepts 23
You will need to fix LED BIT NAMES ENCM511 ‐‐ Basic Assembly language
concepts 24
You will need to fix LED BIT NAMES
BIG HIDDEN DEFECT
• COMMON MISTAKE IN ALL LABS, QUIZZES AND EXAMS So KNOW WHAT the Run‐time crash looks like so you know what defect to go looking for
ENCM511 ‐‐ Basic Assembly language concepts 25
BIG HIDDEN DEFECT – ALL COMPILERS distinguish between “volatile” and “non‐volatile” registers to gain speed
• Our code is happily changing R0, R1, R2, R3, P0, P1 and P2• So the C++ UpdateSimulatorDisplay( ) can happily change R0, R1, R2, R3,
P0, P1 and P2 too.• Which destroys the important values we need to use in P0 and R1• So we need to save the important values in P0 and R1 before calling
UpdateSimulatorDisplay and recover P0 and R1 • There are right and wrong ways of saving things• COMMON MISTAKE IN ALL LABS, QUIZZES AND EXAMS (and your cell‐
phone and airplanes) BECAUSE MIGHT WORK BY MISTAKE SOMETIMESENCM511 ‐‐ Basic Assembly language concepts 26
Wrong ‐‐ save to stack, call function, recover from stack
• Simply saving things onto stack ‐‐ Looks like it should work
• It MAY not work – because of the way that C++ functions are compiled by the BF533 compiler
• I don’t know what happens with MIPS or ARM functions – do you?
ENCM511 ‐‐ Basic Assembly language concepts 27
This approach always worksCODE REVIEW – MUST SAVE TWO THINGS
• Change some code before LINK 20 to SAVE R7 and P5
• Use these NON‐VOLATILE registers to save P0 and R2, call a function, and recover P0 and R2
• Fix some code after the UNLINK
ENCM511 ‐‐ Basic Assembly language concepts 28
NOTEPaired SAVE BEFORE LINK and RECOVER AFTER UNLINK
ALSO FILO stack operations
must be used
WHAT DOES FILO mean?
Since we “know” something about the way the code works that the C++ does not know then we
could“optimise the code”• Do the last update early
ENCM511 ‐‐ Basic Assembly language concepts 29
Once the code is working (and we don’t know that yet) we can “Refactor for speed)
ENCM511 ‐‐ Basic Assembly language concepts 30
Default C++ compiler operation is to move everything out into and then out from temporary memory
values
We don’t have to code that way
There is so much easy optimization – that I have developed a PSP process to write “nearly optimized assembly code immediately”
ENCM511 ‐‐ Basic Assembly language concepts 31
Optimized code becomes short(and fast)
ENCM511 ‐‐ Basic Assembly language concepts 32
Personal Software Process (PSP)• Personally I developed a PSP to write semi‐optimized assembly code immediately
• Key element – Test last approach– Write C++ code– Write tests and test the code– Write ASM code– Use tests to check ASM– Refactor ASM code– Use tests to check refactored code
ENCM511 ‐‐ Basic Assembly language concepts 33