How does a receiving process actually receive a process from a sender process via message queues? - operating-system

I'm working on a project with a sender and receiver process using shared memory and a message queue. For the life of me, I cannot get the receiver process to receive the file, but i can't figure out what's actually going wrong. It seems like it's actually not getting the file or it's just stuck in an infinite loop.
So I understand that using a message queue, you need to attach to the message queue, using the message queue id. Then when you send a message, it goes to the message queue, and the receiver can receive it from that message queue. However that's what i'm doing (i think) in my code, but as mentioned before the receiver process doesn't seem to get the file. So am I wrong in how a process receives a message and thus implementing the code wrong? Any help would be greatly appreciated, as my professor just kinda threw us into this with no explanation on how to do this, so i've been trying to teach myself. This is what i have for my code:
message.h:
#include <stdio.h>
/* The information type */
#define SENDER_DATA_TYPE 1
/* The done message */
#define RECV_DONE_TYPE 2
/**
* The message structure
*/
struct message
{
/* The message type */
long mtype;
/* How many bytes in the message */
int size;
/**
* Prints the structure
* #param fp - the file stream to print to
*/
void print(FILE *fp)
{
fprintf(fp, "%ld %d", mtype, size);
}
};
Sender.cpp:
#include <iostream>
#include <sys/shm.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "msg.h" /* For the message struct */
/* The size of the shared memory chunk */
#define SHARED_MEMORY_CHUNK_SIZE 1000
/* The ids for the shared memory segment and the message queue */
int shmid, msqid;
/* The pointer to the shared memory */
void* sharedMemPtr;
/**
* Sets up the shared memory segment and message queue
* #param shmid - the id of the allocated shared memory
* #param msqid - the id of the shared memory
*/
void init(int& shmid, int& msqid, void*& sharedMemPtr)
{
std::cout<<"Creating key"<<std::endl;
key_t key = ftok("keyfile.txt", 'a');
std::cout<<"Key created"<<std::endl;
shmid =shmget(key,SHARED_MEMORY_CHUNK_SIZE, 0644|IPC_CREAT);
std::cout<<"allocated shared memory"<<std::endl;
sharedMemPtr = shmat(shmid,NULL,0);
std::cout<<"Attached to shared memory"<<std::endl;
msqid = msgget(key,0644|IPC_CREAT);
std::cout<<"Attahed to message queue"<<std::endl;
}
void cleanUp(const int& shmid, const int& msqid, void* sharedMemPtr)
{
/* TODO: Detach from shared memory */
shmdt(sharedMemPtr);
}
/**
* The main send function
* #param fileName - the name of the file
*/
void send(const char* fileName)
{
/* Open the file for reading */
FILE* fp = fopen(fileName, "r");
/* A buffer to store message we will send to the receiver. */
message sndMsg;
/* A buffer to store message received from the receiver. */
message rcvMsg;
/* Was the file open? */
if(!fp)
{
perror("fopen");
exit(-1);
}
/* Read the whole file */
while(!feof(fp))
{
if((sndMsg.size = fread(sharedMemPtr, sizeof(char), SHARED_MEMORY_CHUNK_SIZE, fp)) < 0)
{
perror("fread");
exit(-1);
}
/* TODO: Send a message to the receiver telling him that the data is ready
* (message of type SENDER_DATA_TYPE)
*/
sndMsg.mtype = SENDER_DATA_TYPE;
sndMsg.size = 0;
msgsnd(msqid,&sndMsg,sizeof(sndMsg),0);
std::cout<<"Sent data ready message"<<std::endl;
/* TODO: Wait until the receiver sends us a message of type RECV_DONE_TYPE telling us
* that he finished saving the memory chunk.
*/
std::cout<<"Waiting for reciever message"<<std::endl;
msgrcv(msqid,&rcvMsg,0,RECV_DONE_TYPE,0);
std::cout<<"Message received"<<std::endl;
}
/** TODO: once we are out of the above loop, we have finished sending the file.
* Lets tell the receiver that we have nothing more to send. We will do this by
* sending a message of type SENDER_DATA_TYPE with size field set to 0.
*/
sndMsg.size =0;
sndMsg.mtype = SENDER_DATA_TYPE;
std::cout<<"Sending empty message"<<std::endl;
msgsnd(msqid,&sndMsg,sizeof(sndMsg),0);
std::cout<<"Empty message sent"<<std::endl;
/* Close the file */
fclose(fp);
}
int main(int argc, char** argv)
{
/* Check the command line arguments */
if(argc < 2)
{
fprintf(stderr, "USAGE: %s <FILE NAME>\n", argv[0]);
exit(-1);
}
/* Connect to shared memory and the message queue */
init(shmid, msqid, sharedMemPtr);
/* Send the file */
send(argv[1]);
/* Cleanup */
cleanUp(shmid, msqid, sharedMemPtr);
return 0;
}
Receiver.cpp:
#include <iostream>
#include <sys/shm.h>
#include <sys/msg.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "msg.h" /* For the message struct */
/* The size of the shared memory chunk */
#define SHARED_MEMORY_CHUNK_SIZE 1000
/* The ids for the shared memory segment and the message queue */
int shmid, msqid;
/* The pointer to the shared memory */
void *sharedMemPtr;
/* The name of the received file */
const char recvFileName[] = "recvfile";
/**
* Sets up the shared memory segment and message queue
* #param shmid - the id of the allocated shared memory
* #param msqid - the id of the shared memory
* #param sharedMemPtr - the pointer to the shared memory
*/
void init(int& shmid, int& msqid, void*& sharedMemPtr)
{
std::cout<<"Creating key"<<std::endl;
key_t key = ftok("keyfile.txt", 'a');
shmid =shmget(key,SHARED_MEMORY_CHUNK_SIZE, 0644 | IPC_CREAT);
std::cout<<"allocated shared memory"<<std::endl;
sharedMemPtr = shmat(shmid,NULL,0);
std::cout<<"Attached to shared memory"<<std::endl;
msqid = msgget(key,0644 | IPC_CREAT);
std::cout<<"Attahed to message queue"<<std::endl;
}
void mainLoop()
{
/* The size of the mesage */
int msgSize =0;
/* Open the file for writing */
FILE* fp = fopen(recvFileName, "w");
/* Error checks */
if(!fp)
{
perror("fopen");
exit(-1);
}
std::cout<<"Waiting for message"<<std::endl;
/* TODO: Receive the message and get the message size. The message will
* contain regular information. The message will be of SENDER_DATA_TYPE
* (the macro SENDER_DATA_TYPE is defined in msg.h). If the size field
* of the message is not 0, then we copy that many bytes from the shared
* memory region to the file. Otherwise, if 0, then we close the file and
* exit.
* Keep receiving until the sender set the size to 0, indicating that
* there is no more data to send
*/
while(msgSize != 0){
message recvdMsg;
msgrcv(msqid,&recvdMsg,sizeof(recvdMsg),SENDER_DATA_TYPE,0);
msgSize = recvdMsg.size;
std::cout<<"Entering main loop"<<std::endl;
/* If the sender is not telling us that we are done, then get to work */
if(msgSize != 0)
{
/* Save the shared memory to file */
if(fwrite(sharedMemPtr, sizeof(char), msgSize, fp) < 0)
{
perror("fwrite");
}
/* TODO: Tell the sender that we are ready for the next file chunk.
* I.e. send a message of type RECV_DONE_TYPE (the value of size field
* does not matter in this case).
*/
message sentMsg;
sentMsg.mtype = RECV_DONE_TYPE;
std::cout<<"Ready for next file chunk"<<std::endl;
msgsnd(msqid,&sentMsg,0,0);
std::cout<<"Ready message sent"<<std::endl;
}
/* We are done */
else
{
/* Close the file */
fclose(fp);
}
}
}
void cleanUp(const int& shmid, const int& msqid, void* sharedMemPtr)
{
printf("Detaching from shared memory\n");
shmdt(sharedMemPtr);
printf("Deallocating shared memory chunk\n");
shmctl(shmid,IPC_RMID,NULL);
printf("deallocating message queue\n");
msgctl(msqid,IPC_RMID,NULL);
}
void ctrlCSignal(int signal)
{
/* Free system V resources */
cleanUp(shmid, msqid, sharedMemPtr);
}
int main(int argc, char** argv)
{
/* TODO: Install a signal handler
* In a case user presses Ctrl-c your program should delete message
* queues and shared memory before exiting. You may add the cleaning functionality
* in ctrlCSignal().
*/
signal(SIGINT, ctrlCSignal);
/* Initialize */
init(shmid, msqid, sharedMemPtr);
/* Go to the main loop */
mainLoop();
/** TODO: Detach from shared memory segment, and deallocate shared memory and message queue (i.e. call cleanup) **/
std::cout<<"Cleaning up"<<std::endl;
cleanUp(shmid, msqid, sharedMemPtr);
std::cout<<"Finished"<<std::endl;
return 0;
}

