Hello,
I'm writing an application for cc2530 and I'm using Z-Stack. Now in my application there is an array of structs.
Any struct in this array can be modified when arrives message from another zigbee device or command from uart. I need to modify hole struct in the same time - atomic operation.
First question: Is good idea to disable interrupts when I operate (replacing data in the structure) with this "big" structure (in the structure there is IEEE address, network address and 1 uint8 flag)? Is there any better option than to disable interrupts while I'm in the critical section in Z-Stack/OSAL?
Second question: I think that If I would implement simple mutex with "active waiting", it would cause deadlock because of "cooperative round-robin"...like this:
-> incomming uart command:
uart function(){
mutex_lock(x)
.....
->incomming message -> this function interrupted, running incomming_message_function()
....
mutex_unlock(x)
}
incomming message:
incomming_message_function(){
mutex_lock()
waiting for mutex..... -> deadlock
...or I'm wrong?
Thank you!
Hello, I would like to simplify my question...
I want to ask you:
I have an application in Z-Stack. In my application I've data, which can be modified when message from another device arrive or when arrive command thru UART (callback function). This application is fully operational, but I'm not sure with critical sections in Z-Stack.
Should I handle data modification functions like a "critical section" or functions can't overlap (and every function will finish before another will start)?
Thank you for reply!
RE: "when message from another device arrive or when arrive command thru UART (callback function)"
So 2 part answer to your 2 part question:
1. When data arrives by RF Rx, your Application will eventually receive the data via an OSAL message, namely a 'SYS_EVENT_MSG' with the event as a 'AF_INCOMING_MSG_CMD'. In this case, the memory of the incoming message is completely free from any race or overwrite by any ISR - to be sure, the Application layer owns that memory and must thereby free it as you see in any sample application:
// Release the memory osal_msg_deallocate( (uint8 *)MSGpkt );
2. When data arrives by UART Rx, the Application that opened the UART port gets notified of several important Rx events (like a few bytes of data have been received but are just sitting there with no more coming in, HAL_UART_RX_TIMEOUT, or so many bytes have been received that the circular receive queue is about to overrun itself if you don't quickly read some out, HAL_UART_RX_ABOUT_FULL). In this case, the Application will read the received bytes out of the circular receive queue via the provided API:
extern uint16 HalUARTRead ( uint8 port, uint8 *pBuffer, uint16 length );
The HAL UART driver provided will deconflict any of its local data variables or structures from corruption by an ISR, so the Application does not need to worry about this. Although the data bytes read out could consist of a "message" that may have been corrupted by not reading the bytes out soon enough. Thus, many UART protocols (witness the MT message structure) wrap messages in packtes that have a known start character and a check sequence to ensure message integrity.
Tank you for reply!
I use my own simple protocol for UART with integrity check, so that's not problem :-)
I want to ask you, can for example 'HAL_UART_RX_TIMEOUT' event break any 'running function', or the 'running function' will finish before 'HAL_UART_RX_TIMEOUT' will be served?
I figured from Z-Stack documents, that my 'running function' will finish before another serving function in the app will be executed - is it true? :-)
Right - OSAL is just a simple, round-robin, prioritized, loosely cooperative, tasking loop. So you see that you have the opportunity to get a callback on every pass through the loop (the callback would come from within the 'Hal_ProcessPoll()' function):
void osal_run_system( void ){ uint8 idx = 0;
osalTimeUpdate(); Hal_ProcessPoll();
do { if (tasksEvents[idx]) // Task is highest priority that is ready. { break; } } while (++idx < tasksCnt);
if (idx < tasksCnt) {
Thus, a task with a UART callback is essentially "elevated" in priority to be the highest by that callback.
Your Application task is free to call HalUARTRead() anytime it is running - you may get zero bytes or only the first part of an incoming packet, but no other bad side effects.
I finished before a week, but I wasn't sure that it is 100% OK!