Can I use timer counter value `TIMx_CNT` in main function? - timer

I am testing STM32F103C6 developing board and I want to use TIMx_CNT value in main function like this.
int main(void)
{
while(1)
{
if(TIM2_CNT<500)
{
GPIO_SetBits(GPIOA, GPIO_Pin_4);
} else {
GPIO_ResetBits(GPIOA, GPIO_Pin_4);
}
}
}
Is this possible?
Thanks.

Yes, it's possible. Assuming that you have CMSIS compatible headers included, you need to write TIM2->CNT (instead of TIM2_CNT). Other peripherals follow the same notation.
But for coding style consistency, if you're using ST's HAL (or Cube) libraries, you may want to prefer to use the functions provided by these libraries instead of direct register access, unless there are significant performance benefits.

Related

How to write same client text when using different implementation?

I'm working on projects where I write code on both the client and supplier side.
Suppose in project_A I choose chip_A and in project_B I choose chip_B. Both chip_A and chip_B provide similar functionality.
Next, I encapsulate chip_A and chip_B into modules, respectively.
chip_a.h
typedef sturct
{
uint8_t element1;
uint8_t element2;
...
uint8_t element8;
uint8_t element9;
}chip_a_t;
bool chip_a_get_element1(chip_a_t* me);
bool chip_a_get_element2(chip_a_t* me);
...
bool chip_a_get_element8(chip_a_t* me);
bool chip_a_get_element9(chip_a_t* me);
chip_b.h
typedef sturct
{
uint8_t element_a;
uint8_t element_b;
...
uint8_t element_y;
uint8_t element_z;
}chip_b_t;
bool chip_b_get_element_a(chip_b_t* me);
bool chip_b_get_element_b(chip_b_t* me);
...
bool chip_b_get_element_y(chip_b_t* me);
bool chip_b_get_element_z(chip_b_t* me);
Suppose the program code needs an element_123 (for chip_A is a combination of element_1 and element_8, and for chip_B is a combination of element_a, element_b, element_y and element_z), and the program text is always the same even in different projects; the difference between projects is only the choice of chip.
program.c
agent_t agent = {0};
if (agent_get_element_123(&agent) != true) {return;}
uint8_t data = agent.element_123 + some_data;
/*do other things...*/
If I code agent.c like this
/*agent.c*/
bool agent_get_element_123(agent_t* me)
{
chip_a_t chip_a = {0};
if ((chip_a_get_element1(&chip_a) != true)
|| (chip_a_get_element8(&chip_a) != true))
{
return false;
}
me->element_123 = chip_a.element1 + chip_a.element8;
return true;
}
I will bind agent module to chip_a module, and the agent module is only available for project_A; bind agent module to chip_b being only available for project_B.
Is there a way to write the same client text (agent.c) for different projcets?
FYI:
Hardware only and always supports one chip. It is impossible to have two chips on one hardware.
One project might include code for chip_A and chip_B at the same time, because we often copy entire folder from one project to another project.
There are SO many ways to handle stuff like this, a lot of it depends on what exactly you want to do and what your limitations are.
For example, is the interface between the chips identical, so that the code in agent.c is the same, just with different function names? Then you can just write all your chips to have the same API and link in whichever one you want.
If the code is different, is it possible to introduce a higher-level interface that provides a similar API across all the chips? Then you can have each chip provide this interface and write agent.c to that interface.
You can have an array of function pointers, and each chip fill it in with their functions, then agent.c would choose the element in that array and call the function.
You can create multiple shared libraries, one for each chip, then have agent.c use dlopen() to pick the right one and dlsym() to obtain pointers to the functions.
Do you want the choice of which chip to be used to be a compile time decision (use a preprocessor option to choose), a link time decision (link in different object files with the same API), or a run time decision (choose different share libraries at runtime)?
What you need is conditional-compilation , you need to enable your configurations for CHIP_A or CHIP_B when compiling.
suppose if you want to compile for CHIP_A, then
/* can be done in many ways, used this for simplicity */
#define CHIP_A TRUE
function()
{
/* common code */
#ifdef CHIP_A
/* CHIP_A related code */
#endif /* CHIP_A */
#ifdef CHIP_B
/* CHIP_B related code */
#endif /* CHIP_B */
/* common code */
}

