Merge branch 'memory-test' of mhu/reflow-oven-control-sw into dev
This commit is contained in:
commit
00c796c58f
126
stm-firmware/boot/startup-tests.c
Normal file
126
stm-firmware/boot/startup-tests.c
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#include "startup-tests.h"
|
||||||
|
|
||||||
|
uint32_t startup_test_perform_ccm_ram_check(void)
|
||||||
|
{
|
||||||
|
const void *ccmram_base = (void *)0x10000000UL;
|
||||||
|
const uint32_t ccmram_size = 64U * 1024UL;
|
||||||
|
volatile uint32_t *word_ptr;
|
||||||
|
uint32_t target_val;
|
||||||
|
uint32_t idx;
|
||||||
|
uint32_t ret = 0UL;
|
||||||
|
|
||||||
|
|
||||||
|
/* Perform inversion test with 0x55 and 0xAA, Part 1 */
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) {
|
||||||
|
word_ptr[idx] = idx & 1 ? 0x55AA55AAUL : 0xAA55AA55UL;
|
||||||
|
}
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) {
|
||||||
|
target_val = idx & 1 ? 0x55AA55AAUL : 0xAA55AA55UL;
|
||||||
|
if (target_val != word_ptr[idx]) {
|
||||||
|
ret = (uint32_t)&word_ptr[idx];
|
||||||
|
goto exit_ret_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform inversion test with 0x55 and 0xAA, Part 2 */
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) {
|
||||||
|
word_ptr[idx] = idx & 1 ? 0xAA55AA55UL : 0x55AA55AAUL;
|
||||||
|
}
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) {
|
||||||
|
target_val = idx & 1 ? 0xAA55AA55UL : 0x55AA55AAUL;
|
||||||
|
if (target_val != word_ptr[idx]) {
|
||||||
|
ret = (uint32_t)&word_ptr[idx];
|
||||||
|
goto exit_ret_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform static test with 0xFF */
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) {
|
||||||
|
word_ptr[idx] = 0xFFFFFFFFUL;
|
||||||
|
}
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) {
|
||||||
|
target_val = 0xFFFFFFFFUL;
|
||||||
|
if (target_val != word_ptr[idx]) {
|
||||||
|
ret = (uint32_t)&word_ptr[idx];
|
||||||
|
goto exit_ret_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform static test with 0x00 */
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) {
|
||||||
|
word_ptr[idx] = 0x0UL;
|
||||||
|
}
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ccmram_base; idx < ccmram_size / 4U; idx++) {
|
||||||
|
target_val = 0x0UL;
|
||||||
|
if (target_val != word_ptr[idx]) {
|
||||||
|
ret = (uint32_t)&word_ptr[idx];
|
||||||
|
goto exit_ret_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
exit_ret_address:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t startup_test_perform_system_ram_check()
|
||||||
|
{
|
||||||
|
const void *ram_base = (void *)0x20000000UL;
|
||||||
|
const uint32_t ram_size = 128U * 1024UL;
|
||||||
|
volatile uint32_t *word_ptr;
|
||||||
|
uint32_t target_val;
|
||||||
|
uint32_t idx;
|
||||||
|
uint32_t ret = 0UL;
|
||||||
|
|
||||||
|
|
||||||
|
/* Perform inversion test with 0x55 and 0xAA, Part 1 */
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ram_base; idx < ram_size / 4U; idx++) {
|
||||||
|
word_ptr[idx] = idx & 1 ? 0x55AA55AAUL : 0xAA55AA55UL;
|
||||||
|
}
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ram_base; idx < ram_size / 4U; idx++) {
|
||||||
|
target_val = idx & 1 ? 0x55AA55AAUL : 0xAA55AA55UL;
|
||||||
|
if (target_val != word_ptr[idx]) {
|
||||||
|
ret = (uint32_t)&word_ptr[idx];
|
||||||
|
goto exit_ret_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform inversion test with 0x55 and 0xAA, Part 2 */
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ram_base; idx < ram_size / 4U; idx++) {
|
||||||
|
word_ptr[idx] = idx & 1 ? 0xAA55AA55UL : 0x55AA55AAUL;
|
||||||
|
}
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ram_base; idx < ram_size / 4U; idx++) {
|
||||||
|
target_val = idx & 1 ? 0xAA55AA55UL : 0x55AA55AAUL;
|
||||||
|
if (target_val != word_ptr[idx]) {
|
||||||
|
ret = (uint32_t)&word_ptr[idx];
|
||||||
|
goto exit_ret_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform static test with 0xFF */
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ram_base; idx < ram_size / 4U; idx++) {
|
||||||
|
word_ptr[idx] = 0xFFFFFFFFUL;
|
||||||
|
}
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ram_base; idx < ram_size / 4U; idx++) {
|
||||||
|
target_val = 0xFFFFFFFFUL;
|
||||||
|
if (target_val != word_ptr[idx]) {
|
||||||
|
ret = (uint32_t)&word_ptr[idx];
|
||||||
|
goto exit_ret_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform static test with 0x00 */
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ram_base; idx < ram_size / 4U; idx++) {
|
||||||
|
word_ptr[idx] = 0x0UL;
|
||||||
|
}
|
||||||
|
for (idx = 0, word_ptr = (volatile uint32_t *)ram_base; idx < ram_size / 4U; idx++) {
|
||||||
|
target_val = 0x0UL;
|
||||||
|
if (target_val != word_ptr[idx]) {
|
||||||
|
ret = (uint32_t)&word_ptr[idx];
|
||||||
|
goto exit_ret_address;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exit_ret_address:
|
||||||
|
return ret;
|
||||||
|
}
|
25
stm-firmware/boot/startup-tests.h
Normal file
25
stm-firmware/boot/startup-tests.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef _STARTUP_TESTS_H_
|
||||||
|
#define _STARTUP_TESTS_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Do a RAM check of the CCM RAM.
|
||||||
|
*
|
||||||
|
* Loop over the whole CCM memory area and check it.
|
||||||
|
*
|
||||||
|
* @return 0 if successful. Else the defect address is returned.
|
||||||
|
* @warning This will completely corrupt this memory!
|
||||||
|
* You have to ensure to set it to sane values afterwards!
|
||||||
|
*/
|
||||||
|
uint32_t startup_test_perform_ccm_ram_check(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Do a RAM check of the stnadard SRAM regions
|
||||||
|
* @return 0 if successful. If an error is found, the faulty address is returned
|
||||||
|
* @warning This completely destroys all content in the memory!
|
||||||
|
* @warning Ensure that the stack pointer is moved to a different memory reagion (CCM RAM)!
|
||||||
|
*/
|
||||||
|
uint32_t startup_test_perform_system_ram_check(void);
|
||||||
|
|
||||||
|
#endif /* _STARTUP_TESTS_H_ */
|
@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "startup-tests.h"
|
||||||
|
|
||||||
/* C++ library init */
|
/* C++ library init */
|
||||||
# if defined(__cplusplus)
|
# if defined(__cplusplus)
|
||||||
@ -288,7 +289,7 @@ extern unsigned int __ld_eheap;
|
|||||||
|
|
||||||
#define CPACR (*((volatile uint32_t *)0xE000ED88))
|
#define CPACR (*((volatile uint32_t *)0xE000ED88))
|
||||||
|
|
||||||
void Reset_Handler(void) {
|
void __attribute__((noreturn)) Reset_Handler(void) {
|
||||||
/* Stack is already initialized by hardware */
|
/* Stack is already initialized by hardware */
|
||||||
|
|
||||||
/* The first thing we do here, is to initialize the FPU
|
/* The first thing we do here, is to initialize the FPU
|
||||||
@ -297,6 +298,9 @@ void Reset_Handler(void) {
|
|||||||
*/
|
*/
|
||||||
CPACR |= (0xF << 20);
|
CPACR |= (0xF << 20);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare RAM etc for the System Init function. This ensures, the RAM tests execute at max speed.
|
||||||
|
*/
|
||||||
|
|
||||||
/* Copy .data section */
|
/* Copy .data section */
|
||||||
__init_section(&__ld_load_data, &__ld_sdata, &__ld_edata);
|
__init_section(&__ld_load_data, &__ld_sdata, &__ld_edata);
|
||||||
@ -311,6 +315,41 @@ void Reset_Handler(void) {
|
|||||||
|
|
||||||
/* Set clocks, waitstates, ART operation etc. */
|
/* Set clocks, waitstates, ART operation etc. */
|
||||||
SystemInit();
|
SystemInit();
|
||||||
|
|
||||||
|
if (startup_test_perform_ccm_ram_check()) {
|
||||||
|
/* Hang forever in case of an error. We cannot handle this (yet?) */
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the Stack pointer to CCMRAM
|
||||||
|
* This allows us to perform a RAM test on the main RAM.
|
||||||
|
* Note: sp is not required to be inside the clobber list!
|
||||||
|
*/
|
||||||
|
__asm__ __volatile__ ("mov sp, %0\n\t" :: "r"(0x10000000UL + (64U * 1024UL)) :);
|
||||||
|
|
||||||
|
if (startup_test_perform_system_ram_check()) {
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move the stack pointer back. Note: This only works if this function does not use the stack for variables.
|
||||||
|
* Otherwise everything will be broken.
|
||||||
|
*/
|
||||||
|
__asm__ __volatile__ ("mov sp, %0\n\t" :: "r"(&__ld_top_of_stack) :);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RAM tests destroyed our values. So we have to copy them again...
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copy .data section */
|
||||||
|
__init_section(&__ld_load_data, &__ld_sdata, &__ld_edata);
|
||||||
|
/* Fill bss with zero */
|
||||||
|
__fill_zero(&__ld_sbss, &__ld_ebss);
|
||||||
|
/* Fill Heap with zero */
|
||||||
|
__fill_zero(&__ld_sheap, &__ld_eheap);
|
||||||
|
/* Fill static CCM memory with zeroes */
|
||||||
|
__fill_zero(&__ld_sbss_ccm, &__ld_ebss_ccm);
|
||||||
|
/* Init CCM RAM data section */
|
||||||
|
__init_section(&__ld_load_ccm_data, &__ld_sdata_ccm, &__ld_edata_ccm);
|
||||||
|
|
||||||
/* C++ init function */
|
/* C++ init function */
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
Loading…
Reference in New Issue
Block a user