Beispiel #1
0
void shutdown_worker(void *arg)
{
	PX4_DEBUG("shutdown worker (%i)", shutdown_counter);
	bool done = true;

	pthread_mutex_lock(&shutdown_mutex);

	for (int i = 0; i < max_shutdown_hooks; ++i) {
		if (shutdown_hooks[i]) {
			if (!shutdown_hooks[i]()) {
				done = false;
			}
		}
	}

	if ((done && shutdown_lock_counter == 0) || ++shutdown_counter > shutdown_timeout_ms / 10) {
		if (shutdown_args & SHUTDOWN_ARG_REBOOT) {
			PX4_WARN("Reboot NOW.");
			px4_systemreset(shutdown_args & SHUTDOWN_ARG_TO_BOOTLOADER);

		} else {
			PX4_WARN("Shutdown NOW. Good Bye.");
			board_shutdown();
		}

		pthread_mutex_unlock(&shutdown_mutex); // must NEVER come here

	} else {
		pthread_mutex_unlock(&shutdown_mutex);
		work_queue(HPWORK, &shutdown_work, (worker_t)&shutdown_worker, nullptr, USEC2TICK(10000));
	}
}
	bool handleRestartRequest(uavcan::NodeID request_source) override
	{
		::syslog(LOG_INFO, "UAVCAN: Restarting by request from %i\n", int(request_source.get()));
		::usleep(20 * 1000 * 1000);
		px4_systemreset(false);
		return true; // Will never be executed BTW
	}
