C++ and MATLAB Simulink tips for HWIL simulation software engineers
Friday, December 29, 2023
Windows batch file to run an exe and check its result
Thursday, December 28, 2023
The unbearable lightness of C
static void mdlInitializeConditions(SimStruct *S) { real_T *states = ssGetRealDiscStates(S); for (int i=0; i < 48; i++) { *(states + i) = 0; } }
Wednesday, December 13, 2023
Downloading DTED from the internet
Monday, December 11, 2023
Avoiding catastrophic cancellation
Monday, December 4, 2023
Sharing files between Windows and Ubuntu virtual machine
I have a Windows 10 PC with Ubuntu 22.04 installed as a VirtualBox virtual machine. There are other ways to share files between Windows and Ubuntu, but the following is the most general way I know:
- On Windows, share a folder (e.g. "temp") with your own windows user name.
- Find the IP address of VirtualBox ethernet adapter:
- On Ubuntu make sure you can ping that IP address.
- Open a new Files window, at the bottom left, click on other locations. Then, at the bottom enter smb://<VirtualbBox ethernet adapter IP address>/<Windows folder name>
- After clicking Connect button, you should see the temp folder:
Installing Eclipse CDT and build-essentials to offline Ubuntu
- Download Linux version of Eclipse C++, copy to offline Ubuntu and extract. You can directly run eclipse without any further installation, but you need to finish the following steps to build a C++ project.
- On your Windows PC that is connected to the internet, install a virtualizer like VirtualBox and install Ubuntu Desktop 22.04 as virtual machine.
- Enable Windows - Ubuntu file sharing.
- Use the following shell script to download build_essentials on your online PCs Ubuntu virtual machine and its dependencies. You can copy these downloads to your offline Ubuntu and install them following the steps written as comments down below:
Friday, November 3, 2023
Handling left over carriage return
Simulink signal
- Open Simulink model
- Open Configuration Parameter window, go to Code Generation
- System target file: ert.tlc (Embedded Coder)
- Language: C
- In Simulink APPS menu, click on Embedded Coder, A C CODE tabs appears to the right of APPS menu
- Find the signal line you want the generate code for and double click on it, give it a name, e.g. "mySignal"
- Single click on signal line, a pop up will appear, click on the left-most item, "Add selected signals to code mappings"
- Under C CODE tab, click on Code Interface and then click Default Code Mappings
- A Code Mappings panel will appear at the bottom of model
- Click on right most tab, Signals/States
- Under Signals, find mySignal
- Click to the right of mySignal (Store Class column), change Auto to Model Default.
- Generate code by pressing ctrl + b
- If your model name was MyModel, the generated code will have a file called MyModel_ert_rtw/MyModel.h containing the data structure MyModel_B which has mySignal as a field that you can access from your own C/C++ code.
- If your code is C++, dont forget to use include in C wrapper: extern "C" {#include "MyModel_ert_rtw/MyModel.h"}
Friday, October 13, 2023
Sanity checks
Wednesday, August 16, 2023
Compile s-function with C++17
Thursday, March 16, 2023
Effective usage of locks in multi-threading
function saveData(newData) { addToBuffer(newData) saveBufferToFile() }To make this function thread safe, you might haphazardly lock at the beginning and unlock at the end of function:
function saveData(newData) { lock() addToBuffer(newData) saveBufferToFile() unlock() }Since saving buffer to file on disk takes a lot of time, another thread that wants to add to the buffer has to wait for file operation to finish. To decrease wait time of other locks that call saveData function, lock before adding to buffer and unlock before saving to file:
function saveData(newData) { lock() addToBuffer(newData) unlock() saveBufferToFile() }
Thursday, January 12, 2023
C++: Using non-standard data types
When you use non-standard data types like enum, bool, double, long double, it might become a problem if you are sending data to another platform, e.g. sending from x86 to ARM, or even when sending from Windows to Linux. For example, long double is 8 bytes in MSVC but 16 bytes in GCC. These size differences will result in errors when casting the received bytes to data. Always know non-standard data type lengths of the platform that you are communicating with.
Wednesday, January 11, 2023
Monday, January 9, 2023
C: char pointer vs array
In C, the difference between a char pointer and char array becomes clear when you want to do assignment:
#include<stdio.h> #include<string.h> //for strcpy int main() { char s[][10] = {"aaa", "bbb", "ccc"}; //char* s[] = {"aaa", "bbb", "ccc"}; //same as above char* t1 = s[1]; char t2[10]; strcpy(t2, s[1]); //t2 = s[1];// error: assignment to expression with array type printf("s[1] = %s\n", s[1]); printf("t1 = %s\n", t1); printf("t2 = %s\n", t2); return 0; }
s[1] is a char pointer. You can assign a char pointer to another char pointer but you cannot assign a char array to char pointer, you have to use strcpy.
Another interesting difference:
char a[] = "string1"; char *p1 = a; char *p2 = "string2"; a[0] = 'z'; printf("a[0] = %c\n", a[0]); p1[0] = 'k'; //works fine, changes a[0] printf("a[0] = %c\n", a[0]); p2[0] = 'm'; //results in segmentation fault printf("p2[0] = %c\n", p2[0]);