IoT app with DAVE4

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User16514
Level 1
Level 1
Hello,

an IoT Task based on the XMC4500 Relax Kit should be implemented using the unique component support in DAVE4. Currently, I try to find out what was wrong with my approach since it did not succeed after a couple of days.

A longer time ago the 'lwip' project was used as a basis for implementing an IoT client with PWM and ADC using a leightweight proprietary communication protocol. The entry point to own code was established after analyzing a web request for the GET Keyword and then branching to either a usual web Server behaviour or to controlling/monitoring the IoT part. This works fine for a longer time already.

The additional Task was to save measurement data on an SD card with a common exFAT file system. The 'XMC4500 webserver' has been used as a template for the task.

The following results have been accomplished so far:

1) the SD mode used in the webserver project did not work on the XMC4500 Relax Kit hardware that was purchased 2018

2) the SPI mode for the SDMMC provided access to the SD card however the exFAT file system was not acknowledged

3) the exFAT and the LFN support could not be added in the DAVE4 components but had to be adjusted every time after a source generation in the appropriate .c file

4) the FATFS module could not be added to the existing project derived from the 'lwip' project, possibly because of RTOS configuration problems

5) the chosen approach was to use the DAVE4 LWIP and FATFS components as a basis

6) the FATFS component succeeded after above mentioned modifications for the exFAT file System.

7) the application specific code from the 'loT' Project does not work with the LWIP component (Network functionality is not working)

😎 some initial problems could be solved by adjusting the RTOS thread settings (what was not obvious and difficult to find)

Now I am looking for a way to get the IoT application working with SDMMC support finally.

Thanks for any suggestions how to proceed.

Eckhard
0 Likes
1 Reply
User16514
Level 1
Level 1
The problems could be solved by analyzing the code in the http_server components and by implementing own application in a similar way.
Since the objective was to generate an app with 'web server/terminal/exFAT' support using DAVE4 Apps and as less as possible own code, the resulting project can serve as a base for more complex applications.

Therefore, it might be of interest also to others:

- The IoTappXMC4500 operates a web server at port 80. The response of any GET is always "Welcome to the IoTappXMC4500 microcontroller"
- a terminal can connect to same port, e.g. PuTTY, and the following commands are available:
> LED2 1 -> LED2 will be switched ON and a log entry will be added to a 'IoTapp.log' file on the SD card
> LED2 0 -> LED2 will be switched OFF and a log entry will be added
> SD -> some last log entries will be returned
> exit -> close connection

A project with above functionality can be created in DAVE4 by adding appropriate components, making adjustments to files and by setting sufficient resources for threads.
The few code lines to be added for the IoTapp functionality go to a separate file.

The project is available as an export file of 16 MByte. I am not sure whether that amount of data is allowed to be attached to a posting, however it can be sent on demand.

Please follow the following instructions for reproducing the project step-by-step:


DAVE [4.3.2]:
- create new DAVE CE project

ETH_LWIP:
- add ETH_LWIP [4.1.6]
- enable RTOS
- adjust MAC, IP, Gateway
- enable DNS, set DNS server
- pins
CRS_DV - P15.9
MDC - P2.7
MDIO - P2.0
RMII_CLK - P15.8
RXD0 - P2.2
RXD1 - P2.3
RXER - P2.4
TXD0 - P2.8
TXD1 - P2.9
TXEN - P2.5

CMSIS_RTOS_RTX:
- set concurrent user threads: 7
- set thread stack size: 300
- set threads with user stack size: 5
- set total user stack size: 4000

FATFS:
- add FATFS [4.0.18]
- set Use RTOS
- enable MKFS function

SDMMC_BLOCK:
- enable DMA operation in SPI mode
- pins
CLK - P3.6
Slave - P4.1
MOSI - P3.5
MISO - P4.0

main.c:
- replace application while(1U) loop by
osKernelStart();

test ping:
- generate code
- build active project
- run app
-> make sure that ping is working against set IP address

LED1:
- add threads in main.c for blinking LED1

#define LED1_PIN P1_1
void led1_task(void const *args)
{
while(1)
{
XMC_GPIO_ToggleOutput(LED1_PIN);
osDelay(500);
}
}
osThreadDef(led1_task, osPriorityNormal, 1, 0);

void main_task(void const *args)
{
XMC_GPIO_SetMode(LED1_PIN, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);

osThreadCreate(osThread(led1_task), NULL);
}
osThreadDef(main_task, osPriorityNormal, 1, 0);

- add before osKernelStart():

osKernelInitialize();
osThreadCreate(osThread(main_task), NULL);

- build and run app
-> make sure that LED1 is blinking

