Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save TorstenRobitzki/0ca56010f3ddc3cefe32f3f38c899a1a to your computer and use it in GitHub Desktop.
Save TorstenRobitzki/0ca56010f3ddc3cefe32f3f38c899a1a to your computer and use it in GitHub Desktop.
Bloat generator
#include <nrf.h>
#include <cstdint>
#include <type_traits>
#include <utility>
#include "bootloader/services.hpp"
/* we need a large constant data section to simulate a real firmware size-wise */
/* The data should be random enough that it can not be compressed to easy and
care should be taken, that it doesn't get optimized away */
template < int C >
using int_c = std::integral_constant< int, C >;
template < std::size_t S, int Seed, typename Values = std::tuple<> >
struct generate_one_k_bloat;
template < int Seed, typename ...Values >
struct generate_one_k_bloat< 0, Seed, std::tuple< Values... > >
{
using type = std::tuple< Values... >;
};
template < std::size_t S, int Seed, typename ...Values >
struct generate_one_k_bloat< S, Seed, std::tuple< Values... > >
{
using type = typename generate_one_k_bloat< S - 1, Seed + 683, std::tuple< int_c< Seed >, Values... > >::type;
};
template < int Seed = 0 >
using one_k_bloat_values = typename generate_one_k_bloat< 1024 / sizeof( int ), Seed >::type;
template < typename Kilo >
struct bloat_holder;
template < typename ...Values >
struct bloat_holder< std::tuple< Values... > >
{
static const int data[ sizeof ...(Values) ];
};
template < typename ...Values >
const int bloat_holder< std::tuple< Values... > >::data[ sizeof ...(Values) ] = { Values::value... };
template < std::size_t KilobytesOfBloat = 20 >
struct bloat;
template <>
struct bloat< 0 >
{
int at( std::size_t ) const
{
return 0;
}
};
template < std::size_t KilobytesOfBloat >
struct bloat : bloat< KilobytesOfBloat - 1 >, bloat_holder< one_k_bloat_values< static_cast< int >( KilobytesOfBloat ) > >
{
using kilo_bloat = bloat_holder< one_k_bloat_values< static_cast< int >( KilobytesOfBloat ) > >;
static constexpr std::size_t values_per_k = 1024 / sizeof( int );
static constexpr std::size_t size = KilobytesOfBloat * values_per_k;
int at( std::size_t i ) const
{
return i >= values_per_k * ( KilobytesOfBloat - 1 )
? kilo_bloat::data[ i - values_per_k * ( KilobytesOfBloat - 1 ) ]
: bloat< KilobytesOfBloat - 1 >::at( i );
}
};
static constexpr std::uint32_t led_pin = 17;
static constexpr std::uint32_t button_pin = 13;
static void init()
{
// start high freuquence clock source if not done yet
if ( !NRF_CLOCK->EVENTS_HFCLKSTARTED )
{
NRF_CLOCK->TASKS_HFCLKSTART = 1;
while ( !NRF_CLOCK->EVENTS_HFCLKSTARTED )
;
}
SysTick_Config( SystemCoreClock / 1000 );
NVIC_EnableIRQ(SysTick_IRQn);
NRF_P0->PIN_CNF[ led_pin ] =
( GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos )
| ( GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos )
| ( GPIO_PIN_CNF_DRIVE_H0D1 << GPIO_PIN_CNF_DRIVE_Pos );
NRF_P0->PIN_CNF[ button_pin ] =
( GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos )
| ( GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos );
}
static volatile std::uint32_t systick_cnt = 0;
extern "C" void SysTick_Handler()
{
++systick_cnt;
}
void main_entry()
{
init();
bloat<> bloat_data;
static_cast< void >( bloat_data );
for ( ; ; )
{
for ( auto now = systick_cnt + 1000; systick_cnt < now; )
;
if ( bloat_data.at( 1 ) )
NRF_P0->OUTSET = 1 << led_pin;
for ( auto now = systick_cnt + 1000; systick_cnt < now; )
;
if ( bloat_data.at( 45 ) )
NRF_P0->OUTCLR = 1 << led_pin;
if ( ( NRF_P0->IN & ( 1 << button_pin ) ) == 0 )
start_bootloader();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment