Skip to content

Commit

Permalink
Fixes to setup, and added example of using halucinator
Browse files Browse the repository at this point in the history
  • Loading branch information
clemen19 committed Jul 14, 2019
1 parent 56ca569 commit defe670
Show file tree
Hide file tree
Showing 15 changed files with 493 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.pyc
**/tmp/*
*.egg-info
1 change: 1 addition & 0 deletions 3rd_party/avatar-qemu
Submodule avatar-qemu added at 59cfd6
1 change: 1 addition & 0 deletions 3rd_party/avatar2
Submodule avatar2 added at c43d08
7 changes: 5 additions & 2 deletions 3rd_party/build_qemu.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/bash
source /etc/os-release
set -e

# if [[ "$ID" == "ubuntu" ]]
# then
Expand All @@ -9,11 +10,13 @@ source /etc/os-release
# fi

# May need to update to different repo
git clone https://github.com/avatartwo/avatar-qemu.git avatar-qemu
if [[! -d "/path/to/dir"]]
then
git clone https://github.com/avatartwo/avatar-qemu.git avatar-qemu
fi
cd avatar-qemu
git submodule update --init --recursive

git checkout qemu-3.1
./configure --disable-sdl --target-list=arm-softmmu
make -j4

96 changes: 96 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,99 @@ Examples of these files are given in the test directoy.
workon halucinator
./halucinator -c=<config_file.yaml> -a=<address_file.yaml> -m=<memory_file.yaml>
```


## Build STM MX Cube Examples

A tool to convert the STM's Software Workbench for STM (SW4STM),
This has only been tested on a few STM32F4 examples from STM32Cube_F4_V1.21.0.
It compile them as cortex-m3 devices and not cortex-m4 to enable easier
emulation in QEMU.

To use go into the directory below the SW4STM32 directory in the project and run
`<halucinator_repo_root>/src/tools/stm_tools/build_scripts/CubeMX2Makefile.py .`
Enter a name for the board, and the applications. Then run `make all`.
The binary created will be in `bin` directory

Example

```bash
cd STM32Cube_FW_F4_V1.21.0/Projects/STM32469I_EVAL/Examples/UART/UART_HyperTerminal_IT/SW4STM32/STM32469I_EVAL
<halucinator_repo_root>/src/tools/stm_tools/build_scripts/CubeMX2Makefile.py .
Board: STM32469I_Eval
APP: Uart_IT
make all
```


## STM32F469I Uart Example

To give an idea how to use Halucinator and example is provided `test/STM32/example`.

### Setup
Setup was done prior, but this procedure would be followed for other binaries.
In list below after the colon (:) denotes the file/cmd .

1. Compile binary as above
2. Copy binary to a dir of you choice and cd to it: `test/STM32/example`
3. Create binary file: `<halucinator_repo_root>/src/tools/make_bin.sh Uart_Hyperterminal_IT_O0.elf` creates `Uart_Hyperterminal_IT_O0.elf.bin`
4. Create Memory Layout (specifies memory map of chip): `Uart_Hyperterminal_IT_O0_memory.yaml`
5. Create Address File (maps function names to address): `Uart_Hyperterminal_IT_O0_addrs.yaml`
6. Create Config File (defines functions to intercept and what handler to use for it): `Uart_Hyperterminal_IT_O0_config.yaml`
7. (Optional) create shell script to run it: `run.sh`

Note: the Memory file can be created using `src/halucinator/util/elf_sym_hal_getter.py`
from an elf with symbols. This requires angr and pyyaml.
This was used to create `Uart_Hyperterminal_IT_O0_addrs`


### Running

Start the UART Peripheral device, this a script that will subscribe to the Uart on the peripheral server and
enable interacting with it.

```bash
workon halucinator
<halucinator_repo_root>$python -m halucinator.external_devices.uart -i=1073811456

```

In separate terminal start halucinator with the firmware.

```bash
workon halucinator
<halucinator_repo_root>$./halucinator -c=test/STM32/example/Uart_Hyperterminal_IT_O0_config.yaml \
-a=test/STM32/example/Uart_Hyperterminal_IT_O0_addr.yaml \
-m=test/STM32/example/Uart_Hyperterminal_IT_O0_memory.yaml --log_blocks -n Uart_Example

or
<halucinator_repo_root>$test/STM32/example/run.sh
```
Note the --log_blocks and -n are optional.

You will eventually see in both terminals messages containing
```
****UART-Hyperterminal communication based on IT ****
Enter 10 characters using keyboard :
```

Enter 10 Characters in the first terminal running the uart external device and press enter
should then see below in halucinator terminal
```
INFO:STM32F4UART:Waiting for data: 10
INFO:STM32F4UART:Got Data: 1342154134
INFO:STM32F4UART:Get State
INFO:STM32F4UART:Writing: 1342154134
INFO:STM32F4UART:Get State
INFO:STM32F4UART:Writing:
Example Finished
```


### Stopping

Avatar creates many threads and std input gets sent to QEMU thus killing it is not trivial.
I usually have to kill it with `ctrl-z` and `kill %`


7 changes: 7 additions & 0 deletions setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ workon halucinator
git clone https://github.com/avatartwo/avatar2.git 3rd_party/avatar2

pip install -e 3rd_party/avatar2

# Avatar broke emulate capability which halucinator uses,
# Use old commit until fixed
pushd 3rd_party/avatar2
git checkout c43d08f10b8fdc662d0cc66e4b3bd2d272c8c9ba
popd

pip install -r src/requirements.txt
pip install -e src

Expand Down
8 changes: 4 additions & 4 deletions src/halucinator/peripheral_models/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

class GenericPeripheral(AvatarPeripheral):
read_addresses = set()
def hw_read(self, offset, size, pc):
def hw_read(self, offset, size, pc=0xBAADBAAD):
log.info("%s: Read from addr, 0x%08x size %i, pc: %s" %(self.name,self.address + offset, size, hex(pc)))
addr = self.address + offset
hal_stats.write_on_update('MMIO_read_addresses', hex(addr))
Expand All @@ -26,7 +26,7 @@ def hw_read(self, offset, size, pc):
ret = 0
return ret

def hw_write(self, offset, size, value, pc):
def hw_write(self, offset, size, value, pc=0xBAADBAAD):
log.info("%s: Write to addr: 0x%08x, size: %i, value: 0x%08x, pc %s" %(self.name, self.address + offset, size, value, hex(pc)))
addr = self.address + offset
hal_stats.write_on_update('MMIO_write_addresses', hex(addr))
Expand All @@ -48,7 +48,7 @@ class HaltPeripheral(AvatarPeripheral):
'''
Just halts on first address read/written
'''
def hw_read(self, offset, size, pc):
def hw_read(self, offset, size, pc=0xBAADBAAD):
addr = self.address + offset
log.info("%s: Read from addr, 0x%08x size %i, pc: %s" %(self.name, addr, size, hex(pc)))
hal_stats.write_on_update('MMIO_read_addresses', hex(addr))
Expand All @@ -58,7 +58,7 @@ def hw_read(self, offset, size, pc):
while 1:
pass

def hw_write(self, offset, size, value, pc):
def hw_write(self, offset, size, value, pc=0xBAADBAAD):
addr = self.address + offset
log.info("%s: Write to addr: 0x%08x, size: %i, value: 0x%08x, pc %s" %(self.name, addr, size, value, hex(pc)))
hal_stats.write_on_update('MMIO_write_addresses', hex(addr))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

def get_names_for_addrs(stats_file, binary):



with open(stats_file, 'rb') as infile:
stats = yaml.safe_load(infile)

Expand All @@ -29,7 +27,7 @@ def get_names_for_addrs(stats_file, binary):
funcs['$unknown_function'].append(mmio_addr)

for func, data in funcs.items():
print '%s : %s' %(func, str(data))
print( '%s : %s' %(func, str(data)))



Expand Down
165 changes: 165 additions & 0 deletions test/STM32/example/STM_UART_readme-license.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/**
@page UART_Hyperterminal_IT UART Hyperterminal IT example

@verbatim
******************** (C) COPYRIGHT 2017 STMicroelectronics *******************
* @file UART/UART_Hyperterminal_IT/readme.txt
* @author MCD Application Team
* @brief Description of the UART Hyperterminal example.
******************************************************************************
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
@endverbatim

@par Example Description

This example describes an UART transmission (transmit/receive) between a board and
an Hyperterminal PC application by using an interrupt.

Board: STM32469I-EVAL
Tx Pin: PA.09
Rx Pin: PA.10
_________________________
| ______________| _______________
| |USART1 | | HyperTerminal |
| | | | |
| | TX |______________________|RX |
| | | | |
| | | RS232 Cable | |
| | | | |
| | RX |______________________|TX |
| | | | |
| |______________| |_______________|
| |
| |
| |
| |
|_STM32_Board_____________|

At the beginning of the main program the HAL_Init() function is called to reset
all the peripherals, initialize the Flash interface and the systick.
Then the SystemClock_Config() function is used to configure the system
clock (SYSCLK) to run at 180 MHz for STM32F4xx Devices.

The UART peripheral configuration is ensured by the HAL_UART_Init() function.
This later is calling the HAL_UART_MspInit()function which core is implementing
the configuration of the needed UART resources according to the used hardware.
You may update this function to change UART configuration.

The UART/Hyperterminal communication is then initiated.
The HAL_UART_Receive_IT() and the HAL_UART_Transmit_IT() functions allow respectively
the reception of Data from Hyperterminal and the transmission of a predefined data
buffer.

The Asynchronous communication aspect of the UART is clearly highlighted as the
data buffers transmission/reception to/from Hyperterminal are done simultaneously.

For this example the TxBuffer is predefined and the RxBuffer size is limited to
10 data by the mean of the RXBUFFERSIZE define in the main.c file.

In a first step the received data will be stored in the RxBuffer buffer and the
TxBuffer buffer content will be displayed in the Hyperterminal interface.
In a second step the received data in the RxBuffer buffer will be sent back to
Hyperterminal and displayed.
The end of this two steps are monitored through the HAL_UART_GetState() function
result.

STM32 Eval board's LEDs can be used to monitor the transfer status:
- LED1 is ON when the transmission process is complete.
- LED2 is ON when the reception process is complete.
- LED3 is ON when there is an error in transmission/reception process.

The UART is configured as follows:
- BaudRate = 9600 baud
- Word Length = 8 Bits (7 data bit + 1 parity bit)
- One Stop Bit
- Odd parity
- Hardware flow control disabled (RTS and CTS signals)
- Reception and transmission are enabled in the time

@note USARTx/UARTx instance used and associated resources can be updated in "main.h"
file depending hardware configuration used.

@note When the parity is enabled, the computed parity is inserted at the MSB
position of the transmitted data.

@note Care must be taken when using HAL_Delay(), this function provides accurate delay (in milliseconds)
based on variable incremented in SysTick ISR. This implies that if HAL_Delay() is called from
a peripheral ISR process, then the SysTick interrupt must have higher priority (numerically lower)
than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
To change the SysTick interrupt priority you have to use HAL_NVIC_SetPriority() function.

@note The application needs to ensure that the SysTick time base is always set to 1 millisecond
to have correct HAL operation.


@note The connection of the LCD reset pin to a dedicated GPIO PK7 instead of the STM32F469 NRST pin may cause residual display on LCD with applications/examples that do not require display.
The LCD clear can be ensured by hardware through the board's power off/power on or by software calling the BSP_LCD_Reset() function.

@par Directory contents

- UART/UART_Hyperterminal_IT/Inc/stm32f4xx_hal_conf.h HAL configuration file
- UART/UART_Hyperterminal_IT/Inc/stm32f4xx_it.h IT interrupt handlers header file
- UART/UART_Hyperterminal_IT/Inc/main.h Main program header file
- UART/UART_Hyperterminal_IT/Src/stm32f4xx_it.c IT interrupt handlers
- UART/UART_Hyperterminal_IT/Src/main.c Main program
- UART/UART_Hyperterminal_IT/Src/stm32f4xx_hal_msp.c HAL MSP file
- UART/UART_Hyperterminal_IT/Src/system_stm32f4xx.c STM32F4xx system source file


@par Hardware and Software environment

- This example runs on STM32F469xx/STM32F479xx devices.

- This example has been tested and validated with STMicroelectronics STM32469I-EVAL RevC board and can be
easily tailored to any other supported device and development board.

- STM32469I-EVAL Set-up
- Connect a null-modem female/female RS232 cable between the DB9 connector
- TARGET_STM32469I_EVAL Set-up
- Connect a null-modem female/female RS232 cable between the DB9 connector CN7 (USART1)
and PC serial port on which you want to display data on the HyperTerminal.
@note Make sure that :
- jumper JP8 is on RS232_RX position (1-2) and
- jumper JP15 is on USART1_RX position 1-2)and
- jumper JP19 is on USART1_TX position (1-2).

- Hyperterminal configuration:
- Word Length = 7 Bits
- One Stop Bit
- Odd parity
- BaudRate = 9600 baud
- flow control: None


@par How to use it ?

In order to make the program work, you must do the following :
- Open your preferred toolchain
- Rebuild all files and load your image into target memory
- Run the example

* <h3><center>&copy; COPYRIGHT STMicroelectronics</center></h3>
*/
Binary file added test/STM32/example/Uart_Hyperterminal_IT_O0.elf
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit defe670

Please sign in to comment.