Related

EEPROM emulator on STM32L053

I known that isn't normal to use EEPROM emulator on a STM32L053, because it has is own EEPROM, but nowadays with the chip shortage, i was forcedto use an alternative MCU (STM32L053R8T6) instead of the "original design" (STM32F030C8T6), so i want to use the same code for both MCU, so the EEPROM emulator on the STM32L053R8T6.
But i'm having some difficulty using the EEPROM emulator on the STM32L053, the compiler didn't give any error, and the code run normmally, but didn't save any value to the EEPROM.
Header File:
#define ADDR_FLASH_PAGE_60 ((uint32_t)0x0800F000) /* Base # of Page 60, 1 Kbytes */
#define ADDR_FLASH_PAGE_61 ((uint32_t)0x0800F400) /* Base # of Page 61, 1 Kbytes */
#define ADDR_FLASH_PAGE_62 ((uint32_t)0x0800F800) /* Base # of Page 62, 1 Kbytes */
/* Define the size of the sectors to be used */
#define PAGE_SIZE (uint32_t) FLASH_PAGE_SIZE /* Page size */
/* EEPROM start address in Flash */
#define EEPROM_START_ADDRESS ((uint32_t) ADDR_FLASH_PAGE_60) /* EEPROM emulation start address */
/* Pages 0 and 1 base and end addresses */
#define PAGE0_BASE_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + 0x0000))
#define PAGE0_END_ADDRESS ((uint32_t)(EEPROM_START_ADDRESS + (PAGE_SIZE - 1)))
#define PAGE1_BASE_ADDRESS ((uint32_t)(ADDR_FLASH_PAGE_61))
#define PAGE1_END_ADDRESS ((uint32_t)(ADDR_FLASH_PAGE_61 + PAGE_SIZE - 1))
/* Used Flash pages for EEPROM emulation */
#define PAGE0 ((uint16_t) 0x0000)
#define PAGE1 ((uint16_t)((PAGE1_BASE_ADDRESS-PAGE0_BASE_ADDRESS)/PAGE_SIZE)) /* Virtual page nb between PAGE0_BASE_ADDRESS & PAGE1_BASE_ADDRESS*/
/* No valid page define */
#define NO_VALID_PAGE ((uint16_t)0x00AB)
/* Page status definitions */
#define ERASED ((uint16_t)0xFFFF) /* Page is empty */
#define RECEIVE_DATA ((uint16_t)0xEEEE) /* Page is marked to receive data */
#define VALID_PAGE ((uint16_t)0x0000) /* Page containing valid data */
/* Valid pages in read and write defines */
#define READ_FROM_VALID_PAGE ((uint8_t)0x00)
#define WRITE_IN_VALID_PAGE ((uint8_t)0x01)
/* Page full define */
#define PAGE_FULL ((uint8_t)0x80)
void EE_ReadData(void);
uint16_t EE_Init(void);
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data);
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data);
#endif /* __EEPROM_H */
EEPROM Write Variable Function:
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
{
uint16_t Status = 0;
/* Write the variable virtual address and value in the EEPROM */
Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
/* In case the EEPROM active page is full */
if (Status == PAGE_FULL)
{
/* Perform Page transfer */
Status = EE_PageTransfer(VirtAddress, Data);
}
/* Return last operation status */
return Status;
}

