Author Sun Dongmei: Ph.D. and Associate Professor, School of Automation and Electrical Engineering, Nanjing University of Technology

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.


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);
}
    

In the monitoring GPRS serial port thread, after receiving the serial port data, it is received, analyzed, and the network status is set.


/* 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;
        }
    }
}
    

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.


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;
}
    

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 -

New Energy Structure

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