Beispiel #3
0
int px4_shutdown_request(bool reboot, bool to_bootloader)
{
	int ret = 0;
	pthread_mutex_lock(&shutdown_mutex);

	// FIXME: if shutdown_lock_counter > 0, we should wait, but unfortunately we don't have work queues
	if (reboot) {
		px4_systemreset(to_bootloader);

	} else {
		ret = board_shutdown();
	}

	pthread_mutex_unlock(&shutdown_mutex);

	return ret;
}
Beispiel #4
0
int reboot_main(int argc, char *argv[])
{
	int ch;
	bool to_bootloader = false;

	int myoptind = 1;
	const char *myoptarg = NULL;

	while ((ch = px4_getopt(argc, argv, "b", &myoptind, &myoptarg)) != -1) {
		switch (ch) {
		case 'b':
			to_bootloader = true;
			break;

		default:
			PX4_ERR("usage: reboot [-b]\n"
				"   -b   reboot into the bootloader");

		}
	}

	px4_systemreset(to_bootloader);
}
static void cb_reboot(const uavcan::TimerEvent &)
{
	px4_systemreset(false);

}
Beispiel #6
0
__EXPORT void board_crashdump(uintptr_t currentsp, FAR void *tcb, FAR const uint8_t *filename, int lineno)
{
	/* We need a chunk of ram to save the complete context in.
	 * Since we are going to reboot we will use &_sdata
	 * which is the lowest memory and the amount we will save
	 * _should be_ below any resources we need herein.
	 * Unfortunately this is hard to test. See dead below
	 */

	fullcontext_s *pdump = (fullcontext_s *)&_sdata;

	(void)enter_critical_section();

	struct tcb_s *rtcb = (struct tcb_s *)tcb;

	/* Zero out everything */

	memset(pdump, 0, sizeof(fullcontext_s));

	/* Save Info */

	pdump->info.lineno = lineno;

	if (filename) {

		int offset = 0;
		unsigned int len = strlen((char *)filename) + 1;

		if (len > sizeof(pdump->info.filename)) {
			offset = len - sizeof(pdump->info.filename) ;
		}

		strncpy(pdump->info.filename, (char *)&filename[offset], sizeof(pdump->info.filename));
	}

	/* Save the value of the pointer for current_regs as debugging info.
	 * It should be NULL in case of an ASSERT and will aid in cross
	 * checking the validity of system memory at the time of the
	 * fault.
	 */

	pdump->info.current_regs = (uintptr_t) CURRENT_REGS;

	/* Save Context */


#if CONFIG_TASK_NAME_SIZE > 0
	strncpy(pdump->info.name, rtcb->name, CONFIG_TASK_NAME_SIZE);
#endif

	pdump->info.pid = rtcb->pid;


	/* If  current_regs is not NULL then we are in an interrupt context
	 * and the user context is in current_regs else we are running in
	 * the users context
	 */

	if (CURRENT_REGS) {
		pdump->info.stacks.interrupt.sp = currentsp;

		pdump->info.flags |= (eRegsPresent | eUserStackPresent | eIntStackPresent);
		memcpy(pdump->info.regs, (void *)CURRENT_REGS, sizeof(pdump->info.regs));
		pdump->info.stacks.user.sp = pdump->info.regs[REG_R13];

	} else {

		/* users context */
		pdump->info.flags |= eUserStackPresent;

		pdump->info.stacks.user.sp = currentsp;
	}

	if (pdump->info.pid == 0) {

		pdump->info.stacks.user.top = g_idle_topstack - 4;
		pdump->info.stacks.user.size = CONFIG_IDLETHREAD_STACKSIZE;

	} else {
		pdump->info.stacks.user.top = (uint32_t) rtcb->adj_stack_ptr;
		pdump->info.stacks.user.size = (uint32_t) rtcb->adj_stack_size;;
	}

#if CONFIG_ARCH_INTERRUPTSTACK > 3

	/* Get the limits on the interrupt stack memory */

	pdump->info.stacks.interrupt.top = (uint32_t)&g_intstackbase;
	pdump->info.stacks.interrupt.size  = (CONFIG_ARCH_INTERRUPTSTACK & ~3);

	/* If In interrupt Context save the interrupt stack data centered
	 * about the interrupt stack pointer
	 */

	if ((pdump->info.flags & eIntStackPresent) != 0) {
		stack_word_t *ps = (stack_word_t *) pdump->info.stacks.interrupt.sp;
		copy_reverse(pdump->istack, &ps[arraySize(pdump->istack) / 2], arraySize(pdump->istack));
	}

	/* Is it Invalid? */

	if (!(pdump->info.stacks.interrupt.sp <= pdump->info.stacks.interrupt.top &&
	      pdump->info.stacks.interrupt.sp > pdump->info.stacks.interrupt.top - pdump->info.stacks.interrupt.size)) {
		pdump->info.flags |= eInvalidIntStackPrt;
	}

#endif

	/* If In interrupt context or User save the user stack data centered
	 * about the user stack pointer
	 */
	if ((pdump->info.flags & eUserStackPresent) != 0) {
		stack_word_t *ps = (stack_word_t *) pdump->info.stacks.user.sp;
		copy_reverse(pdump->ustack, &ps[arraySize(pdump->ustack) / 2], arraySize(pdump->ustack));
	}

	/* Is it Invalid? */

	if (!(pdump->info.stacks.user.sp <= pdump->info.stacks.user.top &&
	      pdump->info.stacks.user.sp > pdump->info.stacks.user.top - pdump->info.stacks.user.size)) {
		pdump->info.flags |= eInvalidUserStackPtr;
	}

	int rv = stm32_bbsram_savepanic(HARDFAULT_FILENO, (uint8_t *)pdump, sizeof(fullcontext_s));

	/* Test if memory got wiped because of using _sdata */

	if (rv == -ENXIO) {
		char *dead = "Memory wiped - dump not saved!";

		while (*dead) {
			up_lowputc(*dead++);
		}

	} else if (rv == -ENOSPC) {

		/* hard fault again */

		up_lowputc('!');
	}


#if defined(CONFIG_BOARD_RESET_ON_CRASH)
	px4_systemreset(false);
#endif
}
Beispiel #7
0
int
test_mount(int argc, char *argv[])
{
    const unsigned iterations = 2000;
    const unsigned alignments = 10;

    const char *cmd_filename = "/fs/microsd/mount_test_cmds.txt";


    /* check if microSD card is mounted */
    struct stat buffer;

    if (stat(PX4_ROOTFSDIR "/fs/microsd/", &buffer)) {
        PX4_ERR("no microSD card mounted, aborting file test");
        return 1;
    }

    /* list directory */
    DIR		*d;
    struct dirent	*dir;
    d = opendir(PX4_ROOTFSDIR "/fs/microsd");

    if (d) {

        while ((dir = readdir(d)) != NULL) {
            //printf("%s\n", dir->d_name);
        }

        closedir(d);

        PX4_INFO("directory listing ok (FS mounted and readable)");

    } else {
        /* failed opening dir */
        PX4_ERR("FAILED LISTING MICROSD ROOT DIRECTORY");

        if (stat(cmd_filename, &buffer) == OK) {
            (void)unlink(cmd_filename);
        }

        return 1;
    }

    /* read current test status from file, write test instructions for next round */

    /* initial values */
    int it_left_fsync = fsync_tries;
    int it_left_abort = abort_tries;

    int cmd_fd;

    if (stat(cmd_filename, &buffer) == OK) {

        /* command file exists, read off state */
        cmd_fd = open(cmd_filename, O_RDWR | O_NONBLOCK);
        char buf[64];
        int ret = read(cmd_fd, buf, sizeof(buf));

        if (ret > 0) {
            int count = 0;
            ret = sscanf(buf, "TEST: %u %u %n", &it_left_fsync, &it_left_abort, &count);

        } else {
            buf[0] = '\0';
        }

        if (it_left_fsync > fsync_tries) {
            it_left_fsync = fsync_tries;
        }

        if (it_left_abort > abort_tries) {
            it_left_abort = abort_tries;
        }

        PX4_INFO("Iterations left: #%d / #%d of %d / %d\n(%s)", it_left_fsync, it_left_abort,
                 fsync_tries, abort_tries, buf);

        int it_left_fsync_prev = it_left_fsync;

        /* now write again what to do next */
        if (it_left_fsync > 0) {
            it_left_fsync--;
        }

        if (it_left_fsync == 0 && it_left_abort > 0) {

            it_left_abort--;

            /* announce mode switch */
            if (it_left_fsync_prev != it_left_fsync && it_left_fsync == 0) {
                PX4_INFO("\n SUCCESSFULLY PASSED FSYNC'ED WRITES, CONTINUTING WITHOUT FSYNC");
                fsync(fileno(stdout));
                fsync(fileno(stderr));
                usleep(20000);
            }

        }

        if (it_left_abort == 0) {
            (void)unlink(cmd_filename);
            return 0;
        }

    } else {

        /* this must be the first iteration, do something */
        cmd_fd = open(cmd_filename, O_TRUNC | O_WRONLY | O_CREAT, PX4_O_MODE_666);

        PX4_INFO("First iteration of file test\n");
    }

    char buf[64];
    (void)sprintf(buf, "TEST: %d %d ", it_left_fsync, it_left_abort);
    lseek(cmd_fd, 0, SEEK_SET);
    write(cmd_fd, buf, strlen(buf) + 1);
    fsync(cmd_fd);

    /* perform tests for a range of chunk sizes */
    unsigned chunk_sizes[] = {32, 64, 128, 256, 512, 600, 1200};

    for (unsigned c = 0; c < (sizeof(chunk_sizes) / sizeof(chunk_sizes[0])); c++) {

        printf("\n\n====== FILE TEST: %u bytes chunks (%s) ======\n", chunk_sizes[c],
               (it_left_fsync > 0) ? "FSYNC" : "NO FSYNC");
        printf("unpower the system immediately (within 0.5s) when the hash (#) sign appears\n");
        fsync(fileno(stdout));
        fsync(fileno(stderr));
        usleep(50000);

        for (unsigned a = 0; a < alignments; a++) {

            printf(".");

            uint8_t write_buf[chunk_sizes[c] + alignments] __attribute__((aligned(64)));

            /* fill write buffer with known values */
            for (unsigned i = 0; i < sizeof(write_buf); i++) {
                /* this will wrap, but we just need a known value with spacing */
                write_buf[i] = i + 11;
            }

            uint8_t read_buf[chunk_sizes[c] + alignments] __attribute__((aligned(64)));

            int fd = px4_open(PX4_ROOTFSDIR "/fs/microsd/testfile", O_TRUNC | O_WRONLY | O_CREAT);

            for (unsigned i = 0; i < iterations; i++) {

                int wret = write(fd, write_buf + a, chunk_sizes[c]);

                if (wret != (int)chunk_sizes[c]) {
                    PX4_ERR("WRITE ERROR!");

                    if ((0x3 & (uintptr_t)(write_buf + a))) {
                        PX4_ERR("memory is unaligned, align shift: %d", a);
                    }

                    return 1;

                }

                if (it_left_fsync > 0) {
                    fsync(fd);

                } else {
                    printf("#");
                    fsync(fileno(stdout));
                    fsync(fileno(stderr));
                }
            }

            if (it_left_fsync > 0) {
                printf("#");
            }

            printf(".");
            fsync(fileno(stdout));
            fsync(fileno(stderr));
            usleep(200000);

            px4_close(fd);
            fd = px4_open(PX4_ROOTFSDIR "/fs/microsd/testfile", O_RDONLY);

            /* read back data for validation */
            for (unsigned i = 0; i < iterations; i++) {
                int rret = read(fd, read_buf, chunk_sizes[c]);

                if (rret != (int)chunk_sizes[c]) {
                    PX4_ERR("READ ERROR!");
                    return 1;
                }

                /* compare value */
                bool compare_ok = true;

                for (unsigned j = 0; j < chunk_sizes[c]; j++) {
                    if (read_buf[j] != write_buf[j + a]) {
                        PX4_WARN("COMPARISON ERROR: byte %d, align shift: %d", j, a);
                        compare_ok = false;
                        break;
                    }
                }

                if (!compare_ok) {
                    PX4_ERR("ABORTING FURTHER COMPARISON DUE TO ERROR");
                    return 1;
                }

            }

            int ret = unlink(PX4_ROOTFSDIR "/fs/microsd/testfile");
            px4_close(fd);

            if (ret) {
                px4_close(cmd_fd);
                PX4_ERR("UNLINKING FILE FAILED");
                return 1;
            }

        }
    }

    fsync(fileno(stdout));
    fsync(fileno(stderr));
    usleep(20000);

    px4_close(cmd_fd);

    /* we always reboot for the next test if we get here */
    PX4_INFO("Iteration done, rebooting..");
    fsync(fileno(stdout));
    fsync(fileno(stderr));
    usleep(50000);
    px4_systemreset(false);

    /* never going to get here */
    return 0;
}