f_mount() returns FA_DISK_ERR

I have made few changes in my source code after suggestion form everyone.For connecting FATFS API with SPI interface i have followed this code..
https://github.com/eziya/STM32_SPI_SDCARD/blob/master/Src/fatfs_sd.c
and changed my user_diskio.c accordingly.
After doing all those things then also my SD Card returns FA_DISK_ERROR.
I have changed SD Card slot as well as SD Card. But nothing Changed.
My user_diskio.c look like this:
#include <string.h>
#include "ff_gen_drv.h"
#include "fatfs_sd.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Disk status */
static volatile DSTATUS Stat = STA_NOINIT;
/* USER CODE END DECL */
/* Private function prototypes -----------------------------------------------*/
DSTATUS USER_initialize (BYTE pdrv);
DSTATUS USER_status (BYTE pdrv);
DRESULT USER_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count);
#if _USE_WRITE == 1
DRESULT USER_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count);
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
DRESULT USER_ioctl (BYTE pdrv, BYTE cmd, void *buff);
#endif /* _USE_IOCTL == 1 */
Diskio_drvTypeDef USER_Driver =
{
USER_initialize,
USER_status,
USER_read,
#if _USE_WRITE
USER_write,
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
USER_ioctl,
#endif /* _USE_IOCTL == 1 */
};
/* Private functions ---------------------------------------------------------*/
/**
* #brief Initializes a Drive
* #param pdrv: Physical drive number (0..)
* #retval DSTATUS: Operation status
*/
DSTATUS USER_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
/* USER CODE BEGIN INIT */
return SD_disk_initialize(pdrv);
/* USER CODE END INIT */
}
/**
* #brief Gets Disk Status
* #param pdrv: Physical drive number (0..)
* #retval DSTATUS: Operation status
*/
DSTATUS USER_status (
BYTE pdrv /* Physical drive number to identify the drive */
)
{
/* USER CODE BEGIN STATUS */
return SD_disk_status(pdrv);
/* USER CODE END STATUS */
}
/**
* #brief Reads Sector(s)
* #param pdrv: Physical drive number (0..)
* #param *buff: Data buffer to store read data
* #param sector: Sector address (LBA)
* #param count: Number of sectors to read (1..128)
* #retval DRESULT: Operation result
*/
DRESULT USER_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to read */
)
{
/* USER CODE BEGIN READ */
return SD_disk_read(pdrv, buff, sector, count);
/* USER CODE END READ */
}
/**
* #brief Writes Sector(s)
* #param pdrv: Physical drive number (0..)
* #param *buff: Data to be written
* #param sector: Sector address (LBA)
* #param count: Number of sectors to write (1..128)
* #retval DRESULT: Operation result
*/
#if _USE_WRITE == 1
DRESULT USER_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address in LBA */
UINT count /* Number of sectors to write */
)
{
/* USER CODE BEGIN WRITE */
/* USER CODE HERE */
return SD_disk_write(pdrv, buff, sector, count);
/* USER CODE END WRITE */
}
#endif /* _USE_WRITE == 1 */
/**
* #brief I/O control operation
* #param pdrv: Physical drive number (0..)
* #param cmd: Control code
* #param *buff: Buffer to send/receive control data
* #retval DRESULT: Operation result
*/
#if _USE_IOCTL == 1
DRESULT USER_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
/* USER CODE BEGIN IOCTL */
return SD_disk_ioctl(pdrv, cmd, buff);
/* USER CODE END IOCTL */
}
#endif /* _USE_IOCTL == 1 */
and fatfs_sd.c looks like this:
GO TO THE ABOVE GITHUB LINK
Have no idea where i am going wrong.
Anything on this topic will be helpful.
Thanks in advance.
I've written my own driver using an stm32f7 chip for FatFS before and think I might know what's going on. My guess is that you likely forgot to attach implementations for the disk_write and disk_read functions in diskio.h. Without doing that, the FatFS library has no clue on how to actually interface with the SD card.
You could check out the FatFS documentation/manual as a general resource: here
Pay very close attention to the "Required Functions" section in this app note: here
An example project like yours but for STM32F4: here

