Hello!
What seems odd to me about the chMBPost function is that it accepts an outgoing message parameter as a msg_t, which comes to be a simple int32_t. Any way to pass an array or struct between threads, using a mailbox?
Mailbox message
Re: Mailbox message
You can also use it as a pointer, and pass an array or structure by reference (I think there are other threads covering this)
Obviously its then up to you to manage the referenced memory block as required
Obviously its then up to you to manage the referenced memory block as required
Re: Mailbox message
You might want to look at post:
http://forum.chibios.org/phpbb/viewtopic.php?f=2&t=2980
It shows a small function that allows creating a buffer pool, allocating buffers pointers that you can pass in mailboxes, then freeing the buffer back to the pool.
-John
http://forum.chibios.org/phpbb/viewtopic.php?f=2&t=2980
It shows a small function that allows creating a buffer pool, allocating buffers pointers that you can pass in mailboxes, then freeing the buffer back to the pool.
-John
Re: Mailbox message
Thanks, now it's clear.
Not to create another topic, I'll ask here. The code:
The adcCapture_cb callback never runs. When I run blocking adcConvert, it seems to work fine. What could be wrong?
Not to create another topic, I'll ask here. The code:
Code: Select all
#include "ch.h"
#include "hal.h"
#include "test.h"
#include "usbcfg.h"
#include <string.h>
SerialUSBDriver SDU1;
static void adcCapture_cb(ADCDriver *adcp, adcsample_t *buffer, size_t n);
static uint32_t MBBuf1[4], MBBuf2[4], MBBuf3[4];
static adcsample_t ADCBuf[3];
MAILBOX_DECL(TCTempMB, MBBuf1, sizeof(MBBuf1));
const ADCConversionGroup adg = { true, // circular
3, // num_channels
adcCapture_cb, // end_cb
NULL, // error_cb
ADC_CFGR1_RES_10BIT, // cfgr1
0, // tr
ADC_SMPR_SMP_239P5, // smpr
// chselr
(1U << 0U) | // ADC_IN0 - TEMP_SNS
(1U << 1U) | // ADC_IN1 - VBAT
(1U << 13U) // ADC_IN13 - HEATER_CUR
};
static void adcCapture_cb(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
(void) n;
(void) adcp;
chSysLockFromISR();
chMBPostI(&TCTempMB, 0xDEADFACE); // Placeholder
chSysUnlockFromISR();
}
THD_WORKING_AREA(waControlLoop, 128);
THD_FUNCTION(thdControlLoop, arg) {
(void) arg;
uint32_t v;
BaseAsynchronousChannel *stream = (BaseAsynchronousChannel *) arg;
adcStartConversion(&ADCD1, &adg, ADCBuf, 1);
while( true ) {
chMBFetch(&TCTempMB, (msg_t *) &v, TIME_INFINITE);
chnWrite(stream, (uint8_t *) &v, sizeof(v));
}
}
int main(void) {
halInit();
chSysInit();
usbDisconnectBus(serusbcfg.usbp);
chThdSleepMilliseconds(1000);
usbStart(serusbcfg.usbp, &usbcfg);
usbConnectBus(serusbcfg.usbp);
sduObjectInit(&SDU1);
sduStart(&SDU1, &serusbcfg);
adcStart(&ADCD1, NULL);
chThdSleepMilliseconds(500);
chThdCreateStatic(waControlLoop, sizeof(waControlLoop), NORMALPRIO, thdControlLoop, &SDU1);
while (true) {
chThdSleepMilliseconds(500);
}
}
The adcCapture_cb callback never runs. When I run blocking adcConvert, it seems to work fine. What could be wrong?
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Mailbox message
Hi,
Try compiling using -O0, then enable debug options in chconf.h (assertions, checks, state checker) and place a breakpoint into the callback.
Giovanni
Try compiling using -O0, then enable debug options in chconf.h (assertions, checks, state checker) and place a breakpoint into the callback.
Giovanni
Re: Mailbox message
Ok, here is what I have found.
The callback fires perfectly, except I had to enable STM32 CONTinuous ADC mode so it would restart each round:
Now the callback code and the single thread running together:
When it reaches the chThdSleepMilliseconds(500);, the unhandled exception occurs. After stepping the code, I've found that it happens on the chSysSwitch(currp, otp) invocation from within chschd.c. Any idea?
Also, if I remove chThdSleepMilliseconds(500), no exception happens, but when connecting through terminal it hangs deadly. Might that be because of ADC interrupt firing too fast and blocking USB request callbacks?
The callback fires perfectly, except I had to enable STM32 CONTinuous ADC mode so it would restart each round:
ADC_CFGR1_RES_10BIT | (1U << 13U), // cfgr1 CONT=1
Now the callback code and the single thread running together:
Code: Select all
static void adcCapture_cb(ADCDriver *adcp, adcsample_t *buffer, size_t n) {
(void) n;
(void) adcp;
chSysLockFromISR();
if(chMBGetFreeCountI(&TCTempMB) != 0) {
chMBPostI(&TCTempMB, buffer[0]);
}
chSysUnlockFromISR();
}
THD_WORKING_AREA(waControlLoop, 128);
THD_FUNCTION(thdControlLoop, arg) {
(void) arg;
uint32_t v1;
BaseAsynchronousChannel *stream = (BaseAsynchronousChannel *) arg;
adcStartConversion(&ADCD1, &adg, ADCBuf, 1);
while ( true ) {
chMBFetch(&TCTempMB, (msg_t *) &v1, TIME_INFINITE);
chnWrite(stream, (uint8_t * ) &v1, sizeof(v1));
chThdSleepMilliseconds(500);
}
When it reaches the chThdSleepMilliseconds(500);, the unhandled exception occurs. After stepping the code, I've found that it happens on the chSysSwitch(currp, otp) invocation from within chschd.c. Any idea?
Also, if I remove chThdSleepMilliseconds(500), no exception happens, but when connecting through terminal it hangs deadly. Might that be because of ADC interrupt firing too fast and blocking USB request callbacks?
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: Mailbox message
It is possible, the ADC is a very fast peripheral so continuous mode must be used carefully. You may increase sample time or use HW triggering. You may also call adcConvert() directly from the thread, depending on what you are trying to do.
About chMBPostI(), you don't need to check if there is space beforehand, in that case the function simply fails.
Also check if you are hitting a stack overflow issue.
Giovanni
About chMBPostI(), you don't need to check if there is space beforehand, in that case the function simply fails.
Also check if you are hitting a stack overflow issue.
Giovanni
Re: Mailbox message
Thank you, Giovanni. It finally explains why usb works fine when I remove code within the callback.