How to detect unreleased lock in multi-task C project using static analysis tools?

Is there any way, using static analysis tools(I'm using Codesonar now), to detect unreleased lock problems (something like unreleased semaphores) in the following program?(The comment part marked by arrows)
The project is a multi-task system using Round-robin scheduling, where new_request() is an interrupt task comes randomly and send_buffer() is another period task.
In real case, get_buffer() and send_buffer() are various types of wrappers, which contains many call layers until actual lock/unlock process. So I can't simply specify get_buffer() as lock function in settings of static analysis tool.
int bufferSize = 0; // say max size is 5
// random task
void new_request()
{
int bufferNo = get_buffer(); // wrapper
if (bufferNo == -1)
{
return; // buffer is full
}
if (check_something() == OK)
{
add_to_sendlist(bufferNo); // for asynchronous process of send_buffer()
}
else // bad request
{
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// There should be clear_buffer placed here
// but forgotten. Eventually the buffer will be
// full and won't be cleared since 5th bad request comes.
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
do_nothing();
// clear_buffer(bufferNo);
}
}
int get_buffer()
{
if(bufferSize < 5)
{
bufferSize++;
return bufferSize;
}
else
{
wait_until_empty(); // wait until someone is sent by send_buffer()
return -1;
}
}
// clear specifiled one in buffer
void clear_buffer(int bufferNo)
{
delete(bufferNo)
bufferSize--;
}
// period task
void send_buffer()
{
int sent = send_1st_stuff_in_list();
clear_buffer(sent);
}
yoyozi - Fair disclosure: I'm an engineer at GrammaTech who works on CodeSonar.
First some general things. The relevant parts of the manual for this are on the page: codesonar/doc/html/C_Module/LibraryModels/ConcurrencyModelsLocks.html. Especially the bottom of the page on Resolving Lock Operation Identification Problems.
Based on your comments, I think you have already read this, since you address setting the names in the configuration settings.
So then the question is how many different wrappers do you have? If it is only a few, then the settings in the configuration file are the way to go. If there are many, that gets tedious. And if there are very many it becomes practically impossible.
So knowing some estimate for how many wrapper sets you have would help.
Even with the wrappers accounted for, it may be that the deadlock and race detectors aren't quite what you need for your problem.
If I understand your issue correctly, you have a queue with limited space, and by accident malformed items don't get cleaned out of the queue, and so the queue gets full and that stalls all processing. While you may have multiple threads involved in this implementation, the issue itself would still be a problem in a basically serial setting.
The best way to work with an issue like this is to try and make a simpler example that displays the same core problem. If you can do this in a way that can be shared with GrammaTech, we can work with you on ways to adjust settings or maybe provide hints to the analysis so it can find this issue.
If you would like to talk about this in more detail, and with prodetction against public disclosure of your code, please contact us at support_at_grammatech_dot_com, where the at and dot should be replaced as needed to make a well formed email address.

ASF4 Microchip API timer driver reset function

I'm using ASF4 API hal_timer for a ARM Cortex M4. I'm using the timer driver to timing a data sequence.
Why does no reset function exist? I'm using the timer on a TIMER_TASK_ONE_SHOT mode and want to reset it when ever I need to.
I thought a simple
timer_start(&TIMER_0);
timer_stop(&TIMER_0);
would do the trick but does not seem to work.
Is it necessary to re-initialize the timer for each timing event?
I'm probably missing something obvious. Am I approaching this problem incorrectly reason being why the method timer_reset() doesn't exist?
I have no experience of this API, but looking at the documentation it is apparent that a single timer can have multiple tasks on different periods, so resetting TIMER_0 makes little semantic sense; rather you need to reset the individual timer task attached to the timer - of which there may be more than one.
From the documentation (which is poor and contains errors), and the source code which is more reliable:
timer_task_instance.time_label = TIMER_0.time ;
where the timer_task_instance is the struct timer_task instance you want to reset. This sets the start time to the current time.
Probably best to wrap that in a function:
// Restart current interval, return interval.
uint32_t timer_restart( struct timer_descriptor* desc, struct timer_task* tsk )
{
tsk->time_label = desc->time
return tsk->interval ;
}
Then:
timer_restart( &TIMER_0, &timer_task_instance ) ;
Assuming you're using the (edited) example from the ASF4 Reference Manual:
/* TIMER_0 example */
static struct timer_task TIMER_0_task;
static void TIMER_0_task_cb(const struct timer_task *const timer_task)
{
// task you want to delay using non-existent reset function.
}
void TIMER_0_example(void)
{
TIMER_0_task.interval = 100;
TIMER_0_task.cb = TIMER_0_task_cb;
TIMER_0_task.mode = TIMER_TASK_ONE_SHOT;
timer_add_task(&TIMER_0, &TIMER_0_task);
timer_start(&TIMER_0);
}
Instead of resetting, which isn't supported by the API, you could use:
timer_remove_task(&TIMER_0, &TIMER_0_task);
timer_add_task(&TIMER_0, &TIMER_0_task);
which will effectively restart the delay associated with TIMER_0_task.
Under the hood, timer tasks are maintained as an ordered list, in order of when each task will expire, and using the functions provided by the API maintains the list order.

Implementation of time in Zynq

I'm trying to do a simple STANDALONE application for Zynq. I want to use the 'time.h' to manipulate date/time. I know that there is no hardware implementation on a stanalone BSP, but I want to wire it up on my own.
During compilation, when I call 'time(NULL)' I get a error, that there is no implementation of '_gettimeofday()'. I've found it in and implemented it according to the function definition, so that the errors disappear and everything looks ok, but when I run my project on hardware, I see only zeroes from time().
Can anybody help?
Regards,
G2
Ok, I've done some research, and found this link. This is almost what I'v been searching, but instead of '_times()' I needed '_gettimeofday()' and this is my implementation:
int _gettimeofday(struct timeval *__p, void *__tz)
{
__p->tv_sec = (systemUsCounter / 1000000);
__p->tv_usec = systemUsCounter;
return 0;
}
I left the '__tz' pointer with no chainges.
So this is basicly how to utilize 'time.h' in a standalone application on Zynq.

How to test legacy C code and check which branches where hit

I have a DLL which contains many large (1000+ line) functions. This code has lots of complex logic which I want to ensure doesn't get broken when its maintained so I created a test harness which dynamically loads this DLL and calls its API.
I would like to know a nice way of being able to test which branches of the code where hit within this API from my test harness. The only way I can think of doing this is as follows:
// Pseudo test code
void doTest()
{
loadDllToBeTested();
dll_api_function_1();
assert( dll_api_function_1_branches.branch1Hit == true );
unloadDllToBeTested();
}
// Real api in the C dll
struct dll_api_function_1_branches
{
bool branch1Hit;
}
dll_api_function_1_branches g_dll_api_function_1_branches;
int private_func1()
{
printf("Doing my private stuff\n");
return 1;
}
void dll_api_function_1(void)
{
if ( private_func1() )
{
printf("doing some stuff\n");
dll_api_function_1_branches.branch1Hit = true; // so the test code can check if we got here :(
}
else
{
printf("doing some other stuff\n");
}
// tons of other logic and branching...
}
Which is basically have a struct per function which has values set when certain branches are reached within the function. There would be a global exported instance of this struct which the test code would have to init to zero and then check after calling the API.
Also note that I'm using Visual Studio so tools like gcov can't be used here.
The LLVM project mentions the KLEE tool, which helps creating test cases to exercise all paths (and find bugs in the process). Some of it is strongly Unix-oriented, and it is a current research project (rough edges, some assembly required, and the other disclaimers).

Resources