CMSIS UART driver for Tiva launchpad

I'm trying to make the CMSIS UART driver example work on my Tiva launchpad: https://www.keil.com/pack/doc/CMSIS/Driver/html/group__usart__interface__gr.html
My code is the following:
#include "Driver_USART.h"
#include <cmsis_os.h> /* ARM::CMSIS:RTOS:Keil RTX */
#include <stdio.h>
#include <string.h>
/* USART Driver */
extern ARM_DRIVER_USART Driver_UART0;
void myUART_Thread(void const *argument);
osThreadId tid_myUART_Thread;
void myUSART_callback(uint32_t event)
{
switch (event)
{
case ARM_USART_EVENT_RECEIVE_COMPLETE:
case ARM_USART_EVENT_TRANSFER_COMPLETE:
case ARM_USART_EVENT_SEND_COMPLETE:
case ARM_USART_EVENT_TX_COMPLETE:
/* Success: Wakeup Thread */
osSignalSet(tid_myUART_Thread, 0x01);
break;
case ARM_USART_EVENT_RX_TIMEOUT:
__breakpoint(0); /* Error: Call debugger or replace with custom error handling */
break;
case ARM_USART_EVENT_RX_OVERFLOW:
case ARM_USART_EVENT_TX_UNDERFLOW:
__breakpoint(0); /* Error: Call debugger or replace with custom error handling */
break;
}
}
/* CMSIS-RTOS Thread - UART command thread */
void myUART_Thread(const void* args)
{ // static ARM_DRIVER_USART * USARTdrv = &Driver_UART0;
ARM_DRIVER_VERSION version;
ARM_USART_CAPABILITIES drv_capabilities;
char cmd;
/*Initialize the USART driver */
Driver_UART0.Initialize(myUSART_callback);
/*Power up the USART peripheral */
Driver_UART0.PowerControl(ARM_POWER_FULL);
/*Configure the USART to 4800 Bits/sec */
Driver_UART0.Control(ARM_USART_MODE_ASYNCHRONOUS |
ARM_USART_DATA_BITS_8 |
ARM_USART_PARITY_NONE |
ARM_USART_STOP_BITS_1 |
ARM_USART_FLOW_CONTROL_NONE, 4800);
/* Enable Receiver and Transmitter lines */
Driver_UART0.Control (ARM_USART_CONTROL_TX, 1);
Driver_UART0.Control (ARM_USART_CONTROL_RX, 1);
Driver_UART0.Send("\nPress Enter to receive a message", 34);
osSignalWait(0x01, osWaitForever);
while (1)
{
Driver_UART0.Receive(&cmd, 1); /* Get byte from UART */
osSignalWait(0x01, osWaitForever);
if (cmd == 13) /* CR, send greeting */
{
Driver_UART0.Send("\nHello World!", 12);
osSignalWait(0x01, osWaitForever);
}
}
}
int main(void){
osKernelInitialize (); // initialize CMSIS-RTOS
osKernelStart (); // start thread execution
}
Now I don't expect it to work right away, however my builder starts complaining at the linkig phase that Driver_UART0 is undefined:
.\Objects\bl.axf: Error: L6218E: Undefined symbol Driver_UART0 (referred from blinky.o).
Any idea what I could do to fix this?
Thank you,
Botond
Unfortunately TI doesn't support the CMSIS Driver API at this time. I've have been working on creating this API on my own and have a working example in my GitHub repository:
This is the example:
https://github.com/AllAboutEE/ARM-Programming-Examples-TM4C/blob/master/CMSIS-Driver-Examples/UART-CMSIS-Driver/main.c
You'll have to set your include path in project options to this folder:
https://github.com/AllAboutEE/ARM-Programming-Examples-TM4C/tree/master/inc
Also add the files in this folder to your project:
https://github.com/AllAboutEE/ARM-Programming-Examples-TM4C/tree/master/src
and also this file
https://github.com/AllAboutEE/ARM-Programming-Examples-TM4C/blob/master/startup_LM4F.s

