Skip to content

Commit

Permalink
Merge pull request #130 from RICCIARDI-Adrien/add_initial_can_stack_a…
Browse files Browse the repository at this point in the history
…nd_example

Add initial CAN stack and example
  • Loading branch information
jlbirccyn authored Sep 5, 2023
2 parents dcf4bab + 6452f7a commit 31966c9
Show file tree
Hide file tree
Showing 14 changed files with 792 additions and 0 deletions.
65 changes: 65 additions & 0 deletions com/ComStack_Types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* @file ComStack_Types.h
*
* @section desc File description
*
* This implementation is based on AUTOSAR CAN Driver R22-11, see
* https://www.autosar.org/fileadmin/standards/R22-11/CP/AUTOSAR_SWS_CommunicationStackTypes.pdf
*
* @section copyright Copyright
*
* Trampoline OS
*
* Trampoline is copyright (c) IRCCyN 2005+
* Trampoline is protected by the French intellectual property law.
*
* (C) BayLibre 2023
*
* This software is distributed under the Lesser GNU Public Licence
*
* @section infos File informations
*
* $Date$
* $Rev$
* $Author$
* $URL$
*/
#ifndef COM_STACK_TYPES_H
#define COM_STACK_TYPES_H

#include <tpl_os_types.h>

/**
* @typedef PduIdType
*
* Variables of this type serve as a unique identifier of a PDU within a
* software module or a set thereof, and also for interaction of two software
* modules where the PduId of the corresponding target module is being used for
* referencing.
*/
typedef uint8 PduIdType;

/**
* @typedef PduLengthType
*
* Variables of this type serve as length information of a PDU. The length
* information is provided in number of bytes.
*/
typedef uint32 PduLengthType;

/**
* @typedef PduInfoType
*
* Variables of this type shall be used to store the basic information about a
* PDU of any type, namely a pointer variable pointing to its SDU (payload), a
* pointer to Meta Data of the PDU, and the corresponding length of the SDU in
* bytes.
*/
typedef struct
{
uint8 *SduDataPtr;
uint8 *MetaDataPtr;
PduLengthType SduLength;
} PduInfoType;

#endif
3 changes: 3 additions & 0 deletions examples/posix/can_demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
can_demo/
can_demo_exe
*.py
26 changes: 26 additions & 0 deletions examples/posix/can_demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Trampoline CAN demo example

Have a look to ../README.md for more information about the POSIX target (using ViPER).

This example allows to test the Trampoline CAN stack on the development PC.

On Linux:
```
goil --target=posix/linux --templates=../../../goil/templates/ can_demo.oil
```

Then, the makefile is generated, and it will call goil again when the .oil file
is updated.
```
./make.py
```

Then, run the trampoline binary.
```
VIPER_PATH=../../../viper/ ./can_demo_exe
```

To quit, run the command below from another terminal.
```
killall -SIGINT can_demo_exe
```
79 changes: 79 additions & 0 deletions examples/posix/can_demo/can_demo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include <Can.h>
#include <CanIf.h>
#include <stdio.h>
#include <string.h>
#include <tpl_can_demo_driver.h>
#include <tpl_os.h>

int main(void)
{
// Statically list the CAN controllers to use in the application
static tpl_can_controller_t *can_controllers[] =
{
&can_demo_driver_controller_1,
&can_demo_driver_controller_2,
NULL
};
static Can_ConfigType can_config_type =
{
can_controllers
};
int ret;

printf("Initializing all requested controllers...\r\n");
ret = Can_Init(&can_config_type);
if (ret)
{
printf("[%s:%d] Error : Can_Init() failed (%d).\r\n", __func__, __LINE__, ret);
return -1;
}

printf("Setting first controller baud rate...\r\n");
ret = CanIf_SetBaudrate(0, CAN_BAUD_RATE_500_KBPS);
if (ret)
{
printf("[%s:%d] Error : CanIf_SetBaudrate() failed (%d).\r\n", __func__, __LINE__, ret);
return -1;
}

StartOS(OSDEFAULTAPPMODE);
return 0;
}

