Debugging Mailboxes ChibiOS

This forum is dedicated to feedback, discussions about ongoing or future developments, ideas and suggestions regarding the ChibiOS projects are welcome. This forum is NOT for support.
BMWPower
Posts: 24
Joined: Mon Oct 24, 2016 10:27 pm
Has thanked: 1 time
Been thanked: 2 times

Re: Debugging Mailboxes ChibiOS

Postby BMWPower » Sun Sep 10, 2017 7:19 pm

I wanted to share my working code. You have to be sure no other "task" is locked or is getting an exception. The debugging is still a learning process for me, but its working now.

My code:

Code: Select all

/*
    ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio

    Licensed 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.

    Added new functionality based on the ChibiOS demo. Ben & Edwin alias DisruptiveNL

    Clean Code principles used:
    - Use Intention-Revealing Names

    An I2C file to address all I2C definitions and functionality at one place

    (c) 2017 DisruptiveNL
    For: NUCLEO-STMF411RE

   This c-file is representing the mailboxes. The readSensorX(chpi) functions are getting the values
   and post them in a struct into the mailbox msgs
   
   TODO: reading the respons from the ESP8266 (Serial) status 200!
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ch.h>
#include "hal.h"
#include "cffchipcap.h"
#include "chprintf.h"
#include "moistsensor.h"
#include "pwmds.h"
#include "esp8266.h"

/**
*    In *.h
   typedef struct
   {
      char *state;
      char *url;
   } DSMessage;
*
*/

//#define _DEBUG_

typedef enum {FILLED, NOTFILLED, SETUP,SETTINGUP,UNINITIALIZED,INITIALIZED,READY,SENDING,RESEND
           ,SENDINGHUM, SENDINGTEMP, SENDINGMOIST, SENDINGDC} esp_state_t;
          
bool state = false;

#define NUM_MSGS 16
#define _DEBUG_
#define _NOTSLEEP_

static esp_state_t esp_state = UNINITIALIZED;

static msg_t msgs_queue[NUM_MSGS];
static mailbox_t msgs;
static msg_t current_message;

static BaseSequentialStream *chpi;

/* USART config ESP8266 interface #1 */
static const SerialConfig esp8266uartcfg = {
    115200,
    0,
    0,
    0
};

/* The thread continuous which is fetching a message */
static THD_WORKING_AREA(waGETMESSAGEFROMMB, 512);
static THD_FUNCTION(GETMESSAGEFROMMB, arg)
{   
   (void)arg;
    chRegSetThreadName("GETMESSAGE");
      
   while(true) {

      //The ampersand & symbol should be read as "the address of..". The star *
      //symbol should be read as "the contents of the address...".
      /* Waiting for a message.*/
      if (chMBFetch(&msgs, (msg_t *)&current_message, TIME_INFINITE)== MSG_OK)
      {
            chprintf((BaseSequentialStream*)&SD6,"espmicro.setData('%s','%d')\r\n",((DSMessage *)current_message)->url,((DSMessage *)current_message)->state);   
      }
      else{
            chprintf((BaseSequentialStream*)&SD6,"print('Mailbox empty!')\r\n");
            chThdSleepMilliseconds(100);
      }
            
      chThdYield();
    }
}      

/* The thread continuous which is reading the sensor values and is posting a message in the mailbox */
static THD_WORKING_AREA(waPOSTMESSAGETOMBTEMP, 512);
static THD_FUNCTION(POSTMESSAGETOMBTEMP, arg)
{
   (void)arg;

    chRegSetThreadName("GETMESSAGEFROMSENSORTEMP");

   #ifndef _SLEEP_
      systime_t time = chVTGetSystemTimeX();
   #endif

    while(true) {
      
      #ifndef _SLEEP_
         time += S2ST(60);
      #endif
      
      /*reading sensors like PWM, I2C and ADC*/
      readSensor(chpi);

      // cffchipcap.c
      int32_t temp = getTemperatureValue();
      
      DSMessage dsmi = {};

      dsmi.state = temp;
      dsmi.url = TEMPURL;
         
      chMBPost(&msgs, (msg_t) &dsmi, TIME_INFINITE);
   
      #ifndef _SLEEP_
         chThdSleepUntil(time);
      #else
         chThdSleepSeconds(1);
      #endif
      
   }
}

/* The thread continuous which is reading the sensor values and is posting a message in the mailbox */

static THD_WORKING_AREA(waPOSTMESSAGETOMBHUM, 512);
static THD_FUNCTION(POSTMESSAGETOMBHUM, arg)
{
   (void)arg;
   
    chRegSetThreadName("GETMESSAGEFROMSENSORHUM");

   #ifndef _SLEEP_
      systime_t time = chVTGetSystemTimeX();
   #endif

    while(true) {
      
      #ifndef _SLEEP_
         time += S2ST(70);
      #endif
      
      //readSensor(chpi); //Only do this at the sensor who is read the most often... else locking problems..
      int32_t hum = getHumidityValue();
      
      DSMessage dsm = {};
      
      dsm.state = hum;
      dsm.url = HUMURL;
      
      chMBPost(&msgs, (msg_t) &dsm, TIME_INFINITE);
      
      #ifndef _SLEEP_
         chThdSleepUntil(time);
      #else
         chThdSleepSeconds(1);
      #endif            
   }
}

/* The thread continuous which is reading the sensor values and is posting a message in the mailbox */