TMS320F2812 FatFs f_write returns FR_DISK_ERR

I have problem with an SD card. I'm using the FatFs library ver R0.10b to access the SD card.
My code:
// .... //
FATFS fatfs;
FIL plik;
FRESULT fresult,res1,res2,res3,res4,res5;
UINT zapisanych_bajtow = 0 , br;
UINT zapianie_bajtow = 0;
char * buffor = "123456789abcdef\r\n";
unsigned short int i;
void main(void) {
// ... //
res1 = f_mount(0,&fatfs); // returns FA_OK
res2 = f_open( &plik, "f721.txt", FA_OPEN_ALWAYS | FA_WRITE ); // returns FA_OK
if( res2 == FR_OK )
{
res3 = f_write( &plik, ( const void * ) buffor, 17, &zapisanych_bajtow ); // returns FR_DISK_ERR
}
res4 = f_close( &plik );// returns FR_DISK_ERR
for(;;)
{
}
}
Any idea what might be wrong?
I had similar error with just one difference. I tried to write 4096bytes with f_write function at once. And it always returned FR_DISK_ERR.
And this was caused because I tried to write more then is size of IO buffer in FIL structure in FatFS (defined in ff.h).
typedef struct {
FATFS* fs; /* Pointer to the related file system object (**do not change order**) */
WORD id; /* Owner file system mount ID (**do not change order**) */
BYTE flag; /* Status flags */
BYTE err; /* Abort flag (error code) */
DWORD fptr; /* File read/write pointer (Zeroed on file open) */
DWORD fsize; /* File size */
DWORD sclust; /* File start cluster (0:no cluster chain, always 0 when fsize is 0) */
DWORD clust; /* Current cluster of fpter (not valid when fprt is 0) */
DWORD dsect; /* Sector number appearing in buf[] (0:invalid) */
DWORD dir_sect; /* Sector number containing the directory entry */
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] */
DWORD* cltbl; /* Pointer to the cluster link map table (Nulled on file open) */
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
BYTE buf[_MAX_SS]; /* File private data read/write window */
} FIL;
The last array buf[_MAX_SS] is the file IO buffer. But _MAX_SS is user defined parameter (defined in ff.h) so you can decrease the amount of bytes written at once or eventually change the _MAX_SS value.
I know this is not your case because you only write 17 bytes at once, but this can be helpful for others.
It's few years when I finished with TMS but maybe it will help you:
FA_OPEN_ALWAYS Opens the file if it is existing. If not, a new file is created.
To append data to the file, use f_lseek() function after file open in this method.
If file does not exists use:
FA_CREATE_NEW Creates a new file. The function fails
with FR_EXIST if the file is existing.
I had the same issue with implementation of Chan FatFs on MSP430- always received FR_DISK_ERR result on calling disk_write().
My reason of the issue was the following:
operation failed on xmit_datablock() call, it returned 0.
xmit_datablock() failed because of xmit_spi_multi() failed.
xmit_spi_multi() failed because it was not enough to just transmit bytes from buffer.
It was necessary to read from RXBUF after every write.
Here it is how it looks after the issue was fixed:
/* Block SPI transfers */
static void xmit_spi_multi (
const BYTE* buff, /* Data to be sent */
UINT cnt /* Number of bytes to send */
)
{
do {
volatile char x;
UCA1TXBUF= *buff++; while(! (UCA1IFG & UCRXIFG)) ; x = UCA1RXBUF;
UCA1TXBUF= *buff++; while(! (UCA1IFG & UCRXIFG)) ; x = UCA1RXBUF;
} while (cnt -= 2);
}
Before fixing the issue there was no read from UCA1RXBUF following every write to UCA1TXBUF.
After fixing xmit_spi_multi() my issue with FR_DISK_ERR in disk_write() was solved.