TASK(can_task)
{
Std_ReturnType ret;
uint8 payload[8];
Can_PduType can_pdu, *pointer_can_pdu;
PduInfoType pdu_info;
int i;

printf("Transmitting a CAN 2.0 frame with standard ID...\r\n");
can_pdu.id = 0x123 | TPL_CAN_ID_TYPE_STANDARD;
strcpy(payload, "Ciao !");
can_pdu.length = strlen(payload);
can_pdu.sdu = payload;
pdu_info.SduDataPtr = (uint8 *) &can_pdu;
pdu_info.SduLength = sizeof(can_pdu);
ret = CanIf_Transmit(0, &pdu_info);
if (ret)
printf("[%s:%d] Error : failed to transmit the frame (%d).\r\n", __func__, __LINE__, ret);
printf("Transmission succeeded.\r\n");

printf("Waiting for a CAN 2.0 frame with standard ID...\r\n");
ret = CanIf_ReadRxPduData(0, &pdu_info);
if (ret)
printf("No frame is available.\r\n");
else
{
printf("A frame has been received.\r\n");

pointer_can_pdu = (Can_PduType *) pdu_info.SduDataPtr;
printf("ID = 0x%X, length = %d, payload = ", pointer_can_pdu->id, pointer_can_pdu->length);
for (i = 0; i < pointer_can_pdu->length; i++)
printf("0x%02X ", pointer_can_pdu->sdu[i]);
printf("\r\n");
}

TerminateTask();
}
27 changes: 27 additions & 0 deletions examples/posix/can_demo/can_demo.oil
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
OIL_VERSION = "2.5";

CPU can_task {
OS config {
STATUS = EXTENDED;
BUILD = TRUE {
APP_SRC = "can_demo.c";
TRAMPOLINE_BASE_PATH = "../../..";
LDFLAGS = "-lrt -lpthread";
APP_NAME = "can_demo_exe";
LINKER = "gcc";
SYSTEM = PYTHON;
LIBRARY = can;
};
};

APPMODE stdAppmode {};

TASK can_task {
PRIORITY = 1;
AUTOSTART = TRUE {
APPMODE = stdAppmode;
};
ACTIVATION = 1;
SCHEDULE = FULL;
};
};
1 change: 1 addition & 0 deletions goil/templates/build/build_py.goilTemplate
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ end foreach
%
if with_ioc:
includeDirs += ["-I", "% !OS::BUILD_S::TRAMPOLINE_BASE_PATH %/ioc"]
includeDirs += ["-I", "% !OS::BUILD_S::TRAMPOLINE_BASE_PATH %/com"]
includeDirs += ["-I", "% !OS::BUILD_S::TRAMPOLINE_BASE_PATH %/os"]
includeDirs += ["-I", "% !OS::BUILD_S::TRAMPOLINE_BASE_PATH %/debug"]
includeDirs += ["-I", "% !PROJECT %"]
Expand Down
8 changes: 8 additions & 0 deletions goil/templates/config/posix/config.oil
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ IMPLEMENTATION posix {
STRING COMPILER = "gcc";
STRING ASSEMBLER = "gcc";
STRING LINKER = "gcc";
ENUM [
can
] LIBRARY[];
},
FALSE
] BUILD = FALSE;
Expand Down Expand Up @@ -62,5 +65,10 @@ CPU posix {
PATH = "../viper";
};

LIBRARY can {
PATH = "../net/can";
CFILE = "tpl_can_core.c";
CFILE = "../../machines/posix/tpl_can_demo_driver.c";
};
};

117 changes: 117 additions & 0 deletions machines/posix/tpl_can_demo_driver.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/**
* @file tpl_can_demo_driver.c
*
* @section desc File description
*
* See tpl_can_demo_driver.h for description.
*
* @section copyright Copyright
*
* Trampoline OS
*
* Trampoline is copyright (c) IRCCyN 2005+
* Trampoline is protected by the French intellectual property law.
*
* (C) BayLibre 2023
*
* This software is distributed under the Lesser GNU Public Licence
*
* @section infos File informations
*
* $Date$
* $Rev$
* $Author$
* $URL$
*/
#include <Can.h>
#include <stdio.h>
#include <string.h>
#include <tpl_can_demo_driver.h>

