Solved! The issue a similar name in my bootscript my main source file. Look at the answer for more details.
I've had this mind-boggling error for weeks now. I am compiling for the GD32V chip. What happens is, I have the following class, which abstracts the gpio pin output for the chip:
class pin_out : public hwlib::pin_out
{
private:
const pin_info_type & myPin;
bool status;
public:
pin_out(pins pin_number) : myPin(pin_info_array[(int)pin_number]){
rcu_periph_clock_enable(myPin.enable_register);
gpio_init(myPin.port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, myPin.pin);
gpio_bit_reset(myPin.port, myPin.pin);
status=0;
}
void write(bool x){
if(x){
status=1;
gpio_bit_set(myPin.port, myPin.pin);
}else{
gpio_bit_reset(myPin.port, myPin.pin);
status=0;
}
}
void flush(){
// Empty
}
void toggle(){
status=!status;
write(status);
}
};
This works great, I can make a pin and call 'pin.write(1)' and 'pin.write(0)' as many times as I want and it works. However, as soon as I instance 2 pins, i.e. pin1 and pin2... it doesn't matter if I write to the second pin or not, my code just doesn't run. However, now the funny part, if I copy/paste this pin_out class and rename it and instance 2 objects from these different classes, it does run again.
Here's how this class looks:
class test_pin_out{
private:
const pin_info_type & myPin;
public:
test_pin_out(pins pin_number) : myPin(pin_info_array[(int)pin_number]){
rcu_periph_clock_enable(myPin.enable_register);
gpio_init(myPin.port, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, myPin.pin);
gpio_bit_reset(myPin.port, myPin.pin);
}
void write(bool x){
if(x){
gpio_bit_set(myPin.port, myPin.pin);
}else{
gpio_bit_reset(myPin.port, myPin.pin);
}
}
};
And then I use this main:
#include "hwlib.hpp"
int main(void)
{
hwlib::target::pin_out pin1 = hwlib::target::pin_out(hwlib::target::pins::led_blue);
hwlib::target::test_pin_out pin2 = hwlib::target::test_pin_out(hwlib::target::pins::led_green);
while(true){
pin1.write(1);
pin2.write(1);
}
return 0;
}
I am using the official manufacturer's header files. Myself I am suspecting some optimization issue that happens within the device headers, as my code so far only runs with O2 and O3 optimization(not lower or higher).
Does anyone have any clue as to where I might have to look or how I can resolve this issue?
EDIT: As response to the replies, here is the class I inherit from. Hwlib::pin_out
class pin_out : public noncopyable {
public:
/// @copydoc pin_in_out::write()
virtual void write( bool x ) = 0;
/// @copydoc pin_in_out::flush()
virtual void flush() = 0;
};
And the class this class inherits from:
class noncopyable {
public:
noncopyable( const noncopyable& ) = delete;
noncopyable& operator=( const noncopyable& ) = delete;
constexpr noncopyable() {}
// ~noncopyable() {} // somehow requires the heap??
};
I finally solved it! The one thing I didn't expect to be the issue, was the issue.
Basically I had the linkerscript calling the bootscript. I grabbed these two files from a blogpost. However, the linkerscript called the bootscript's function, which was named 'main'. As my own function in my source file was also called 'main', something went wrong. So only my source's main function got called and not my bootscript, which meant my bss wasn't being reset to 0, which caused undefined behaviour.
Stupid on my part to not look into this, but I'm still quite new to all of this.