A data collector based on STM32F107 was designed to collect and process various types of data (serial port, CAN port) and upload it wirelessly via a GPRS module. The CAN device driver was developed in detail, and the serial port data from the GPRS module was used for uploading and downloading. Finally, some issues encountered during the use of threads were discussed.
First, functional analysis
The system's functionality is shown in Figure 1, which is not overly complex. Due to the large amount of data reported by the lower-level sensor modules, the content of the processing program is quite extensive.
Second, writing the CAN driver
To modularly handle the active reporting data from the sensors, the CAN device no longer uses interrupt processing but instead utilizes the RTT device framework to rewrite the driver. Studying the CAN bus transceiver equipment within RTT:
It was found that only the framework existed, with no actual content. The approach was similar to writing a candevice like a serial port.
Studying the serial port driver in use:
This involved reading code. After understanding the framework, a driver similar to Linux was written.
Once all the programs were written, the general device operation functions could be used to operate the CAN. In the main program, the device was first initialized, and then registered.
Third, achieving serial data processing in device mode
The GPRS module is primarily used to receive serial data. First, a gprswatch process was created to monitor the serial port for incoming data.
In the monitoring GPRS serial port thread, after receiving the serial port data, it is received, analyzed, and the network status is set.
The monitoring and operation of the corresponding GPRS module is completed elsewhere in the program. A device operation function is also written for the GPRS module read and write operations, mainly using the previously written gprswatch thread.
So far, the basic operation of the GPRS module has been realized.
Fourth, experiences during the debugging process
1. Process initialization and memory allocation
In the RTT project, the int rt_application_init(void) function provides a basic usage, dynamically creating threads with rt_thread_create and allocating memory. During programming, due to limited memory, it was necessary to divide the allocated memory. The manual recommended using commands to check the memory usage of the thread during runtime, and then allocating memory based on experience. However, this led to many errors during debugging. Later, after consulting the manual and copying an example, I modified the program to create statically allocated threads using rt_thread_init, and the above errors no longer occurred.
2. Using Finsh
Finsh was widely used during the debugging process, greatly facilitating the debugging process.
According to the instructions in the user manual, any function that can be exported to Finsh should be written if it is not running in the program.
In the serial console, it was convenient to debug the GPRS-related functions, and the above functions needed to be run in the main program.
3. Format of the RTT routine
The RTT-based STM32F107 platform routines were written and posted on GitHub:
https://github.com/sundm75/STM32F107Board-rttproject
Each application in the example has a corresponding test**** file. In this file, all used Finsh operations are controlled through the serial port.
- End -
Our Wind Power Lighting Pole, Solar Street Lights Pole are made from quality sheet through bending,
forming, automatic welding and hot galvanization. We can reach one-run
machining length of 14m and can bend sheet of thickness up to 45mm. We
adopt advanced welding procedures, automatically weld main joints and
reach rank-II welding quality.
We have supplied our Wind Power Lighting Pole,Solar Street Lights Pole to Australia, Columbia, England, Kuwait, Iraq, Philippines, Pakistan and etc.
Wind Power Pole, Solar Lighting Pole, Solar Street Lights Pole, Wind and Solar Lighting Poles JIANGSU XINJINLEI STEEL INDUSTRY CO.,LTD , https://www.steel-pole.com
Sun Dongmei: Ph.D. and Associate Professor, School of Automation and Electrical Engineering, Nanjing University of Technology
void gprswatch(void)
{
rt_thread_t thread;
thread = rt_thread_find("gprswatch");
if (thread != RT_NULL)
rt_thread_delete(thread);
thread = rt_thread_create("gprswatch", gprswatch_entry, RT_NULL, 0x1000, 0x12, 200);
if (thread != RT_NULL)
rt_thread_startup(thread);
}
/* Monitoring GPRS serial thread entry */
void gprswatch_entry(void *parameter)
{
rt_err_t result = RT_EOK;
rt_uint32_t event;
unsigned char gprs_rx_buffer[GPRS_RX_LEN] = {0x00};
while (1)
{
result = rt_event_recv(&rev_event, REV_MASK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &event);
if (result == RT_EOK)
{
if (event & REV_DATA)
{
rt_memset(gprs_rx_buffer, 0x00, sizeof(gprs_rx_buffer));
rt_thread_delay(RT_TICK_PER_SECOND / 10);
rt_device_read(gprs_device, 0, gprs_rx_buffer, GPRS_RX_LEN);
rt_kprintf(gprs_rx_buffer);
if (rt_strstr((char const *)gprs_rx_buffer, "MYURCCLOSE: 0"))
{
net_status = CONNECT_ERROR;
rt_kprintf("The network is broken.\n");
}
else if (rt_strstr((char const *)gprs_rx_buffer, "Call Ready"))
{
net_status = CONNECT_NULL;
rt_kprintf("The module is restarted.\n");
}
// Additional conditions for other statuses...
}
if (event & REV_STOPWATCH)
return;
}
}
}
rt_bool_t gprs_send_data_package(unsigned char *cmd, char *ack, rt_uint32_t waittime, rt_uint8_t retrytime, rt_uint32_t len)
{
rt_bool_t res = RT_FALSE;
rt_err_t result = RT_EOK;
rt_uint32_t event;
unsigned char gprs_rx_buffer[GPRS_RX_LEN] = {0x00};
rt_thread_t thread;
thread = rt_thread_find("gprswatch");
if (thread != RT_NULL)
rt_thread_delete(thread);
do
{
rt_device_write(gprs_device, 0, cmd, len);
result = rt_event_recv(&rev_event, REV_MASK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, waittime * RT_TICK_PER_SECOND, &event);
if (result == RT_EOK)
{
if (event & REV_DATA)
{
rt_memset(gprs_rx_buffer, 0x00, sizeof(gprs_rx_buffer));
rt_thread_delay(RT_TICK_PER_SECOND / 2);
rt_device_read(gprs_device, 0, gprs_rx_buffer, GPRS_RX_LEN);
rt_kprintf(gprs_rx_buffer);
// Additional parsing logic...
}
}
retrytime--;
} while ((!res) && (retrytime >= 1));
gprswatch();
return res;
}
Author
August 15, 2025