New module starts but runs only once

Hello, I am new here and come from ardupilot, I want to switch to PX4.
I build a new module on PX4 with pixhawk. The code compiles, the module is started automatically after I added it to the rc.mc_apps but does run only one time.

When I start the module by hand through rsh, it does run only when I hit the enter key.
Do you know where it comes from?

Thanks

Impossible to tell without seeing the code.

/****************************************************************************
*

  • Copyright © 2018 PX4 Development Team. All rights reserved.
  • 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.
    1. 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.
    1. Neither the name PX4 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 OWNER 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.

****************************************************************************/

#include “rotary_wing.h”

int RotaryWing::print_usage(const char *reason)
{
if (reason) {
PX4_WARN("%s\n", reason);
}

PRINT_MODULE_DESCRIPTION(
	R"DESCR_STR(

Description

Section that describes the provided module functionality.

This is a template for a module running as a task in the background with start/stop/status functionality.

Implementation

Section describing the high-level implementation of this module.

Examples

CLI usage example:
$ module start -f -p 42

)DESCR_STR");

PRINT_MODULE_USAGE_NAME("module", "system");
PRINT_MODULE_USAGE_COMMAND("start");
PRINT_MODULE_USAGE_PARAM_FLAG('f', "Optional example flag", true);
PRINT_MODULE_USAGE_PARAM_INT('p', 0, 0, 1000, "Optional example parameter", true);
PRINT_MODULE_USAGE_DEFAULT_COMMANDS();

return 0;

}

int RotaryWing::print_status()
{
PX4_INFO(“Running”);
// TODO: print additional runtime information about the state of the module

return 0;

}

int RotaryWing::custom_command(int argc, char argv[])
{
/

if (!is_running()) {
print_usage(“not running”);
return 1;
}

// additional custom commands can be handled like this:
if (!strcmp(argv[0], "do-something")) {
	get_instance()->do_something();
	return 0;
}
 */

return print_usage("unknown command");

}

int RotaryWing::task_spawn(int argc, char *argv[])
{
_task_id = px4_task_spawn_cmd(“rotary_wing”,
SCHED_DEFAULT,
SCHED_PRIORITY_ATTITUDE_CONTROL,
1700,
(px4_main_t)&run_trampoline,
(char *const *)argv);

if (_task_id < 0) {
	_task_id = -1;
	return -errno;
}

return 0;

}

RotaryWing *RotaryWing::instantiate(int argc, char *argv[])
{
int example_param = 0;
bool example_flag = false;
bool error_flag = false;

int myoptind = 1;
int ch;
const char *myoptarg = nullptr;

// parse CLI arguments
while ((ch = px4_getopt(argc, argv, "p:f", &myoptind, &myoptarg)) != EOF) {
	switch (ch) {
	case 'p':
		example_param = (int)strtol(myoptarg, nullptr, 10);
		break;

	case 'f':
		example_flag = true;
		break;

	case '?':
		error_flag = true;
		break;

	default:
		PX4_WARN("unrecognized flag");
		error_flag = true;
		break;
	}
}

if (error_flag) {
	return nullptr;
}

RotaryWing *instance = new RotaryWing();

if (instance == nullptr) {
	PX4_ERR("alloc failed");
}

return instance;

}

RotaryWing::RotaryWing()
: ModuleParams(nullptr)
{
}

void RotaryWing::parameter_update_poll()
{
bool updated;

/* Check if parameters have changed */
orb_check(_params_sub, &updated);

if (updated) {
	struct parameter_update_s param_update;
	orb_copy(ORB_ID(parameter_update), _params_sub, &param_update);
	//updateParams();
	//parameters_updated();
}

}

void RotaryWing::sensor_mag_update_poll()
{
bool updated;

orb_check(_sensor_mag_sub, &updated);

if (updated) {
	orb_copy(ORB_ID(sensor_mag), _sensor_mag_sub, &_sensor_mag);
}

}

void RotaryWing::rc_channels_update_poll()
{
bool updated;

orb_check(_rc_channels_sub, &updated);

if (updated) {
	orb_copy(ORB_ID(rc_channels), _rc_channels_sub, &_rc_channels);
}

}

void RotaryWing::run()
{
_params_sub = orb_subscribe(ORB_ID(parameter_update));
_sensor_mag_sub = orb_subscribe(ORB_ID(sensor_mag));
_rc_channels_sub = orb_subscribe(ORB_ID(rc_channels));

px4_pollfd_struct_t fds={};
fds.events = POLLIN;

while (!should_exit()) {

	// wait for up to 100ms for data
	int pret = px4_poll(&fds, 1, 100);

	if (pret == 0) {
		continue;
	} 
	
	if (pret < 0) {
		// this is undesirable but not much we can do
		PX4_ERR("poll error %d, %d", pret, errno);
		usleep(100000);
		continue;

	}
	
    if (fds.revents & POLLIN) {
    	usleep(10000);
		sensor_mag_update_poll();
		rc_channels_update_poll();
		
		float heading = atanf(_sensor_mag.y/_sensor_mag.x);
		
		if (_sensor_mag.x < 0.0f) {
			heading += (float)M_PI;
		}
		
		if (heading > (float)M_PI) {
			heading = (float)M_PI-heading;
		}
		
		PX4_INFO("Magnetometer heading:\t%8.4f, rc0:\t%8.4f, rc1:\t%8.4f, rc2:\t%8.4f, rc3:\t%8.4f",
			(double)heading*(double)180.0f/M_PI,
			(double)_rc_channels.channels[0],
			(double)_rc_channels.channels[1],
			(double)_rc_channels.channels[2],
			(double)_rc_channels.channels[3]);
		
		_actuators.control[0] = _rc_channels.channels[0]*cosf(heading)+_rc_channels.channels[1]*sinf(heading);
		_actuators.control[1] = -_actuators.control[0];
		_actuators.control[3] = _rc_channels.channels[2];
		
		if (_actuators_0_pub != nullptr) {
			orb_publish(ORB_ID(actuator_controls_0), _actuators_0_pub, &_actuators);
		} else {
			_actuators_0_pub = orb_advertise(ORB_ID(actuator_controls_0), &_actuators);
		}
	}
	//parameters_update(parameter_update_sub);
}

orb_unsubscribe(_sensor_mag_sub);
orb_unsubscribe(_params_sub);
orb_unsubscribe(_rc_channels_sub);

}

void RotaryWing::parameters_update(int parameter_update_sub, bool force)
{
bool updated;
struct parameter_update_s param_upd;

orb_check(parameter_update_sub, &updated);

if (updated) {
	orb_copy(ORB_ID(parameter_update), parameter_update_sub, &param_upd);
}

if (force || updated) {
	updateParams();
}

}

int rotary_wing_main(int argc, char *argv[])
{
return RotaryWing::main(argc, argv);
}