Added documentation for the implementation

pull/14688/head
Mohammed Mubeen 2021-07-06 20:12:12 +05:30
parent ff01046385
commit 65a72c29c8
3 changed files with 105 additions and 0 deletions

View File

@ -31,6 +31,53 @@
namespace mbed {
class RawCAN: public CAN {
public:
/** Creates an unlocked CAN interface connected to specific pins.
*
* @param rd read from transmitter
* @param td transmit to transmitter
*
* Example:
* @code
* #include "mbed.h"
*
*
* Ticker ticker;
* DigitalOut led1(LED1);
* DigitalOut led2(LED2);
* //The constructor takes in RX, and TX pin respectively.
* //These pins, for this example, are defined in mbed_app.json
* RawCAN can1(MBED_CONF_APP_CAN1_RD, MBED_CONF_APP_CAN1_TD);
* RawCAN can2(MBED_CONF_APP_CAN2_RD, MBED_CONF_APP_CAN2_TD);
*
* unsigned char counter = 0;
*
* void send() {
* if(can1.write(CANMessage(1337U, &counter, 1))) {
* printf("Message sent: %d\n", counter);
* counter++;
* }
* led1 = !led1;
* }
*
* int main() {
* ticker.attach(&send, 1);
* CANMessage msg;
* while(1) {
* if(can2.read(msg)) {
* printf("Message received: %d\n\n", msg.data[0]);
* led2 = !led2;
* }
* ThisThread::sleep_for(200);
* }
* }
*
* @endcode
*/
/* Note: The can apis are unlocked hence using this when multiple
* threads are accessing a single instance of CAN will lead to
* race conditions, can be used in single threaded CAN.
*/
using CAN::CAN;

View File

@ -470,6 +470,63 @@ For application that require optimized maximum performance, the recommendation i
The SPI DMA transfer support shall be implemented on a case-by-case based on below example
https://github.com/ABOSTM/mbed-os/tree/I2C_SPI_DMA_IMPLEMENTATION_FOR_STM32L4
### CAN receive interrupt problem due to mutex and resolution
In bxCAN and earlier versions the receive interrupt flags can be cleared only on performing a read operation in ST MCUs
But can_read() cannot be used in interrupt context as it is gaurded by lock operation and mbed does not allow locks in
interrupt context. Hence the Rx interrupt is disabled for a while and read is deferred to thread context, the interrupt is
enabled on a successful read.
As an other option RawCAN (with unlocked CAN apis) is also available and can be used directly, if only one thread is accessing
the CAN interface.
While using RxInterrupt with the CAN object the receive ISR callback registered should defer read to thread context.
A simple example is as shown below:
#include "mbed.h"
Ticker ticker;
Thread canReadThread;
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
CAN can1(PD_0 ,PD_1);
EventQueue queue(32 * EVENTS_EVENT_SIZE);
int counter = 0xABCD;
CANMessage msg;
void canRead(){
if(can1.read(msg)) {
if(msg.id==1100)
led2 = !led2;
if(msg.id==1102){
led3 = !led3;
}
}
}
void canISR(){
queue.call(canRead);
led3 = !led3;
}
int main() {
can1.frequency(100000);
can1.mode(CAN::Normal);
can1.attach(canISR, CAN::RxIrq);
canReadThread.start(callback(&queue, &EventQueue::dispatch_forever));
while(1) {
}
}
## Mbed OS Wiki pages

View File

@ -1187,6 +1187,7 @@ static void can_irq(CANName name, int id)
// In legacy can (bxCAN and earlier), reading is the only way to clear rx interrupt. But can_read has mutex locks
// since mutexes cannot be used in ISR context, rx interrupt is masked here to temporary disable it
// rx interrupts will be unamsked in read operation. reads must be deffered to thread context.
// refer to the CAN receive interrupt problem due to mutex and resolution section of README doc.
__HAL_CAN_DISABLE_IT(&CanHandle, CAN_IT_FMP0);
if ((tmp1 != 0) && tmp2) {