static THD_WORKING_AREA(waPOSTMESSAGETOMBPWM, 512);
static THD_FUNCTION(POSTMESSAGETOMBPWM, arg)
{
   (void)arg;

    chRegSetThreadName("GETMESSAGEFROMSENSORPWM");

   #ifndef _SLEEP_
      systime_t time = chVTGetSystemTimeX();
   #endif

    while(true) {
      
      #ifndef _SLEEP_
         time += S2ST(80);
      #endif
      
      //readSensor(chpi);
      int32_t pwm = getDutycycleValue();
      
      DSMessage dsm = {};
      
      dsm.state = pwm;
      dsm.url = PWMURL;
      
      chMBPost(&msgs, (msg_t) &dsm, TIME_INFINITE);
      
      #ifndef _SLEEP_
         chThdSleepUntil(time);
      #else
         chThdSleepSeconds(1);
      #endif
      
      //Let the main thread kick the PWM
      setDPmwDs(pwm);
            
   }
}

/* The thread continuous which is reading the sensor values and is posting a message in the mailbox */

static THD_WORKING_AREA(waPOSTMESSAGETOMBMOIST, 512);
static THD_FUNCTION(POSTMESSAGETOMBMOIST, arg)
{
   (void)arg;

    chRegSetThreadName("GETMESSAGEFROMSENSORMOIST");

   #ifndef _SLEEP_
      systime_t time = chVTGetSystemTimeX();
   #endif
   
   int8_t counter = 0;

    while(true) {
      
      #ifndef _SLEEP_
         time += S2ST(90);
      #endif
      
      readMoistSensor(chpi);
      int32_t moist = getMoistValue();
      
      DSMessage dsm = {};
      
      dsm.state = moist;
      dsm.url = MOISTURL;
      
      /* So the ESP8266 does not get >3 sensor values the first time */
      if (counter==1)
      {
         chMBPost(&msgs, (msg_t) &dsm, TIME_INFINITE);
      }
      
      #ifndef _SLEEP_
         chThdSleepUntil(time);
      #else
         chThdSleepSeconds(1);
      #endif
      
      counter = 1;
            
   }
}

 ////////////////////////////////////////
 // ESP8266 UART Class Methods
 ////////////////////////////////////////
 void initESP8266(BaseSequentialStream *chp)
 {

   /* start USART */
    sdStart(&SD6, &esp8266uartcfg);
   chprintf(chp, "Started SD6 ESP8266\r\n");

   /* config GPIO on Nucleo */
    palSetPadMode(stm32F411TxPort6, stm32F411TxPin6, PAL_MODE_ALTERNATE(8));
    palSetPadMode(stm32F411RxPort6, stm32F411RxPin6, PAL_MODE_ALTERNATE(8));
    chprintf(chp, "Init Pins ESP8266\r\n");

   chThdSleepMilliseconds(500);

   /* Make BaseSequentialStream sort of global */
    chpi = chp;
    chprintf(chp, "Init ESP8266 over USART \r\n");

   /* Init mailboxes */
   chMBObjectInit(&msgs, msgs_queue, NUM_MSGS);

   /* Pre-filling the free buffers pool with the available buffers, the post
        will not stop because the mailbox is large enough.*/

   /* Init ESP8266 through USART */
   chprintf((BaseSequentialStream*)&SD6,"import network\n\r");
   chThdSleepMilliseconds(1000);
   chprintf((BaseSequentialStream*)&SD6,"import config\n\r");
   chThdSleepMilliseconds(1000);
   chprintf((BaseSequentialStream*)&SD6,"import micropython\n\r");
   chThdSleepMilliseconds(1000);
   chprintf((BaseSequentialStream*)&SD6,"import espmicro\n\r");
   chThdSleepMilliseconds(1000);
   chprintf((BaseSequentialStream*)&SD6,"espmicro.do_connect()\n\r");
   chThdSleepMilliseconds(1000);
   chprintf((BaseSequentialStream*)&SD6,"network.WLAN(network.STA_IF).isconnected()\n\r");
   chThdSleepMilliseconds(1000);
   chprintf(chp, "\n\r");
    chprintf(chp, "InitPool ESP8266 over USART \r\n");
    esp_state = SETUP;

   /* Start threads to run infinitive */
    chThdCreateStatic(waGETMESSAGEFROMMB, sizeof(waGETMESSAGEFROMMB), NORMALPRIO, GETMESSAGEFROMMB, NULL);
   chThdCreateStatic(waPOSTMESSAGETOMBTEMP, sizeof(waPOSTMESSAGETOMBTEMP), NORMALPRIO, POSTMESSAGETOMBTEMP, NULL);
   chThdCreateStatic(waPOSTMESSAGETOMBHUM, sizeof(waPOSTMESSAGETOMBHUM), NORMALPRIO, POSTMESSAGETOMBHUM, NULL);
   chThdCreateStatic(waPOSTMESSAGETOMBPWM, sizeof(waPOSTMESSAGETOMBPWM), NORMALPRIO, POSTMESSAGETOMBPWM, NULL);
   chThdCreateStatic(waPOSTMESSAGETOMBMOIST, sizeof(waPOSTMESSAGETOMBMOIST), NORMALPRIO, POSTMESSAGETOMBMOIST, NULL);

    chprintf(chp, "Functions ESP8266 over USART \r\n");
   chprintf(chpi, "ESP status GETMESSAGE |: %d", esp_state);
   chprintf(chpi, "\r\n");
 }



Return to “Development and Feedback”

Who is online

Users browsing this forum: No registered users and 10 guests