Dear Support,

I been using MyNewt v1.0.0-dev, and i tried to make use of Mqueue.

What i did was following the tutorial below:

https://mynewt.apache.org/os/core_os/mqueue/mqueue/
Since the tutorial is not updated, i tried to modify it but unfortunately i 
can't make it work.

Below are what i have done on Mqueue: (the main.c file is attached)
1. initialize Mqueue and eventq:
        
    /* Initialize eventq */
    os_eventq_init(&queue_task_evq);

    /* Initialize mqueue */
    os_mqueue_init(&rxpkt_q, &queue_task_handler, NULL);
2. Add queue_task_handler to process the data received:

void process_rx_data_queue(void)
{
    int i;
    struct os_mbuf *om;

    /* Drain all packets off queue and process them */
    while ((om = os_mqueue_get(&rxpkt_q)) != NULL) {
        const uint8_t *data = om->om_data;
        int temp_len = om->om_len;
        console_printf("Data get: ");
        for(i=0; i<temp_len; i++)
            console_printf("%02X ", *data++);
        console_printf("\n\r");

        os_mbuf_free_chain(om);
    }
}

static void queue_task_handler(struct os_event *ev)
{
    struct os_mbuf *m_resp;
    while ((m_resp = os_mqueue_get(&rxpkt_q)) != NULL)  {
        process_rx_data_queue();
    }
}

3. Put some data into the queue:

        /* Put data into mbuf */
        struct os_mbuf *om;
        memset(&om,0, sizeof(om));
        uint8_t temp_data[5];
        temp_data[0] = i;
        om->om_data = temp_data;
        om->om_len = 1;

        queue_task_rx_data_func(om);


int queue_task_rx_data_func(struct os_mbuf *om)
{
    int rc;

    rc = os_mqueue_put(&rxpkt_q, &queue_task_evq, om);
    if (rc != 0) {
        return -1;
    }

    return 0;
}

Please help me on anything i miss out or done wrongly.

Thank you very much.

Regards,

Then Yoong Ze


/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <assert.h>
#include <string.h>

// #include "esb.h"

#include "console/console.h"
#include "shell/shell.h"
#include "syscfg/syscfg.h"
#include "os/queue.h"
#include "os/os_eventq.h"

#include "sysinit/sysinit.h"
#include "os/os.h"
#include "bsp/bsp.h"
#include "hal/hal_gpio.h"
#ifdef ARCH_sim
#include "mcu/mcu_sim.h"
#endif

/* Init all tasks */
volatile int tasks_initialized;
int init_tasks(void);

/* Blinky Task */
#define BLINKY_TASK_PRIO (2)
#define BLINKY_STACK_SIZE    OS_STACK_ALIGN(256)
struct os_task blinky_task;
os_stack_t blinky_stack[BLINKY_STACK_SIZE];

/* Work Task */
#define WORK_TASK_PRIO (1)
#define WORK_STACK_SIZE      OS_STACK_ALIGN(256)
struct os_task work_task;
os_stack_t work_stack[WORK_STACK_SIZE];

/* Shell Task */
#define SHELL_TASK_PRIO (3)
#define SHELL_STACK_SIZE      OS_STACK_ALIGN(256)
struct os_task shell_task;
os_stack_t shell_stack[SHELL_STACK_SIZE];

/* Queue Task */
struct os_mqueue rxpkt_q;
struct os_eventq queue_task_evq;

int queue_task_rx_data_func(struct os_mbuf *om);

static volatile int g_task1_loops;

struct os_eventq blinky_evq;

/* For LED toggling */
int g_led_pin;

void shell_task_handler(void *arg)
{
    while(1){
        os_eventq_run(&blinky_evq);
    }
}