Undeclared identifiers (C-mex S-Functions)

I understand that this is a very common problem that a lot is facing. however I don't understand how to link to my program. It's a simple c = a+b program. I have the following as my C-Mex S-function:
#define S_FUNCTION_NAME Addition
#define S_FUNCTION_LEVEL 2
#include "simstruc.h"
static void mdlInitializeSizes(SimStruct *S)
{
int_T nInputPorts = 2; /* Set no. of input ports */
int_T nOutputPorts = 1; /* Set no. of output ports */
int_T needsInput = 1; /* Direct feed through = yes */
int_T inputPortIdx = 0;
int_T outputPortIdx = 0;
ssSetNumSFcnParams(S, 0);
if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S))
{
return; /* If no. of expected input parameters is not equal to no.
of parameters entered in dialog box, return. Simulink
to generate an error indicating parameter mismatched */
}
/* Configure input ports */
if (!ssSetNumInputPorts(S, 2)) return;
/* Configure first input ports */
ssSetInputPortWidth(S, 0, DYNAMICALLY_SIZED); /* Set dimensions of first input port */
ssSetInputPortDirectFeedThrough(S, 0, 1); /* Set direct feed through */
/* Configure second input ports */
ssSetInputPortWidth(S, 1, DYNAMICALLY_SIZED); /* Set dimensions of second input port */
ssSetInputPortDirectFeedThrough(S, 1, 1); /* Set direct feed through */
/* Configure output ports */
if (!ssSetNumOutputPorts(S,1)) return;
ssSetOutputPortWidth(S, 0, DYNAMICALLY_SIZED); /* Set dimensions of output ports */
ssSetNumSampleTimes(S, 1); /* Set no. of sample times */
ssSetSimStateCompliance(S, USE_DEFAULT_SIM_STATE);
ssSetOptions (S,0);
} /* End of mdlInitializeSizes */
static void mdlInitializeSampleTimes (SimStruc *S)
{
ssSetSampleTimes(S, 0, INHERITED_SAMPLE_TIME);
/* Inherited Sample time: S-function block executes whenever driving block executes */
ssSetOffsetTime(S, 0, 0.0); /* No offset required */
ssSetModelReferenceSampleTimeDefaultInheritance(S); /* */
} /* End of mdlInitializeSampleTime */
static void mdlOutputs (SimStruc *S, int_T tid)
{
int_T i;
InputRealPtrsType uPtrs = ssGetInputPortRealSignalPtrs(S,0);
real_T *y = ssGetOutputPortRealSignal(S,0);
int_T width = ssGetOutputPortWidth(S,0);
for (i=0; i<width; i++) /* i = location of memory. from 0 to 1. */
{
*y++ = (*uPtrs[i+1]) + (*uPtrs[i]); /* c = a + b */
}
} /* End of mdlOutputs */
static void mdlTerminate(SimStruct *S)
{
/* No task to be perform at end of simulation therefore no termination required.
But this is a compulsory function to have for C-mex S-function */
} /* End of mdlTerminate */
#ifdef MATLAB_MEX_FILE
#include "simulink.c"
#else
#include "cg_sfun.h"
#endif
however when compiling on matlab, i keep getting the following error:
Addition.c:47: error: expected ‘)’ before ‘*’ token
Addition.c:56: error: expected ‘)’ before ‘*’ token
In file included from Addition.c:82:
/DIST/it/sw/amd64/matlab/r2010b/simulink/include/simulink.c: In function ‘_ProcessMexSfunctionCmdLineCall’:
/DIST/it/sw/amd64/matlab/r2010b/simulink/include/simulink.c:2545: error: ‘mdlInitializeSampleTimes’ undeclared (first use in this function)
/DIST/it/sw/amd64/matlab/r2010b/simulink/include/simulink.c:2545: error: (Each undeclared identifier is reported only once
/DIST/it/sw/amd64/matlab/r2010b/simulink/include/simulink.c:2545: error: for each function it appears in.)
/DIST/it/sw/amd64/matlab/r2010b/simulink/include/simulink.c:2601: error: ‘mdlOutputs’ undeclared (first use in this function)
Any comments will be greatly appreciated!
You misspelled SimStruct in the two lines mentioned at the top of your error message. That error about the parentheses means that the compiler doesn't know that SimStruc is a type, so the * doesn't fit. After that, those two functions aren't defined, so the simulink interface gets upset that it can't find those two required functions in your file.