static int can_demo_driver_init(struct tpl_can_controller_t *ctrl, void *data);
static int can_demo_driver_set_baudrate(struct tpl_can_controller_t *ctrl, tpl_can_baud_rate_t baud_rate);
static Std_ReturnType can_demo_driver_transmit(struct tpl_can_controller_t *ctrl, const Can_PduType *pdu_info);
static Std_ReturnType can_demo_driver_receive(struct tpl_can_controller_t *ctrl, Can_PduType *pdu_info);
static int can_demo_driver_is_data_available(struct tpl_can_controller_t *ctrl);

tpl_can_controller_t can_demo_driver_controller_1 =
{
0x12341111,
can_demo_driver_init,
can_demo_driver_set_baudrate,
can_demo_driver_transmit,
can_demo_driver_receive,
can_demo_driver_is_data_available
};

tpl_can_controller_t can_demo_driver_controller_2 =
{
0x12342222,
can_demo_driver_init,
can_demo_driver_set_baudrate,
can_demo_driver_transmit,
can_demo_driver_receive,
can_demo_driver_is_data_available
};

static int can_demo_driver_init(struct tpl_can_controller_t *ctrl, void *data)
{
printf("[%s:%d] Initialized controller 0x%08X.\r\n", __func__, __LINE__, ctrl->base_address);
return 0;
}

static int can_demo_driver_set_baudrate(struct tpl_can_controller_t *ctrl, tpl_can_baud_rate_t baud_rate)
{
static uint32 baud_rate_lut[] =
{
// CAN_BAUD_RATE_50_KBPS
50000,
// CAN_BAUD_RATE_100_KBPS
100000,
// CAN_BAUD_RATE_125_KBPS
125000,
// CAN_BAUD_RATE_250_KBPS
250000,
// CAN_BAUD_RATE_500_KBPS
500000,
// CAN_BAUD_RATE_1_MBPS
1000000
};
uint32 bits_per_second;

if (baud_rate >= CAN_BAUD_RATE_COUNT)
{
printf("[%s:%d] Wrong baud rate code %d, aborting.\r\n", baud_rate);
return -1;
}
bits_per_second = baud_rate_lut[baud_rate];

printf("[%s:%d] Baud rate set to %u for controller 0x%08X.\r\n", __func__, __LINE__, bits_per_second, ctrl->base_address);
return 0;
}

static Std_ReturnType can_demo_driver_transmit(struct tpl_can_controller_t *ctrl, const Can_PduType *pdu_info)
{
uint32 i;

printf("[%s:%d] Transmission request for controller 0x%08X, CAN ID = 0x%X, flags = 0x%02X, payload length = %u, payload = ",
__func__, __LINE__, ctrl->base_address, pdu_info->id & ~TPL_CAN_ID_TYPE_MASK, pdu_info->length, pdu_info->id >> 30);
for (i = 0; i < pdu_info->length; i++)
printf("0x%02X ", pdu_info->sdu[i]);
printf("\r\n");

return 0;
}

static Std_ReturnType can_demo_driver_receive(struct tpl_can_controller_t *ctrl, Can_PduType *pdu_info)
{
pdu_info->id = 0x1ab; // Random value
strcpy(pdu_info->sdu, "Test");
pdu_info->length = strlen(pdu_info->sdu);
return 0;
}

static int can_demo_driver_is_data_available(struct tpl_can_controller_t *ctrl)
{
return 1;
}
37 changes: 37 additions & 0 deletions machines/posix/tpl_can_demo_driver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* @file tpl_can_demo_driver.h
*
* @section desc File description
*
* Exposes two dummy CAN controllers that implements all controller operations
* by displaying debug messages.
* The purpose of this driver is to test the CAN stack.
*
* @section copyright Copyright
*
* Trampoline OS
*
* Trampoline is copyright (c) IRCCyN 2005+
* Trampoline is protected by the French intellectual property law.
*
* (C) BayLibre 2023
*
* This software is distributed under the Lesser GNU Public Licence
*
* @section infos File informations
*
* $Date$
* $Rev$
* $Author$
* $URL$
*/
#ifndef TPL_CAN_DEMO_DRIVER_H
#define TPL_CAN_DEMO_DRIVER_H

#include <Can.h>

// All available controllers
extern tpl_can_controller_t can_demo_driver_controller_1;
extern tpl_can_controller_t can_demo_driver_controller_2;

#endif
Loading

0 comments on commit 31966c9

Please sign in to comment.