I am writing a C program on NIOS II SBT for Eclplise to deal with Pushbuttons interrupts on a DE2 board, not that it matters but I keep running into this error 'keys_irq' undeclared(first use in this function) error. I dont know what I am doing wrong.
volatile int keys_edge_capture;
static void keys_int_init() {
void* keys_edge_capture_ptr = (void*) &keys_edge_capture;
// Enable all three keys as interrupt
IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PUSH_BUTTONS_BASE, 0x0F);
// Reset edge capture register
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PUSH_BUTTONS_BASE, 0x00);
// Register ISR and place it on the interrupt table
alt_ic_isr_register(PUSH_BUTTONS_IRQ_INTERRUPT_CONTROLLER_ID, PUSH_BUTTONS_IRQ,keys_irq, keys_edge_capture_ptr, 0x00);
}
void keys_irq(void* context) {
// Recast context to keys_edge_capture type
volatile int* keys_edge_capture_ptr = (volatile int*) context;
// Read the edge capture to determine what triggered the interrupt
*keys_edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(PUSH_BUTTONS_BASE);
if (*keys_edge_capture_ptr & 0b0100) // extract KEY2
*(red_leds) = *(switches);
else if (*keys_edge_capture_ptr & 0b1000) { // extract KEY3
//do something
}
// clear the edge capture register
IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PUSH_BUTTONS_BASE, 0x00);
// dummy instruction to synchronize the handler
IORD_ALTERA_AVALON_PIO_EDGE_CAP(PUSH_BUTTONS_BASE);
return;
}
int main()
{
int SW_Value,Keys_Val;
int mask = 0xF;
while(1){
SW_Value = *(switches) & mask;
*(green_leds) = SW_Value;
keys_int_init();
}
return 0;
}
The function keys_int_init is calling a reference to keys_irq. Since keys_irq is not yet defined, the compiler doesn't know what the function is. In order to avoid this, you can add something called a prototype at the beginning of the file, before keys_int_init is defined.
void keys_irq(void* context);
This tells the compiler what type the function is so it knows how to handle it.
Related
Updated question - first version below
I have set up a custom signal handler to buffer frames being removed from a CAN interface. In the handler, I block the signal first, and unblock it last, using pthread_sigmask().
In bufferMessageDirect(), the interface ID iface_id is checked, and in case of error, because this can only normally be my fault, assert(0) is called.
After my programme has been running for some time, but the exact time varies, with a stream of CAN frames arriving, this assert() is tripped and execution ends. When I inspect the signal handler stack frame, iface_id is 0 which is valid, but the argument can_interface_id as passed into bufferMessageDirect() is -1.
I have a dump of the incoming CAN frames, and there is nothing unusual about them. The stack frame for the signal handler indicates that the converted CAN message is as expected and the the interface ID is 0. In the stack frame of bufferMessageDirect(), the interface ID is -1.
Please would you offer advice on what might be causing this issue?
I added the calls to pthread_sigmask() because I thought that, maybe, the signal was firing while its handler was already in progress.
/************************************************************** EXTERNAL DATA */
extern can_metadata_t can_metadata;
extern internal_time_t otherthing_heartbeat[THING_QUANTITY];
extern internal_time_t something_heartbeat[THING_QUANTITY];
/************************************************************** INTERNAL DATA */
STATIC volatile ssize_t bytes_read = 0;
STATIC volatile int socket_desc = 0;
STATIC volatile struct can_frame frame = {0};
STATIC volatile uint32_t receiver_id = 0u;
STATIC volatile uint32_t command_id = 0u;
STATIC volatile uint32_t function_id = 0u;
STATIC volatile int32_t iface_id = 0;
STATIC volatile cand_result_t d_result = CAND_RESULT_OK;
STATIC volatile canh_result_t h_result = CANH_RESULT_OK;
STATIC volatile internal_time_t *const heartbeats[2] =
{
otherthing_heartbeat,
something_heartbeat,
};
// ============================================================================
void
myHandler(int const signal_number,
siginfo_t *const p_signal_info,
void *const p_ucontext)
{
uint8_t ii = 0u;
uint8_t thing_id = 0u;
bool is_something = 0u;
can_message_t message = {0};
int std_result = 0;
/* Mark as unwanted */
(void) p_ucontext;
if ((HANDLERS_SIGNUM_CAN_RX != signal_number) ||
(NULL == p_signal_info))
{
/* No penalty for these conditions */
return;
}
else
{
/* Block this signal */
std_result = pthread_sigmask(SIG_BLOCK, &signal_set_can, NULL);
/* This result is asserted because the only failure is if the SIG_BLOCK
* action is invalid
*/
assert(0 == std_result);
socket_desc = p_signal_info->si_fd;
bytes_read = read(socket_desc, &frame, sizeof(frame));
if (bytes_read != sizeof(frame))
{
// ...
goto unblock_signal;
}
}
/* Is this an error frame? */
if ((frame.can_id & CAN_ERR_FLAG) != 0u)
{
// ...
goto unblock_signal;
}
/* Is this a frame with an 11-bit ID? */
else if ((frame.can_id & CAN_EFF_FLAG) == 0u)
{
// ...
goto unblock_signal;
}
/* Is this a frame with a 29-bit ID? */
else
{
function_id = frame.can_id & CAN_EFF_MASK;
command_id = function_id;
receiver_id = function_id;
function_id &= MASK_FUNCTION_ID;
function_id >>= POSITION_FUNCTION_ID;
command_id &= MASK_COMMAND_ID;
command_id >>= POSITION_COMMAND_ID;
receiver_id &= MASK_RECEIVER_ID;
thing_id = (frame.can_id & MASK_THING_ID) - 1u;
is_something = frame.can_id & MASK_RECEIVER_IS_SOMETHING;
/* Update the housekeeping stats */
if (function_id < FUNCTIONCODE_QUANTITY)
{
delivered_for_function_id[function_id]++;
}
else
{
delivered_for_function_id[FUNCTIONCODE_QUANTITY]++;
}
}
/* Handle emergency messages */
if (FUNCTIONCODE_EMGC == function_id)
{
// ...
goto unblock_signal;
}
/* Handle heartbeats */
if (FUNCTIONCODE_HB == function_id)
{
// Gets time from CLOCK_MONOTONIC_RAW and converts to microseconds
(void) getRawTimeFormatInternal(&(heartbeats[is_something][thing_id]));
goto unblock_signal;
}
/* Discard anything but Responses */
if (FUNCTIONCODE_RESPONSE != function_id)
{
// ...
goto unblock_signal;
}
/* Make the busy something available again */
if (true == is_something)
{
something_busy_bits &= ~(1 << thing_id);
}
/* Otherwise, find the interface ID and push to the buffer */
iface_id = -1;
/* Find buffer first */
for (ii = 0u; ii < CAN_INTERFACE_QUANTITY; ii++)
{
if (can_metadata.socket[ii] == socket_desc)
{
iface_id = (int32_t) ii;
break;
}
}
if (-1 == iface_id)
{
goto unblock_signal;
}
/* Otherwise convert and buffer */
h_result = canFrameToMessage(&message, &frame);
if (CAN_RESULT_OK != h_result)
{
// ...
goto unblock_signal;
}
d_result = bufferMessageDirect((can_interface_id_t) iface_id, &message);
if (CAN_RESULT_OK != d_result)
{
// ...
assert(0);
}
// ........................................................................
unblock_signal:
/* Unblock this signal */
std_result = pthread_sigmask(SIG_UNBLOCK, &signal_set_can, NULL);
/* This result is asserted because the only failure is if the SIG_BLOCK
* action is invalid
*/
assert(0 == std_result);
}
// ============================================================================
cand_result_t
bufferMessageDirect(
can_interface_id_t const can_interface_id,
can_message_t const *const p_message)
{
canh_result_t h_result = CANH_RESULT_OK;
cand_result_t result = CAND_RESULT_OK;
h_result = validateInterfaceId(can_interface_id);
if (CANH_RESULT_OK != h_result)
{
result = CAND_RESULT_INTERNAL_ERROR;
assert(0); // This is tripped, because can_interface_id is -1
}
// ...
// Push into buffer (call to buffer utility)
return result;
}
Old question
I have set up a custom signal handler to buffer frames being removed from a CAN interface. In the handler, I block the signal first, and unblock it last, using pthread_sigmask().
The basic recipe is:
void
myHandler(
int const signal_number,
siginfo_t *const p_signal_info,
void *const p_ucontext)
{
check_signal_info();
pthread_sigmask(SIG_BLOCK, set_of_this_signal_only);
read(socket, &can_frame, sizeof(can_frame));
derive_can_iface_id(&iface_id);
buffer_push((iface_enum_type) iface_id, can_frame);
pthread_sigmask(SIG_UNBLOCK, set_of_this_signal_only);
}
In buffer_push(), the interface ID iface_id is checked, and in case of error, because this can only normally be my fault, assert(0) is called.
After my programme has been running for some time, but the exact time varies, with a stream of CAN frames arriving, this assert() is tripped and execution ends. When I inspect the signal handler stack frame, iface_id is 0 which is valid, but the argument as passed into buffer_push() is -1.
I added the calls to pthread_sigmask() because I thought that, maybe, the signal was firing while its handler was already in progress.
The prototype for buffer_push() is:
result_enum_type
buffer_push(
iface_enum_type const can_interface_id,
can_frame_type const *const p_message)
iface_id is declared outside the function like so:
static volatile uint32_t iface_id = 0;
For the avoidance of doubt, below the call to buffer_push() it is all my own code --- no external calls. Also, I have a dump of the incoming CAN frames, and this signal handler correctly parses each one.
Please would you offer advice on what might be causing this issue?
How can the value of an argument in a function called from a signal handler be different from the value passed in?
How can that happen? Because the C standard says it can:
When the processing of the abstract machine is interrupted by receipt of a signal, the values of objects that are neither lock-free atomic objects nor of type volatile sig_atomic_t are unspecified, as is the state of the floating-point environment. The value of any object modified by the handler that is neither a lock-free atomic object nor of type volatile sig_atomic_t becomes indeterminate when the handler exits, as does the state of the floating-point environment if it is modified by the handler and not restored to its original state.
None of the following are either "lock-free atomic obects" or of "type volatile sig_atomic_t":
STATIC volatile ssize_t bytes_read = 0;
STATIC volatile int socket_desc = 0;
STATIC volatile struct can_frame frame = {0};
STATIC volatile uint32_t receiver_id = 0u;
STATIC volatile uint32_t command_id = 0u;
STATIC volatile uint32_t function_id = 0u;
STATIC volatile int32_t iface_id = 0;
STATIC volatile cand_result_t d_result = CAND_RESULT_OK;
STATIC volatile canh_result_t h_result = CANH_RESULT_OK;
STATIC volatile internal_time_t *const heartbeats[2] =
{
otherthing_heartbeat,
something_heartbeat,
};
Every single one of those variables has indeterminate value when your signal handler is invoked, and every one of those variables will become indeterminate when your signal handler returns if they're modified in the signal handler.
Note also footnote 188 of the (draft) C11 standard:
Thus, a signal handler cannot, in general, call standard library functions.
Basically, you can't safely do much of anything in a signal handler. Strictly-conforming C code can only modify objects as noted above. POSIX extends what a signal handler can safely do to calling only functions that are async-signal-safe - a very limited set. Windows has similar provisions. The Linux signal-safety man page provides the Linux-specific list of functions that are async-signal-safe on Linux.
What's potentially happening is there are race conditions between your normal processing and your signal processing. It works most of the time, but every now and then one of those race conditions appears and you get corrupted values.
I'm aware of volatile keyboard and it doesn't ensure synchronization safety.
The following code is used inside an interrupt routine, and I'm using heavily the function
GetCharUART inside the main loop.
Is it safe to and stable to write code like that ? or I have to go to low level synchronization like a mutex, if that's true, how would I protect that rbuf ?
volatile char rbuf[5][UART_BUFSIZE];
vu16 rin[5] = { 0, 0, 0, 0, 0 };
vu16 rout[5] = { 0, 0, 0, 0, 0 };
void USART_IRQHandler(char Channel, USART_TypeDef *USARTx)
{
volatile unsigned int IIR;
IIR = USARTx->SR;
if (IIR & USART_FLAG_RXNE)
{ // read interrupt
USARTx->SR &= ~USART_FLAG_RXNE; // clear interrupt
rbuf[Channel][rin[Channel]] = USART_ReceiveData(USARTx);
rin[Channel]++;
if(rin[Channel]>=UART_BUFSIZE) rin[Channel]=0;
}
if (IIR & USART_FLAG_TXE)
{
USARTx->SR &= ~USART_FLAG_TXE; // clear interrupt
}
}
int GetCharUART (char Channel)
{
int result;
if (rin[Channel]==rout[Channel]) {
return EMPTY;
}
result=rbuf[Channel][rout[Channel]];
rout[Channel]++;
if(rout[Channel]>=UART_BUFSIZE)
rout[Channel]=0;
return result;
}
Modified code:
void USART_IRQHandler(char Channel, USART_TypeDef *USARTx)
{
volatile unsigned int IIR;
IIR = USARTx->SR;
if (IIR & USART_FLAG_RXNE)
{ // read interrupt
USARTx->SR &= ~USART_FLAG_RXNE; // clear interrupt
rbuf[Channel][rin[Channel]% UART_BUFSIZE] = USART_ReceiveData(USARTx);
rin[Channel]++;
}
if (IIR & USART_FLAG_TXE)
{
USARTx->SR &= ~USART_FLAG_TXE; // clear interrupt
}
}
/******************************************************************************/
int GetCharUART (char Channel)
{
int result;
if (rin[Channel]==rout[Channel]) {
return EMPTY;
}
result=rbuf[Channel][rout[Channel]% UART_BUFSIZE];
rout[Channel]++;
return result;
}
Your code has a functional bug.
In the ISR you don't check for a "buffer full" condition. The code just increments rin[Channel] without looking at rout[Channel]. So a whole buffer of data can be lost.
Example: If rout[Channel] equals zero and rin[Channel] equals UART_BUFSIZE-1 then the ISR will set rin[Channel] to zero. In other words the buffer will now appear empty and data is lost.
So the first step is to fix the code.
Rather than trying to make data structures that would work synchronously work with interrupts, it's best to use a different data structure that actually is safe for use in interrupts.
It is common for circular/ring buffers to be used for data structures that need to be shared between regular code and interrupt code.
https://en.wikipedia.org/wiki/Circular_buffer
A circular buffer is implemented with two indices, and each side is only modifying one of the indices, which has a sort of reader/writer style. This allows it to be pushed onto and popped off by concurrent executions.
Because of the dual indices and the fact the indices are always incremented in one direction, the worst case that could happen is that the interrupt dropped a byte when the buffer is almost full because it didn't pick up on a recent change to the other index, which is not a big deal.
If you make your own implementation, remember to test it, because it can be easy to mess up.
The code snippets below come from the manufacturer. I am completely confused as to what they are trying to do. In particular, anything to do with InterruptHandler.
Please comment on the code in the globals section. Does this look right?
Also the various APIs included all have sticking points for me. Are they trying to use a void pointer? ... Plenty to ask, please comment mainly on how they are suggesting the timer2 would work.
...
/**
Section: Global Variables Definitions
*/
void (*TMR2_InterruptHandler)(void);
...
/**
Section: TMR2 APIs
*/
void TMR2_Initialize(void)
{
// Set TMR2 to the options selected in the User Interface
// T2CKPS 1:2; T2OUTPS 1:2; TMR2ON off;
T2CON = 0x11;
// T2CS LFINTOSC;
T2CLKCON = 0x04;
// T2PSYNC Not Synchronized; T2MODE Software control One shot; T2CKPOL Rising Edge; T2CKSYNC Not Synchronized;
T2HLT = 0x08;
// T2RSEL TMR4_postscaled;
T2RST = 0x02;
// PR2 8;
T2PR = 0x08;
// TMR2 0;
T2TMR = 0x00;
// Clearing IF flag before enabling the interrupt.
PIR4bits.TMR2IF = 0;
// Enabling TMR2 interrupt.
PIE4bits.TMR2IE = 1;
// Set Default Interrupt Handler
TMR2_SetInterruptHandler(TMR2_DefaultInterruptHandler);
// Start TMR2
TMR2_Start();
}
void TMR2_ISR(void)
{
// clear the TMR2 interrupt flag
PIR4bits.TMR2IF = 0;
if(TMR2_InterruptHandler)
{
TMR2_InterruptHandler();
}
}
void TMR2_SetInterruptHandler(void* InterruptHandler)
{
TMR2_InterruptHandler = InterruptHandler;
}
void TMR2_DefaultInterruptHandler(void)
{
// add your TMR2 interrupt custom code
// or set custom function using TMR2_SetInterruptHandler()
}
/**
End of File
*/
Thanks,
Steve
edit:
The manufacturer code includes a routine (I can't seem to add it here) for managing high-level interrupts that calls TMR2_ISR if (PIE4bits.TMR2IE == 1 && PIR4bits.TMR2IF == 1) This would seem to negate any TMR2_DefaultInterruptHandler would it not?
Thanks again for your help.
The comments of Garr Godfrey and Martin James provided helpful hints. Thus, I will try to fill the possible gaps:
void (*TMR2_InterruptHandler)(void); is a global variable with a function pointer providing the current interrupt handler.
I would read TMR2_ISR() as "interrupt service routine". From the presented code, it's not clear from where it is called. Suspecting from it's name, it's reasonable to assume that it's called when the interrupt is triggered. It checks whether the global interrupt handler function pointer TMR2_InterruptHandler is not NULL and calls the pointed function in case of success.
If TMR2_Initialize() has been called before then TMR2_InterruptHandler points to function TMR2_DefaultInterruptHandler(). Thus, in this case, the latter is called from TMR2_ISR().
void TMR2_SetInterruptHandler(void* InterruptHandler) is used in TMR2_Initialize(). It sets the current interrupt handler. (Surprise.)
I'm a little bit puzzled because I would make it:
void TMR2_SetInterruptHandler(void (*InterruptHandler)())
This is because my daily work with C++ drilled me for "clean typing" but I remember that C is much more lax about this. (void* is compatible to any pointer.)
As Garr Godfrey already said: "put your code in TMR2_DefaultInterruptHandler"
where it is recommended by the comment
// add your TMR2 interrupt custom code
I am using an MSP430 and writing code in C. I am receiving characters (working) via UART and placing them into an array rxDataArray. Since I am using an MSP430G2211, I have limited memory. The maximum array size is 50 and any more it won't build/load and says out of space.
My MSP430 is communicating to a ESP8266 module (wifi) where I am using "AT" commands. I am receive an echo of my AT command, followed by a response (ex. AT+RST responds with AT+RST...ok). I am confused using C, how I can make a string with just the "ok" response and check if it worked correctly. I have the data in the array, just not sure how to pick certain elements of the array, make a string, and compare that to "ok" response. I am used to using CString in C++ and am confused how to do this in C.
/--------------------------------------------------------------------
// Timer_A UART - Receive Interrupt Handler
//-------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMERA1_VECTOR))) Timer_A1_ISR (void)
#else
#error Compiler not supported!
#endif
{
static unsigned char rxBitCnt = 8;
static unsigned char rxData = 0;
switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching
case TAIV_TACCR1: // TACCR1 CCIFG - UART RX
TACCR1 += UART_TBIT; // Add Offset to CCRx
if (TACCTL1 & CAP) { // Capture mode = start bit edge
TACCTL1 &= ~CAP; // Switch capture to compare mode
TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0
}
else {
rxData >>= 1;
if (TACCTL1 & SCCI) { // Get bit waiting in receive latch
rxData |= 0x80;
}
rxBitCnt--;
if (rxBitCnt == 0) { // All bits RXed?
rxBuffer = rxData; // Store in global variable
if (rxDataCnt < 50)
{
rxDataArray[rxDataCnt] = rxBuffer;
rxDataCnt++;
}
else
{
int i = 0;
for (i; i<50-1; i++)
{
rxDataArray[i] = rxDataArray[i+1];
}
rxDataArray[50-1] = rxBuffer;
}
rxBitCnt = 8; // Re-load bit counter
TACCTL1 |= CAP; // Switch compare to capture mode
__bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR)
}
}
break;
}
}
//-----------------------------------------------------------------------
You can turn OFF echo by sending ATE0 command.
Also to find the intended string response please follow below steps:
Enable UART Transmit and Receive Interrupt.
After completing your command transmission you will start receiving data in UART ISR.
In the receive interrupt start a timer of say 1 second(You need to consider baud-rate for exact calculation).
Make track of number of received bytes in UART ISR.
Now after timer expires add null to end of last received byte in buffer.
Now,You can use string manipulation functions of C to find the intended response.
I am attempting to pass a reference to an I/O pin as an function argument on a PIC24F MCU using C. For PICs, the device header file provides access to the i/o buffer registers via:
LATAbits.LATA2 = 0; // sets the pin (RA2 in this case) low.
if (PORTAbits.RA3) { // reads the state of the pin. (RA3)
I want to do something like this:
int main() {
Configure(); // Sets up peripherals, etc.
WaitForHigh(PORTAbits.RA3); // waits for pin RA3 to go hi.
...
return 0;
}
void WaitForHigh( ?datatype? pin_reference ) {
while( !pin_reference ); // Stays here until the pin goes hi.
}
So what datatype am I trying to pass here? And what's actually going on when I poll that pin? Below, I copy a relevant portion from the PIC24F device header that I'm using in case it helps.
#define PORTA PORTA
extern volatile unsigned int PORTA __attribute__((__sfr__));
typedef struct tagPORTABITS {
unsigned RA0:1;
unsigned RA1:1;
unsigned RA2:1;
unsigned RA3:1;
unsigned RA4:1;
unsigned RA5:1;
} PORTABITS;
extern volatile PORTABITS PORTAbits __attribute__((__sfr__));
Thank you in advance!
As an alternative to using a macro, a function can accept both the PORT register address (or latch register address, eg. LATA in the case of a pin configured for output) and the mask of the bit in the register that is needed. For example:
#include<p24FV32KA301.h> // defines both PORTA and _PORTA_RA3_MASK
void WaitForHigh( volatile unsigned int * port, pin_mask ) {
while( !(*port & pin_mask) ); // Stays here until the pin goes hi.
}
int main()
{
...
WaitForHigh( &PORTA, _PORTA_RA3_MASK ); // waits for pin RA3 to go hi.
...
return 0;
}
Please, note that the PORT bit values are obtained through a bit field, so, answering your question, you can't. Bit fields doesn't have address, so you cannot pass it as a pointer to a function.
Instead, you could use a Macro:
#define WaitForHigh(p) do{while(!(p));}while(0)
It is true that macros has it's draw backs on code readability, yet, given that proper care is taken, there are situations where they're the best solution. It is arguable if macro is the best solution in this Q&A, yet it is important to mention.
Thanks to the commenters for the suggestions to improve the macro safeness.
You can combine preprocessor processing with a function to get what you wan along with compile time checking of the symbols. For example:
#define PORT_FUNC(f, p, b) f(p, b)
#define WaitForHigh(p, b) PORT_FUNC(WaitForHighImp, &p, _ ##p## _ ##b## _MASK)
void WaitForHighImp(volatile unsigned* p, unsigned char mask)
{
while (!(*p & m))
;
}
int main()
{
WaitForHigh(PORTA, RA3);
}
The advantage of this approach is that you online say "PORTA" once and "RA3" once at the time of the call, you make sure the bit name is present in the port and that the bit is present.