Page 1 of 10
INFORMATION
The quiz consists of 21 question sections with a number of sub-questions within each
section. Ensure that you complete all the questions. The mark distribution is as below:
•
•
•
•
•
•
•
•
Question 1 [5]
Question 2 [3]
Question 3 [4]
Question 4 [10]
o CodeRunner Question
Question 5 [18]
Question 6 [5]
Question 7 [10]
o CodeRunner Question
Question 8 [5]
o CodeRunner Question
Emulator system details:
ARM Emulator Memory Map:
Description
Address
Code Block Start 0x0000
Code Block End 0x07FF
Memory Start
0x40020800
Memory End
0x40020FFF
By including any of the following comments you can control the output of the Debug
trace when running a precheck.
/*
Use variables below to control the debug trace.
mem_addr_start=0x40020c00
mem_addr_length=32
print_mem_inline=False
mem_display_mode=hex
*/
By setting print_mem_inline=True, you can print the memory contents inline with
the trace.
The memory trace will display as ascii /hex/int characters by setting:
mem_display_mode=ascii // or
mem_display_mode=hex // or
mem_display_mode=int // Note: this is a new
debugging mode
mem_addr_start controls the memory trace start address and
mem_addr_length controls the number of byte address spaces to display.
Page 2 of 10
Question 1 [5]
Answer true or false to the following statements regarding the STM32CubeIDE and
the toolchain. Incorrect answers will earn negative marks. Select "Pass" if you do
not want to supply an answer (to earn 0 marks).
1.1
1.2
The toolchain and the IDE is one and the same thing. [1] FALSE
One can set breakpoints in the disassembly view. [1] TRUE
1.3
The
1.4
1.5
The
button from the IDE will start a debug session. [1] FALSE
The best way to view the value of a local variable is using the Memory Browser
window. [1] FALSE
button from the IDE will restart a debug session. [1] FALSE
Question 2 [3]
Study the following assembly code outline.
1 main
2
3
4
5
6
7 func1
8
9
10
11
12
13 func2
14
15
2.1
2.2
...
BL func1
...
B main
...
BL func2
...
MOV PC, LR
...
MOV PC, LR
Which line number imposes a problem on the program flow? [1] 9
What is the problem with the code? [1]
a. The program will not enter the func2 subroutine
b. The link register is overwritten in the func2 subroutine, so the func2 subroutine
will not return control to func1 after it is called
c. The link register is overwritten in the func1 subroutine, so it will not return control
to the main routine
Page 3 of 10
2.3
What tool/technique can be used to fix the problem? [1]
a. Branch to func1 after branching to func2 to return control to func1.
b. Use an interrupt handler to call func2.
c. Use the stack to preserve to value of the link register before branching to func2.
Question 3 [4]
The following questions are related to the differences between the BSRR and ODR
registers that may be used to change the output logic level of the GPIO pins.
3.1
3.2
3.3
If I set an single GPIO output pin to either 0 or 1, which of the following statements
is true regarding the number of instructions that are required in the most efficient
implementation: [2]
Answer: BSRR requires fewer instructions than the ODR alternative
True or false: You can read from the GPIOA_BSRR register to determine the current
output pin logic level. (this question is marked negative) [1] False
You can read from the GPIOA_ODR register to determine the output pin logic level.
(this question is marked negative) [1] True
Question 4 [10]
An engineer designed a new PCB based on the STM32F407VG processor and the
STM32F4 -discovery evaluation kit. Similar to the evaluation kit, they included 4 LEDs for
indication, but they changed pin assignment to that of the schematic below:
You are tasked with creating the setLEDs function which has the following prototype:
void setLEDs(uint8_t colour);
Page 4 of 10
This function must turn on and off the corresponding LEDS based on the value passed
to colour argument from the table below:
Colour
Description
0
All LEDs off
1
Only Green LED on
2
Only Orange LED on
3
Only Red LED on
4
Only Blue LED on
You may only use the HAL_GPIO_WritePin and HAL_GPIO_ReadPin functions.
Note: Other devices may be connected to the other available pins on the GPIOD port
but are not specified.
Take note:
• This Coderunner question does penalize incorrect checks.
• Syntax checking is enabled and you can precheck as many times as you like.
• Your code must compile in order to be evaluated.
• It not necessary to use any external IDE.
Possible solution #1:
void setLEDs(uint8_t colour){
uint16_t gpio_reset_pins = (0xA050);
switch(colour) {
case 0:
HAL_GPIO_WritePin(GPIOD, gpio_reset_pins, GPIO_PIN_RESET);
break;
case 1:
HAL_GPIO_WritePin(GPIOD, gpio_reset_pins, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, 0x10, GPIO_PIN_SET);
break;
case 2:
HAL_GPIO_WritePin(GPIOD, gpio_reset_pins, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, 0x2000, GPIO_PIN_SET);
break;
case 3:
HAL_GPIO_WritePin(GPIOD, gpio_reset_pins, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, 0x8000, GPIO_PIN_SET);
break;
case 4:
Page 5 of 10
HAL_GPIO_WritePin(GPIOD, gpio_reset_pins, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD, 0x40, GPIO_PIN_SET);
break;
default:
break;
}
}
Possible solution #2:
void setLEDs(uint8_t colour){
uint16_t gpio_reset_pins = GPIO_PIN_4|GPIO_PIN_13|GPIO_PIN_15|GPIO_PIN_6;
//All pins that must be turned off
uint16_t gpio_set_pins = 0; //Pin that should be turned on - initially nil
if (colour == 1) { // GREEN LED
gpio_set_pins = GPIO_PIN_4;
}
else if (colour == 2) { // ORANGE LED
gpio_set_pins = GPIO_PIN_13;
}
else if (colour == 3) { // RED LED
gpio_set_pins = GPIO_PIN_15;
}
else if (colour == 4) { // BLUE LED
gpio_set_pins = GPIO_PIN_6;
}
HAL_GPIO_WritePin(GPIOD, gpio_reset_pins, GPIO_PIN_RESET);//reset all
pins
if (gpio_set_pins != 0) {// turn on pin
HAL_GPIO_WritePin(GPIOD, gpio_set_pins, GPIO_PIN_SET);
}
}
Question 5 [18]
The following are general questions that can be answered using the GPIO lecture slides,
STM32F407 reference manual and STM3232F407 datasheet
In C, one can write to a peripheral register using the following code:
uint32_t * reg=(uint32_t *) 0x"address in hex";
*reg=(*reg&0x"mask")|0x"bits to set in hex";
Where "address in hex" is replaced by the register's 32 bit address, "mask" by a mask to
apply to preserve various bits and "bits to set in hex" by the hex representation of the
bits you want to set.
Page 6 of 10
Specify the word, as well as the address that it should be written to, to configure the
specified pin. Also specify the mask that should be applied to the word to preserve the
bits not being written to. Specify all 8 hexadecimal digits, use capital letters for the
characters A to F, and do not include 0x in your answer.
Question
To set pins PB11, PB12, PB13, and PB14
as general purpose output (using the
GPIOB_MODER register) [3]
To set pin PB11, PB12, PB13, and PB14 as
push-pull digital outputs (using the
GPIOB_OTYPER register) [3]
To set pin PB11, PB12, PB13, and PB14 as
low speed outputs (using the
GPIOB_OSPEEDR register) [3]
To disable the internal pull-up and pulldown resistors pin PB11, PB12, PB13, and
PB14 (using the GPIOB_PUPDR register):
To set pin PA0 as input (using the
GPIOA_MODER register) [3]
6. To disable the internal pull-up and pulldown resistors for pin PA0 (using the
GPIOA_PUPDR register) [3]
7. What is the address, mask and value to
use in order to enable the RCC AHB1
peripheral clock for GPIOA and GPIOD in
the RCC_AHB1ENR register? [3]
Address
0x40020400
Mask
Value
0xC03FFFFF 0x15400000
0x40020404
0xFFFF87FF
0x40020408
0xC03FFFFF 0x00000000
0x00000000
0x4002040C 0xC03FFFFF 0x00000000
0x40020000
0xFFFFFFFC 0x00000000
0x4002000C 0xFFFFFFFC 0x00000000
0x40023830
0xFFFFFFF6
0x00000009
Question 6 [5]
For the following questions, answer true or false.
6.1
6.2
6.3
6.4
6.5
An interrupt with a priority of 3 can interrupt another interrupt that has a priority of
5. [1] True
External interrupts can only trigger on the rising edge. [1] False
When an interrupt occurs you must be careful to ensure that you push the 8 data
words forming the stack frame to the stack before you call the interrupt handler.
[1] False
The vector table only stores the memory address of where to branch to when an
interrupt/exception occurs. [1] False
The Nested Vectored Interrupt Controller is merely a software abstraction and not
a physical integrated circuit. [1] False
Page 7 of 10
Question 7 [10]
You are tasked with designing a program to calculate and display the angular rotation
rate based on pulses received from a rotary encoder sensor. The rotary encoder
generates pulses that represent the rate of rotation. The sensor emits 360 pulses for
each full rotation.
The GPIO pin configuration has already been completed to set-up pin PD2 as GPIO_EXTI
(external interrupt), to trigger on a rising edge. The GPIO interrupt for this pin is handled
in the EXTI2_IRQHandler function.
The time interval in which pulses have to be measured is 100ms. This is achieved by
using the HAL_Delay function - to delay for 100ms between every angular rotation rate
report.
The unit in which the angular rate of rotation must be reported is: °/s i.e. degrees per
second.
You must report the angular rate of rotation within 2 decimal points.
The sensor will generate pulses at varying rates and therefore generate interrupts at
varying rates on the EXTI2 pin. It can be assumed that the pulses are ideal, with no
jitter and no need for any form of debouncing or conditioning.
You have to complete code in the template below to complete the program. Do not
modify the printf statement.
Only make modifications inside the BEGIN and END markers in the code.
Take note:
• This Coderunner question does penalize incorrect checks.
• Syntax checking is enabled and you can precheck as many times as you like.
• Your code must compile in order to be evaluated.
• It not necessary to use any external IDE.
Possible solution:
/* BEGIN place your global variables here */
uint32_t pulseCount = 0;
/* END place your global variables here */
void EXTI2_IRQHandler(void)
{
/* USER CODE BEGIN EXTI2_IRQn 0 */
pulseCount++;
/* USER CODE END EXTI2_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
Page 8 of 10
}
int main(void)
{
HAL_Init();
SystemClock_Config();
while (1)
{
HAL_Delay(100); // delay for 100ms
/* BEGIN write code here to calculate angular rotation rate */
double angularRotationRate =0;
angularRotationRate =(double)(pulseCount) *10;
pulseCount = 0; // Reset pulse count for the next measurement interval
/* END write code here to calculate angular rotation rate */
printf("Angular Rotation Rate: %4.2f °/s\n", angularRotationRate);
}
}
Question 8 [5]
Write an assembly function turnOnGreenLed to turn on the green Led4 for
the STM32F4DISCOVERY development kit.
You can assume the GPIO ports have been configured correctly using the
STM32CubeMX and that the initialisation routines have already been called in the main
function.
The equivalent C-prototype would be:
void turnOnGreenLed();
Take note:
• You may only work with output data register.
• This Coderunner question does penalize incorrect checks.
• Syntax checking is enabled and you can precheck as many times as you like.
• Your code must compile in order to be evaluated.
• It not necessary to use any external IDE.
Possible solution:
.syntax unified
/*
Use varibales below to control the debug trace.
Page 9 of 10
mem_addr_start=0x40020c00
mem_addr_length=32
print_mem_inline=False
mem_display_mode=hex
*/
turnOnGreenLed:
ldr R0, =0x40020c14 //load the ouput register memory address
ldr R1,[r0] // load the ouput register value
orr R1,R1,#0x1000 // set bit 12
str r1, [r0] // store the value in the output register
mov pc, lr // restore pc
TEST CASES:
Test input
Expected output
compile
1
OK
15
check for mov PC, LR
Check bytecode length vs
solution
Memory Contents:
Addr
0
1
2
3
0x40020C14
0x00
0x10
0x00
0x00
Memory Contents:
Addr
0
1
2
3
0x40020C14
0x00
0xF0
0x00
0x00
OK
OK
ie. two instructions = byte code
length of 8
check length 24
Page 10 of 10