You are here
Home > embedded >

Modbus Master Stack On ATSAME54 With RTOS

In previous post we discussed about how to port modbus slave stack on ATSAME54. This post we will discuss on how to port modbus master stack on SAME microcontroller. You can download example freemodbus master stack for reference from FreeModbus. We have referred the ‘AT91SAM7X_FREETROS’ example project. You can follow the steps from previous post for creating directory of project files. Instead of modbus slave stack, add modbus master stack. In addition, We are using FreeRTOS in our project. So In top level directory we have added FreeRTOS V9.0.0 . Please refer to modifications in port specific files described in previous post.

So lets begin with issues while port modbus master stack on SAME, Without an operating systems there are normally no queues available. In case of modbus stack without using RTOS, the queue sending and receiving functions are implemented using a static variable which is set to TRUE when an event is posted. The receive function checks the variable and if TRUE returns the previously stored event. But in case of an RTOS the functions should use a real event queue. We Changed the function xMBPortEventPost() to post an event to a queue. This function will be called from an ISR so we have used xMBPortEventPostFromISR() API for that. This is the interrupt safe version of xMBPortEventPost() provided in FreeRTOS.

We changd the function xMBPortEventGet( ) to retrieve an event from that queue . The function should block until an event has been posted to the queue.

Like this we are calling xQueueCreateStatic() API from vQueueCreate and vQueueDelete() API from vMBPEventDelete .

Next step is to define the functions vMBPEnterCritical( ) and vMBPExitCritical( ) in file portother.c. A switch to another task cannot occur between the calls to vMBPEnterCritical and vMBPExitCritical . Only interrupts whose logical priority is above the value assigned to the configMAX_SYSCALL_INTERRUPT_PRIORITY constant can execute in critical section and interrupts are not permitted to call FreeRTOS API functions. In FreeRTOS there are API’s portENTER_CRITICAL() and portEXIT_CRITICAL() which we have used respectively in above two functions.

Note that if we are calling portENTER_CRITICAL() and portEXIT_CRITICAL() functions from ISR, the following assertion will get fail: configASSERT((portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK) == 0);

If you are also stuck here, means you are calling these APIs from ISR. In FreeRTOS there are interrupt safe APIs which can be used inside ISR. So here in this case we found following two interrupt safe versions for above functions:

portSET_INTERRUPT_MASK_FROM_ISR() and portCLEAR_INTERRUPT_MASK_FROM_ISR()

Use thses APIs where the function is called from ISR:

In main function, we created two tasks using xTaskCreateStatic() API from FreeRTOS , one is application task and another is for modbus task .

TESTING ON SIMULATOR:

We have now created the modbus master workpace. For testing it, we have to run the modbus slave program on PC side. We are developing the stack on linux system. For this system we found out the Diagslave Modbus Slave Simulator . Install it in your system then execute ‘linux_x86-64/diagslave -h’ It will show the options you can configure. We executed simulator by giving the following command:

After running modbus master program, the simulator showing this output:

Happy to help you during your port modbus master stack on SAME controllers.

Top
%d bloggers like this: