From SubfireWiki
Setting up the skeleton code for the test
- Open the csiproject.glade file using the glade-2 program
- Move the loop test buttons, all test buttons and horizontal separators down (in that order) by selecting them and using the "Packing" tab in the Properties window. Simply increase the "Cell Y" property by one.
- Now just add a new button and progress bar in the blank spots that have been created.
- Try to follow the naming established convention.
- For example, if you are adding a LIN card test, set these properties:
- For the primary Button:
- Widget/Name: run_lin_primary_test_button
- Widget/Label: Test Primary LIN Card
- Signals:: Signal: clicked, Handler: on_run_lin_primary_test_clicked
- For the primary Progress Bar:
- Widget/Name: lin_primary_progress_bar
- Packing: "Yes" for all buttons available
- Packing/H Padding: 3
- Click the Save the Build buttons in the main Glade window.
- Refresh the Eclipse workspace (select the top level directory and press the F5 key)
- Open the tests.h file:
- Add the card type to the card_type enum (near the top of the file)
- Add a new "TestExtraInfo" struct near the bottom of the file. It should have at least a void* adapter_handle, a int (*open_adapter) (...) and a int (*close_adapter) (...) entry. See the other TestExtraInfo blocks for details.
- Add a run_*_test function declaration near the other run_*_test declarations.
- Open the callbacks.c file:
- Add a *_test_extra_infos array in the appropriate place. For now it can simply by populated with NULLs (since the functions haven't been implemented yet)
- Add appropriate entries in the appropriate spots to these arrays (at the top of the file). Be sure to fill in one entry each for primary and one for backup.
- test_progress_bar_names
- test_button_names
- output_text_view_names
- test_names
- test_functions -- Use the name you selected above for run_*_test
- Implement the button callback functions
- You'll find them at the end. Use the implementations of the other on_run_*_clicked functions as a guide.
- Add case statements for the new test type where necessary, copy/pasting the examples for other tests
- initialize_callbacks
- prepare_and_quit
- on_main_window_show
- NOTE: You've probably realized that there's a bit of copy/pasting of code. It's possible to hack this down (using macros or just rearranging the data structures) so that these case statements would be unnecessary. If you have the time, please fix it up.
- Now add the skeleton for the test code. This goes in tests.c:
- Start with this template (using the same function name and TestExtraInfo struct type as what was chosen in tests.h):
void *run_can_test(void *args)
{
int i;
TestInfo *test_info = (TestInfo *) args;
CANTestExtraInfo * can_test_extra_info = (CANTestExtraInfo*)test_info->extra_info;
char buf[message_width];
common_test_startup(test_info);
gdk_threads_enter();
notify_test_progress(test_info, _("Initializing"), 0);
gdk_threads_leave();
common_test_cleanup(test_info);
}
- At this point, it's worth going back to callbacks.c and adding
- At this point the program should build and run again. The test buttons should be greyed out, but otherwise, it should work.
Writing your generic test code
- Now, write the actual code to build this test.
- This is specific to your type of card, so I can't help much here.
- You will probalby have some sort of loop which looks something like this:
for(...) {
double percent = ... // Calculate percentage of test complete here
if (common_test_cancel_check(test_info))
return;
g_snprintf(buf, sizeof(buf), _("..."), ... ); // This will be a message for the user
gdk_threads_enter();
notify_test_progress(test_info, output_buffer, percent);
gdk_threads_leave();
// Run some part of the test
if(test_failed) {
common_test_failed(test_info);
}
g_usleep(10000); // Wait for a little while to give the illusion that the computer is working hard
}
- While writing this test, you will probably need to add new functions to your TestExtraInfo data structure.
- This keep card-specific code out of the general test code and will allow the whole program to compile, even when the drivers and libraries for some particular card are not available.
Writing the code for your specific card
- Here we will just implement the functions in your *TestExtraInfo structure. The code will go separate files.
- There should be a .h header and a .c implementation file.
- Name them after your card (adlink_7841.h and adlink_7841.c for an Adlink 7841 CAN card)
- The .c file is the only file that should access the functions in the library for the driver (that is, it's the only one that should include any card-specific headers)
- See the other card-specific .h and .c files for examples
- Note the .h file should include (only) tests.h. The .c file should include the .h file and any card-specific headers required.
- To build your new code, you'll need to modify configure.in, src/Makefile.am, and po/POTFILES.in.
- This is a bit complicated to describe. Try to follow the examples given for other cards if possible.
- When done, run ./autogen.sh to recreate all the makefiles.
- When done, you'll need to update the *_test_extra_infos array in callbacks.c.
- Block off your specific function names using an #ifdef structure.
- Don't forget that you'll need to include your new header file into callbacks.c