exFAT:
- modify Dave/Generated/FATFS/ff_Src/ffconf.h
- repeat in Dave/Model/APPS/FATFS/v4_0_18/Templates/ff_Src/ffconf.h
line 60 -> #include "stdlib.h"
line 120 -> #define FF_CODE_PAGE 850
line 157 -> #define FF_USE_LFN 3
line 284 -> #define FF_FS_EXFAT 1
- fix in Dave/Generated/FATFS/ff_Src/syscall.c
- repeat in Dave/Model/APPS/FATFS/v4_0_18/Templates/ff_Src/syscall.c
line 132 -> #if FF_USE_LFN == 3 /* LFN with a working buffer on the heap */
- add to Dave/Generated/FATFS/ff_Src a 'unicode.c' file (find one in the Internet)

IoTapp:
- add to main.c
#include "IoTapp.h"
- add in main.c to main_task
runIoTapp();
- create file "IoTapp.h" in the project folder

/* demo of a basic IoTapp
* - open a http server at port 80
* - serve http requests from a web browser
* - serve the following commands e.g. in a PuTTY session:
* > LED2 1 -> switch LED2 ON, write a log message
* > LED2 0 -> switch LED2 OFF, write a log message
* > SD -> return last lines from IoTapp.log file
*/
void runIoTapp();

#define LED2_PIN P1_0

- create file "IoTapp.c" in the project folder

#include
#include "IoTapp.h"

/* static web responses */
const static char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";
const static char http_html_default[] = "Congrats!

Welcome to the IoTappXMC4500 microcontroller!

";
/* static IoT terminal headline */
#define http_iot_headline "IoTappXMC4500\r\n> "

static FATFS g_fatfs; /* File system object */
static FIL g_file1; /* File object */

/* web server thread function */
static void iot_server_netconn_thread(void *arg);

/** enty point to IoTapp functionality */
#define IOT_THREAD_STACKSIZE 1200
void runIoTapp()
{
/* start a web server */
sys_thread_new("iot_server_netconn", iot_server_netconn_thread, NULL, IOT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
}

/** write to SD card */
static void
writeData(const char* Info, char* response, int length)
{
do
{
/* mount file system */
if(FR_OK != f_mount(&g_fatfs, "", 0))
break;

/* file open */
if(FR_OK != f_open(&g_file1, "IoTapp.log", FA_OPEN_ALWAYS | FA_WRITE))
break;

/* move to end of the file to append data */
if(FR_OK != f_lseek(&g_file1, f_size(&g_file1)))
break;

/* write message into file */
UINT bw = 0; /* Bytes written */
if(FR_OK != f_write(&g_file1, Info, strlen(Info), &bw))
break;

/* close file */
if(FR_OK != f_close(&g_file1))
break;

/* unmount file system */
if(FR_OK != f_mount(NULL, "", 0))
break;

} while (false);
}

/** IoT LED request */
#define LED2ON ": LED2 ON\r\n"
#define LED2OFF ": LED2 OFF\r\n"
static void
iot_led2_request(const char* cmd, char* response, int length)
{
/* clear response */
strcpy(response, "");

/* evaluate params */
if((strlen(cmd) < 6) || (length < strlen(LED2OFF)+1))
return;

/* process command */
if(cmd[5] == '0'){
XMC_GPIO_SetOutputLow(LED2_PIN);
strcpy(response, LED2OFF);
writeData(LED2OFF,response,length);
}else if(cmd[5] == '1'){
XMC_GPIO_SetOutputHigh(LED2_PIN);
strcpy(response, LED2ON);
writeData(LED2ON,response,length);
}
}

/** IoT SD request */
static void
iot_sd_request(const char* cmd, char* response, int length)
{
/* evaluate params */
if(strcmp(cmd,"SD") != 0)
return;

do
{
/* mount file system */
if(FR_OK != f_mount(&g_fatfs, "", 0))
break;

/* open file */
if(FR_OK != f_open(&g_file1, "IoTapp.log", FA_OPEN_ALWAYS | FA_READ))
break;

/* move to one buffer length before end of file */
int pos = f_size(&g_file1) - length + 1;
if(FR_OK != f_lseek(&g_file1, pos >= 0 ? pos : 0))
break;

/* read data from file */
UINT br = 0; /* Bytes read */
if(FR_OK != f_read(&g_file1, response, length-1, &br))
break;

/* close file */
if(FR_OK != f_close(&g_file1))
break;

/* unmount file system */
if(FR_OK != f_mount(NULL, "", 0))
break;

} while (false);
}

/** Serve IoT request */
static void
iot_request_serve(struct netconn *conn)
{
...text had to be shortened to 10000 chars...
}

- build project
text data bss dec hex filename
105084 708 52988 158780 26c3c IoTappXMC4500.elf

- insert a SD card
- start IoTapp
- test with a web browser -> "Welcome to the IoTappXMC4500 microcontroller!"
- test with a terminal, e.g. PuTTY
> LED2 1 -> switch LED2 ON, write a log message
> LED2 0 -> switch LED2 OFF, write a log message
> SD -> return last lines from IoTapp.log file
> exit -> close connection
0 Likes