void work_task_handler(void *arg)
{
    struct os_task *t;

    g_led_pin = LED_BLINK_PIN;
    hal_gpio_init_out(g_led_pin, 1);

    while(1){
        t = os_sched_get_current_task();
        assert(t->t_func == work_task_handler);
        /* Do work... */
        int i;
        for(i=0; i<1000000; i++)
        {
            /* Simulate doing a noticeable amount of work */
            hal_gpio_write(g_led_pin, 1);
        }

        /* Put data into mbuf */
        struct os_mbuf *om;
        memset(&om,0, sizeof(om));
        uint8_t temp_data[5];
        temp_data[0] = i;
        om->om_data = temp_data;
        om->om_len = 1;

        queue_task_rx_data_func(om);
        console_printf("Entered\n\r");
        os_time_delay(3*OS_TICKS_PER_SEC);
    }
}

void blinky_task_handler(void *arg)
{
    struct os_task *t;

    g_led_pin = LED_BLINK_PIN;
    hal_gpio_init_out(g_led_pin, 1);

    while (1) {
        t = os_sched_get_current_task();
        assert(t->t_func == blinky_task_handler);

        ++g_task1_loops;

        /* Wait one second */
        os_time_delay(OS_TICKS_PER_SEC/10);

        /* Toggle the LED */
        hal_gpio_toggle(g_led_pin); 
    }
}

void process_rx_data_queue(void)
{
    int i;
    struct os_mbuf *om;

    /* Drain all packets off queue and process them */
    while ((om = os_mqueue_get(&rxpkt_q)) != NULL) {
        const uint8_t *data = om->om_data;
        int temp_len = om->om_len;
        console_printf("Data get: ");
        for(i=0; i<temp_len; i++)
            console_printf("%02X ", *data++);
        console_printf("\n\r");

        os_mbuf_free_chain(om);
    }
}

int queue_task_rx_data_func(struct os_mbuf *om)
{
    int rc;

    rc = os_mqueue_put(&rxpkt_q, &queue_task_evq, om);
    if (rc != 0) {
        return -1;
    }

    return 0;
}

static void queue_task_handler(struct os_event *ev)
{
    struct os_mbuf *m_resp;
    while ((m_resp = os_mqueue_get(&rxpkt_q)) != NULL)  {
        process_rx_data_queue();
    }
}

/**
 * init_tasks
 *
 * Called by main.c after os_init(). This function performs initializations
 * that are required before tasks are running.
 *
 * @return int 0 success; error otherwise.
 */
int
init_tasks(void)
{
    os_task_init(&work_task, "work", work_task_handler, NULL,
        WORK_TASK_PRIO, OS_WAIT_FOREVER, work_stack, WORK_STACK_SIZE);

    os_task_init(&blinky_task, "blinky", blinky_task_handler, NULL,
            BLINKY_TASK_PRIO, OS_WAIT_FOREVER, blinky_stack, BLINKY_STACK_SIZE);

    os_task_init(&shell_task, "shell", shell_task_handler, NULL,
            SHELL_TASK_PRIO, OS_WAIT_FOREVER, shell_stack, SHELL_STACK_SIZE);
    /* Shell/Console */
    shell_init();

    tasks_initialized = 1;

    return 0;
}


/**
 * main
 *
 * The main function for the project. This function initializes the os, calls
 * init_tasks to initialize tasks (and possibly other objects), then starts the
 * OS. We should not return from os start.
 *
 * @return int NOTE: this function should never return!
 */
int
main(int argc, char **argv)
{
    int rc;

#ifdef ARCH_sim
    mcu_sim_parse_args(argc, argv);
#endif

    sysinit();

    /* Initialize eventq for the application task. */
    os_eventq_init(&blinky_evq);

    /* Initialize eventq */
    os_eventq_init(&queue_task_evq);

    /* Initialize mqueue */
    os_mqueue_init(&rxpkt_q, &queue_task_handler, NULL);

    rc = init_tasks();
    assert(rc == 0);

    /* Set the default eventq for packages that lack a dedicated task. */
    os_eventq_dflt_set(&blinky_evq);

    os_start();

    /* os start should never return. If it does, this should be an error */
    assert(0);

    return rc;
}

Reply via email to