This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MODBUS F28335: Open-Source

Other Parts Discussed in Thread: CONTROLSUITE

Hello,

I work at CERTI (Brazil) and we're developing a implementation of MODBUS for F28335. We are providing it as open-source, so if any other developer here needs it the code is at my github: https://github.com/brunoluiz/28335ModbusSlave

It doesn't use interruptions because the project that we are using the MODBUS has a lot of critical interruptions, so it works with polling. But don't panic: it works very well (at least at my tests).

I'll be pleased if other devs tests the code too and inform me any issue at the code. And if possible, comment about the structure of the project/code. I used a modular aproach, but is my first big raw implementation of a protocol in C.

  • First of all thanks so much for providing this protocol it will save me a ton of time!!

    Couple questions:
    1.) What is timer0 used for and is it needed, because in my application I use timer0 for other things and wouldn't want to tie up that timer?
    2.) Is there a way to display the modbus packet so I can see if it is receiving/transmitting the packet I expect?
    3.) How could I change the holding and input registers to 16 bits?

    Also I think in ModbusSlave.c on line 62 you meant to include the defined value "SERIAL_PARITY" as opposed to just defining it there as ODD

    Again thanks so much!

    -Shane
  • One more question is it possible to have more than 4 holding registers  and input registers

  • 1) Timer0 is used to count the 3.5 char time. As the MODBUS documentation says, this time is like the "frame start". But you can go to "contrib/modbus/plataform/DSP2833x/Timer.c" and change the regs to Timer1 or Timer2 (just use "find and replace" tool)
    2) When I was running the tests I modified the last state to break after 10 iterations. Then I could saw the requests and responses, which I'd saved at an array.
    3) In ModbusDataMap you have to declare it as 16 bits int (for example) and then modify the "contrib/modbus/ModbusDataHandler.c" bitwise operations... It's a little painful, but if you do that, please, send it for me on github to other people use it. I hadn't implemented because I'd a very tight deadline, but if someone implement it and send for me as a pull request I will be thankful.
    4) You're right about the SERIAL_PARITY. Now I am not with the workspace configured here, if you want to fix it and send as a pull request at GitHub feel free (I'll accept the request)
    5) Yeah, you can have more than 4 registers. Just add more them at the ModbusDataMap (remove the dummy and add your variables). I just don't know the limit (I didn't tested it) =\
  • I have been using this library for a couple of weeks now and it is working pretty well, I have one issue that I can not resolve and was wondering if you could give some help.

    For the datahandler_readDigitalData, I'm having trouble reading just one value at a time.  If I read more than one it is fine but if I try to just read one it does not seem to give me the correct value of the input register.  I believe it is somewhere in this portion of the code but can't seem to pin point it.  Any help would be much appreciated.

    Thanks,

    // MODIFIABLE: specified address values
    	for (idx = 0; idx < numberOfBytes; idx++) {
    		Uint16 coilsNum = totalDataRequested - idx*8;
    		Uint16 padding = idx + firstDataAddress - reg16ReturnIdx;
    		Uint16 content = 0;
    		content = *(dataPtr + padding) >> (reg16ReturnIdx*8);
    
    		if(coilsNum >= 8) {
    			slave->dataResponse.content[slave->dataResponse.contentIdx++] = content & 0x00FF;
    		} else {
    			Uint16 mask;
    			mask = ~(0xFFFF << coilsNum);
    			slave->dataResponse.content[slave->dataResponse.contentIdx++] = content & mask;
    		}
    
    		if(reg16ReturnIdx == 0) reg16ReturnIdx = 1;
    		else reg16ReturnIdx = 0;
    	}

  • Sorry, I was on vacation and I am only saw this now. Could you post it as an issue at GitHub? There I can better manage it. But, so far that I remember, coils and digital inputs were very hard to implement but, anyway, I will check it out.

    If you find some solution before me, please send as a pull request at github (probably I will accept it) or post it here. It will help other devs in future projects (y).

  • Just an FYI I posted this on github as well.
  • Hi, I have been looking at your library to understand how it works. You mention that in order to have more than 4 holding registers, more can be added at the ModbusDataMap. I opened the ModbusDataMap.c file, but I do not see any dummy variable listed. All I see is the definition of various memory and I/O types being enabled or not. Could you please point exactly where in the script (or some other script in the library) can I make the necessary change. I think we could need as many as 10 registers.

    Another thing that I want to understand is the debug modes in ModbusSettings.h. This is what I found in the file:
    // Debug settings =========================================
    #define DEBUG_UTILS_PROFILING 0 // Include the necessary files to the linker!!
    #define DEBUG_LOG_ENABLED 0

    So what values can be given here for the debug modes? Also, what are these necessary files to be included to the linker, that you mention in the comment?

    Lastly, how can the addresses of the holding registers, input registers and receiving and transmitting data be set (or do I not have to touch that)?
  • You add the additional registers in the include folder in file ModbusDataMap.h

  • The holding and input registers are currently from 0 to 4 in the ModbusDataMap.h. To increase the number of registers, can I simply add dummy 5, dummy 6, dummy 7 etc? Also, if I add those, do I have to make any changes somewhere else in the library so that those registers are recognized?

    Also, where are these registers located? Can we change the addresses or that should not be done?

    Also, could you please tell me what DEBUG modes are available? Should I just leave it at default setting (No debug)?
  • you can simply add the dummy6, dummy7, etc but you can name them whatever you want.

    you do not need to make changes anywhere else

    the only way I know of to change the addresses is to change the ordering of them inside each register in the ModbusDataMap.h

    I'm not sure about the DEBUG modes.

  • Thanks for the replies Shane! I have two more questions.
    1. Does the character time depend on the baud rate, or does it depend on the peripheral clock frequency? I am asking this since the character time must be common for all parts on the Modbus RTU network. If it is a somewhat high baud rate, can I use a state machine to count the black characters, rather using a dedicated timer?
    2. Bruno says that it works through polling. How is this implemented? Does a state machine simply keep collecting data in the receive buffer and the CPU accesses this state machine time to time to see if the data is valid for processing and then processes it?
  • I think I will have to let Bruno answer as I'm not entirely sure

  • Hi Shane, I have one more question for you. I noticed that there are assembly files in

    28335ModbusSlave-master\contrib\DSP2833x\DSP2833x_common\source

    I also found some of those assembly files in other CCS projects as well. So I am wondering how the assembly files are created/included. Is a custom assembly file created by CCS when a project is compiled, or does CCS include some of the common assembly files in a project while compiling, based on what is needed?

    If my understanding is completely wrong, can someone please help me understand how assembly files are handled?

  • i don't believe the assembly files located there are necessary, I do not have them in my project.  

  • Thanks for the quick reply! So, if I want to include the implementation, all I need to do is include the header files given in
    28335ModbusSlave-master\contrib\modbus
    in my project and it will work? Nothing else (assembly file, linker file) is needed? I am trying to look at this as a closed box structure which can be just put in some project to work.
  • Attached is an example project, hope that helpsExampleProject.zip

  • Hi Shane, I looked at that example and I noticed that there are bunch of the same .asm files, such as DSP2833x_ADC_cal.asm. Is this file included by Code Composer studio when you compile the project? Where does CCS look for these files when compiling the project?

    One more request. The following is a simple LED blink project.

    https://dl.dropboxusercontent.com/u/64396346/My_Project.zip

    Could you please add the modbus salve implementation to this project and give me the updated project? This will help me understand exactly what you needed to put in the project for modbus slave to work. Thanks!

  • the .asm files are required for the certain perphials on the DSP to run properly, they are provided by TI in the controlSuite. I will not have time to modify your project. But all you would have to do is replace my main.c file with yours, then there you go
  • So if I am getting this right, the .asm were not added by you manually to the project? All you did was add the necessary header files and then .asm files and .c files like DSP2833x_Adc.c got included in your project by CCS? My LED blink project doesn't have any .asm files and I did not get any when I compiled the project. But if I include a suitable header file, then I will get those? Sorry if I am making this confusing.
  • You do have to manually add them.  Refer to this teaching rom for tutorials it helped me tremendously when I first started.

    e2e.ti.com/.../2038.c2000-teaching-rom

  • Ok, I will see the tutorials.
  • Hello,

    I have two questions:
    1. Is this modbus implementation for the RTU or TCP?
    2. Is this code works as slave only, master only or slave/master?

    Regards,
  • it is RTU

    and the code is for slave only

  • What if we want to add master behaviour? Do you think the software structure is suitable for that? Or do you suggest to look for other modbus implementations?
  • I believe Bruno author of this library has a modbus master library as well, but i'm not sure of the completeness of that