How do I fix a DDE SAS unrecoverable error? - sas

I have a script that opens Excel, opens a Shell, exports to excel and then saves. I get the following error:
ERROR: DDE session not ready.
FATAL: Unrecoverable I/O error detected in the execution of the DATA step program.
Aborted during the EXECUTION phase.
And have not been able to identify if the cause is truly the DDE or not.
I have tried switching the Excel|system to particular cells. I've tried copying and pasting exactly from another script that works. I've tried adding a pause for excel. I've also tried this on both a windows 10 machine and windows 7 lab computer.
proc sort nodupkey data=output2.SUMM2 out=output2.summary_rc (keep=refcirc);
by refcirc;
run;
proc sql;
create table output2.rc_driver as
select distinct s.refcirc,
put(s.refcirc,3.) || "_" || rc.PCP_RCIRC_desc
as prefix,
rc.PCP_RCIRC_desc as entity_name
from output2.summary_rc as s
inner join output2.ref_circ_data as rc
on s.refcirc = rc.PCP_RCIRC_CD
order by refcirc;
quit;
/* -------------------------------------------------------------------- */
/* */
/* Get the number of observations/loop counter. */
/* */
/* -------------------------------------------------------------------- */
%let dptr=%sysfunc(open(output2.rc_driver));
%let nobs=%sysfunc(attrn(&dptr,nobs));
%let dcls=%sysfunc(close(&dptr));
/* -------------------------------------------------------------------- */
/* */
/* Build an array for the referral circle and identifiers. */
/* */
/* -------------------------------------------------------------------- */
data _null_;
set output2.rc_driver;
num = _N_;
m_rccode = 'rccode' || trim(left(num));
call symput(m_rccode,trim(left(refcirc)));
m_entity = 'entity' || trim(left(num));
call symput(m_entity,trim(left(entity_name)));
m_prefix = 'prefix' || trim(left(num));
call symput(m_prefix,trim(left(prefix)));
run;
/* -------------------------------------------------------------------- */
/* */
/* Open Excel for DDE. */
/* */
/* -------------------------------------------------------------------- */
;
%macro OpenXL;
options noxwait noxsync missing=' ';
filename sas2xl dde 'excel|system';
data _null_;
length fid rc start stop time 8;
fid=fopen('sas2xl','s');
if (fid le 0) then do;
rc=system('start excel');
start=datetime();
stop=start+10;
do while (fid le 0);
fid=fopen('sas2xl','s');
time=datetime();
if (time ge stop) then fid=1;
end;
end;
rc=fclose(fid);
run;
%mend;
/* -------------------------------------------------------------------- */
/* */
/* Open the template spreadsheet. */
/* */
/* -------------------------------------------------------------------- */
%macro OpenShell;
filename cmds dde 'excel|system';
data _null_;
file cmds;
put '[error(false)]'; /*This suppresses errors that may occur if Excel is already open*/
put '[open("W:\PI\AQC_Reporting_Production_Process\01 Quarterly_Reporting\Labreports\QEDM-Lab_Utilization_Quarterly\Excel Shell\Lab_Summary_shell_v3.xls")]';
put '[workbook.insert(3)]' ;
put '[workbook.delete("Macro1")]';
run;
%mend;
/* -------------------------------------------------------------------- */
/* */
/* This macro writes the summary tab report. */
/* */
/* -------------------------------------------------------------------- */
%macro write_summary(rccode, entity, prefix, sheetname);
filename data dde "excel|&sheetname!r1c1:r7c1" notab;
/* */
/* Fill in the heading of the summary tab report. */
/* */
/* -------------------------------------------------------------------- */
data _null_;
set output2.summ2;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
put "Blue Cross and Blue Shield of Massachusetts";
put;
put "&entity";
put "Top 10 Non-Quest Diagnostic Laboratories";
put;
put "Incurred Period &dateStart. - &dateEndIncur.";
put "Processed Period &dateStart. - &dateEndProcess.";
run;
/* -------------------------------------------------------------------- */
/* */
/* Fill in the data of the summary tab report. */
/* */
/* -------------------------------------------------------------------- */
filename data dde "excel|&sheetname!r10c1:r60c7" notab;
data _null_;
set output2.summ2;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
put provname '09'x
units '09'x
unit_pct '09'x
paidx '09'x
paidx_pct '09'x
billed_amt '09'x ;
run;
%mend;
/* -------------------------------------------------------------------- */
/* THERE IS MORE CODE DELETED HERE TO SUBMIT. */
/* */
/* This macro writes the detail by Analysis tab report. */
/* */
/* -------------------------------------------------------------------- */
%macro write_analysis(rccode, entity, prefix, sheetname);
filename data dde "excel|&sheetname!r6c1:r10c1" notab;
/* -------------------------------------------------------------------- */
/* */
/* Fill in the heading of the analysis tab report. */
/* */
/* -------------------------------------------------------------------- */
data _null_;
set output2.summ2;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
put "Blue Cross and Blue Shield of Massachusetts";
put "&entity";
put "Incurred Period &dateStart. - &dateEndIncur.";
put "Processed Period &dateStart. - &dateEndProcess.";
put "Diagnostic Laboratory Comparison Summary";
run;
/* -------------------------------------------------------------------- */
/* */
/* Populate table of the analysis tab report. */
/* */
/* -------------------------------------------------------------------- */
filename data dde "excel|&sheetname!r20c3:r23c6" notab;
data _null_;
set output2.savings;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
put units '09'x
paidx '09'x
dol_unit '09'x
savings '09'x ;
run;
/* -------------------------------------------------------------------- */
/* */
/* Create macro variables of the analysis tab report. */
/* */
/* -------------------------------------------------------------------- */
filename data dde "excel|&sheetname!r28c2:r41c2" notab;
data _null_;
set output2.summ2;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
/* -------------------------------------------------------------------- */
/* */
/* Bullet 1 macro variables. */
/* */
/* -------------------------------------------------------------------- */
if provname='TOTAL TOP 10 (NON-QUEST) LAB UTILIZATION' then do;
call symput("bullet1a", trim(left(put(unit_pct,percent12.1))));
end;
if provname='TOTAL TOP 10 (NON-QUEST) LAB UTILIZATION' then do;
call symput("bullet1b", trim(left(put(paidx_pct,percent12.1))));
end;
/* -------------------------------------------------------------------- */
/* */
/* Bullet 2 macro variables. */
/* */
/* -------------------------------------------------------------------- */
if RankFacProv=1 then do;
call symput("bullet2a", trim(left(provname)));
end;
if RankFacProv=1 then do;
call symput("bullet2b", trim(left(put(unit_pct,percent12.1))));
end;
if RankFacProv=1 then do;
call symput("bullet2c", trim(left(put(paidx_pct,percent12.1))));
end;
if RankFacProv=1 then do;
call symput("bullet2d", trim(left(put(dol_unit,dollar8.2))));
end;
/* -------------------------------------------------------------------- */
/* */
/* Bullet 3 macro variables. */
/* */
/* -------------------------------------------------------------------- */
if RankFacProv=2 then do;
call symput("bullet3a", trim(left(provname)));
end;
if RankFacProv=2 then do;
call symput("bullet3b", trim(left(put(unit_pct,percent12.1))));
end;
if RankFacProv=2 then do;
call symput("bullet3c", trim(left(put(paidx_pct,percent12.1))));
end;
if RankFacProv=2 then do;
call symput("bullet3d", trim(left(put(dol_unit,dollar8.2))));
end;
run;
/* -------------------------------------------------------------------- */
/* */
/* Build bullet 4 macro variables. */
/* */
/* -------------------------------------------------------------------- */
data _null_;
set output2.remaining_8_final;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
if RankFacProv=999 then do;
call symput("bullet4a", trim(left(put(unit_pct,percent12.1))));
end;
if RankFacProv=999 then do;
call symput("bullet4b", trim(left(put(paidx_pct,percent12.1))));
end;
run;
/* -------------------------------------------------------------------- */
/* */
/* Get data except for the total for the top 10. */
/* */
/* -------------------------------------------------------------------- */
data output2.sort1;
set output2.remaining_8_final;
if RankFacProv ne 999;
run;
/* -------------------------------------------------------------------- */
/* */
/* Sort by referral circle and by most expensive $/service unit. */
/* */
/* -------------------------------------------------------------------- */
proc sort data=output2.sort1;
by refcirc descending dol_unit;
run;
/* -------------------------------------------------------------------- */
/* */
/* Get the current referral circle and then the most expensive */
/* $/service unit. Build bullet 4c macro variables. */
/* */
/* -------------------------------------------------------------------- */
data _null_;
set output2.sort1;
by refcirc;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
if first.refcirc;
file data lrecl=1000 stopover;
call symput("bullet4c", trim(left(provname)));
run;
/* -------------------------------------------------------------------- */
/* */
/* Get the current referral circle and then the most expensive */
/* $/service unit. Build bullet 4d macro variables. */
/* */
/* -------------------------------------------------------------------- */
data _null_;
set output2.sort1;
by refcirc;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
if first.refcirc;
file data lrecl=1000 stopover;
call symput("bullet4d", trim(left(put(dol_unit,dollar8.2))));
run;
/* -------------------------------------------------------------------- */
/* */
/* Get data execpt for the total for the top 10. */
/* */
/* -------------------------------------------------------------------- */
data output2.sort2;
set output2.remaining_8_final;
if RankFacProv ne 999;
run;
/* -------------------------------------------------------------------- */
/* */
/* Sort by referral circle and by least expensive $/service unit. */
/* */
/* -------------------------------------------------------------------- */
proc sort data=output2.sort2;
by refcirc dol_unit;
run;
/* -------------------------------------------------------------------- */
/* */
/* Get the current referral circle and then the least expensive */
/* $/service unit. Build bullet 4e macro variables. */
/* */
/* -------------------------------------------------------------------- */
data _null_;
set output2.sort2;
by refcirc;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
if first.refcirc;
file data lrecl=1000 stopover;
call symput("bullet4e", trim(left(provname)));
run;
/* -------------------------------------------------------------------- */
/* */
/* Get the current referral circle and then the least expensive */
/* $/service unit. Build bullet 4f macro variables. */
/* */
/* -------------------------------------------------------------------- */
data _null_;
set output2.sort2;
by refcirc;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
if first.refcirc;
file data lrecl=1000 stopover;
call symput("bullet4f", trim(left(put(dol_unit,dollar8.2))));
run;
/* -------------------------------------------------------------------- */
/* */
/* Build bullet 5 macro variables. */
/* */
/* -------------------------------------------------------------------- */
data _null_;
set output2.summ_phys1;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
if RankPhysProv=999 then do;
call symput("bullet5a", trim(left(put(unit_pct,percent12.1))));
end;
run;
/* -------------------------------------------------------------------- */
/* */
/* Build bullet 6 macro variables. */
/* */
/* -------------------------------------------------------------------- */
data _null_;
set output2.summ2;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
if RankFacProv=9999 then do;
call symput("bullet6a", trim(left(put(unit_pct,percent12.1))));
end;
if RankFacProv=9999 then do;
call symput("bullet6b", trim(left(put(paidx_pct,percent12.1))));
end;
run;
/* -------------------------------------------------------------------- */
/* */
/* Create dynamic text. */
/* */
/* -------------------------------------------------------------------- */
/* */
/* Use macro bullets 1-3. */
/* */
/* -------------------------------------------------------------------- */
filename data dde "excel|&sheetname!r28c2:r33c2" notab;
data _null_;
set output2.SUMM2;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
put "The Top 10 Providers represent a total of &bullet1a of diagnostic laboratory services for the Group's"
/ "members and &bullet1b of cost."
/ "&bullet2a is the highest service provider with &bullet2b of services"
/ "representing &bullet2c of cost. Unit cost is &bullet2d.."
/ "&bullet3a is the second largest service provider with &bullet3b of services"
/ "representing &bullet3c of cost. Unit cost is &bullet3d..";
run;
/* -------------------------------------------------------------------- */
/* */
/* Use macro bullets 4. */
/* */
/* -------------------------------------------------------------------- */
filename data dde "excel|&sheetname!r34c2:r35c2" notab;
data _null_;
set output2.remaining_8_final;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
put "The next 8 providers represent a total of &bullet4a of services and &bullet4b of cost. The highest cost provider is"
/ "&bullet4c at &bullet4d while &bullet4e is the lowest at &bullet4f..";
run;
/* -------------------------------------------------------------------- */
/* */
/* Use macro bullets 5. */
/* */
/* -------------------------------------------------------------------- */
filename data dde "excel|&sheetname!r36c2:r36c2" notab;
data _null_;
set output2.summ_phys1;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
put "The Top 10 Physician Office Laboratories performed &bullet5a of all physician office lab services.";
run;
/* -------------------------------------------------------------------- */
/* */
/* Use macro bullets 6. */
/* */
/* -------------------------------------------------------------------- */
filename data dde "excel|&sheetname!r41c2:r41c2" notab;
data _null_;
set output2.summ2;
if refcirc="&rccode" /*and referral_circle_desc=&rcdesc*/ ;
file data lrecl=1000 stopover;
put "Quest provided a total of &bullet6a of laboratory services for the Group's members at &bullet6b of total cost.";
run;
%mend;
/* -------------------------------------------------------------------- */
/* */
/* This macro writes the report spreadsheets. */
/* */
/* -------------------------------------------------------------------- */
%macro run_data;
%OpenXL;
%do i=1 %to &&nobs;
%OpenShell;
%write_summary(&&rccode&i, &&entity&i, &&prefix&i, Summary);
/* %write_summary_fs(&&rccode&i, &&entity&i, &&prefix&i, Summary Free Standing);*/
/* %write_summary_fac(&&rccode&i, &&entity&i, &&prefix&i, Summary Facility);*/
%write_detail_by_pcp(&&rccode&i, &&entity&i, &&prefix&i, Detail_by_PCP);
%write_detail_by_lab(&&rccode&i, &&entity&i, &&prefix&i, Detail_by_Lab);
%write_summary_PhysOffLabs(&&rccode&i, &&entity&i, &&prefix&i, Physician_Office_Labs);
%write_analysis(&&rccode&i, &&entity&i, &&prefix&i, Analysis);
%let saveAsCmdVar = [save.as("W:\PI\AQC_Reporting_Production_Process\01 Quarterly_Reporting\Labreports\Shields MRI Reporting\&quarter2.&ytd.\final reports new\&&prefix&i.._Lab_Summary_&quarter2.._TEST.xls")];
/* -------------------------------------------------------------------- */
/* */
/* Save and close. */
/* */
/* -------------------------------------------------------------------- */
filename cmds dde "excel | system";;
data _null_;
file cmds;
x= sleep(10);
put '[error(false)]';
put %unquote(%str(%'&saveAsCmdVar%'));
put '[close()]';
run;
data _null_;
rc = sleep(10);
run;
%end;
/* -------------------------------------------------------------------- */
/* */
/* End DDE. */
/* */
/* --------------------------------------------------------ear------------ */
data _null_;
file cmds;
put '[quit()]';
run;
%mend;
/* -------------------------------------------------------------------- */
/* */
/* Build all reports on the non-molecular "side." */
/* */
/* -------------------------------------------------------------------- */
%run_data;
/*** ---------------------- END PROGRAM ---------------------------------- ***;
************** **** ** *****
************** ** ** ** ** **
** ** ** ** ** **
** ** ** ** ** **
** ** ** ** ** **
************** ** ** ** ** **
************** ** ** ** ** **
** ** ** ** ** **
** ** ** ** ** **
** ** ** ** ** **
************** ** ** ** ** **
************** ** **** *****
*** ---------------------- END PROGRAM ---------------------------------- ***;
Expected results is several tabs of Excel for each referral circle (rc) that save to the location identified. None save.
Error repeats several times as follows:
NOTE: There were 336 observations read from the data set OUTPUT2.SUMM2.
NOTE: DATA statement used (Total process time):
real time 0.03 seconds
cpu time 0.00 seconds
NOTE: The file CMDS is:
DDE Session,
SESSION=excel | system,RECFM=V,LRECL=32767
ERROR: DDE session not ready.
FATAL: Unrecoverable I/O error detected in the execution of the DATA step program.
Aborted during the EXECUTION phase.

Related

The adc should be able to work well for this kind of applications?

I've been trying to process speech on a stm32f407ve development board for some time now, which makes me wonder if the ADC is really set up to precisely sample the values. CMSIS FFT Functions. But when I try to couple it with the ADC in continuous conversion to sample a sine signal, it doesn't seem to sample well periodically. I put a sine signal into it from a frequency test of a 1khz sine wave from an internet video with a plug that I take out of some headphones, which by the way I already tested that it works correctly with an oscilloscope. So... this one from the development board is obviously not from a DSP but its ADC should work correctly for this type of application? Here is my code, obviously I made sure that the test was emitting voltage before the debug.
#include "main.h"
#include "arm_math.h"
#include "arm_const_structs.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define Fs 4096;
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
/* USER CODE BEGIN PV */
#define SIGNAL_BUFFER_LENGTH 4096
float signalBuffer[2*SIGNAL_BUFFER_LENGTH];
float fftBuffer[2*SIGNAL_BUFFER_LENGTH];
float magnitudes[SIGNAL_BUFFER_LENGTH];
/* USER CODE END PV */
uint32_t k;
uint32_t cont1,cont2;
uint32_t start;
uint32_t stopi;
uint32_t delta;
float32_t maxValue; /* Max FFT value is stored here */
uint32_t maxIndex;
float frecuencia=10.0;
float32_t Ts;
float tiempo;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
* #retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
#define ARM_CM_DEMCR (*(uint32_t*)0xE000EDFC)
#define ARM_CM_DWT_CTRL (*(uint32_t*)0xE0001000)
#define ARM_CM_DWT_CYCCNT (*(uint32_t*)0xE0001004)
if(ARM_CM_DWT_CTRL !=0){
ARM_CM_DEMCR |= 1<<24;
ARM_CM_DWT_CYCCNT =0;
ARM_CM_DWT_CTRL |= 1<<0;
}
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
Ts=1.0/(float)Fs;
HAL_ADC_Start(&hadc1);
for(k=0;k<2*SIGNAL_BUFFER_LENGTH;k+=2 )
{
signalBuffer[k]=HAL_ADC_GetValue(&hadc1);
}
k++;
//signalBuffer[0]=0;
//start= ARM_CM_DWT_CYCCNT;
arm_cfft_f32(&arm_cfft_sR_f32_len4096,signalBuffer,0,1);
signalBuffer[0]=0;
arm_cmplx_mag_f32(signalBuffer,magnitudes,4096);
arm_max_f32(magnitudes, 4096, &maxValue, &maxIndex);
//stopi = ARM_CM_DWT_CYCCNT;
//delta=stopi-start;
//tiempo=delta/8.0E07*1000.0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
You are just calling the function to take a single reading over and over in a loop. There is no reason to think that each pass through this loop will take the same amount of time. You need to set the ADC to be triggered from a timer in order to have some kind of reproducible sample rate.
In general the internal ADC is not of suitable quality for audio use. There is an external audio codec fitted to this board, look at the example projects in the Stm32CubeF4 package.

Image acquisition with buffer (Matrox)

I'm new to programming with Matrox (MIL) and C++. I've been wanting to use a camera to its limit (120 Hz frame rate). I'm currently using MIL through Microsoft Visual Studio to program the camera. How my program works currently is using MdigProcess to acquire and save each image using a separate function. However, this slows down the camera to roughly 10Hz since it calls the function every time the to save the image in a buffer when it is ready. If I don't save the images, then the camera works fine. But I won't have any data :/
I am thinking of having the images (100 images for now) in the buffers first once, then save them. Is there a way to do that? Here is my attempt:
#include <mil.h>
#include <stdlib.h>
/* Number of images in the buffering grab queue.
Generally, increasing this number gives a better real-time grab.
*/
#define BUFFERING_SIZE_MAX 5
/* User's processing function prototype. */
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void*
HookDataPtr);
/* User's processing function hook data structure. */
typedef struct
{
MIL_ID MilDigitizer;
MIL_ID MilImageDisp;
MIL_INT ProcessedImageCount;
} HookDataStruct;
/* Main function. */
/* ---------------*/
int MosMain(void)
{
MIL_ID MilApplication;
MIL_ID MilSystem;
MIL_ID MilDigitizer;
MIL_ID MilDisplay; /* Display identifier. */
MIL_ID MilImageDisp; /* Display Image buffer identifier. */
MIL_ID MilGrabBufferList[BUFFERING_SIZE_MAX] = { 0 };
MIL_INT MilGrabBufferListSize;
MIL_INT ProcessFrameCount = 0, ProcessFrameMissed = 0, ProcessFrameCorrupted = 0;
MIL_DOUBLE ProcessFrameRate = 0;
MIL_DOUBLE FrameRate; // Initializes the FrameRate variable as double
HookDataStruct UserHookData;
MappAlloc(M_NULL, M_DEFAULT, &MilApplication); /* This initializes the MIL library. M_NULL means no cluster manager will be used. M_DEFAULT means reported error message will be displayed. */
MsysAlloc(M_SYSTEM_RAPIXOCL, M_DEFAULT, M_DEFAULT, &MilSystem); /* This allocates a MIL system*/
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, &MilDisplay); /* M_WINDOWED means it will display at a separate window*/
MdigAlloc(MilSystem, M_DEV0, MIL_TEXT("C:\\Users\\fluids-student\\Documents\\JAI 5000 PMCL.dcf"), M_DEFAULT, &MilDigitizer);
/* Allocate a monochrome display buffer. */
MbufAlloc2d(MilSystem, 2560, 2048, 8 + M_UNSIGNED, M_IMAGE + M_DISP + M_GRAB + M_PROC, &MilImageDisp);
MbufClear(MilImageDisp, M_BLACK);
/* Display the image buffer. */
MdispSelect(MilDisplay, MilImageDisp);
/* This inquires the frame rate */
MdigInquire(MilDigitizer, M_SELECTED_FRAME_RATE, &FrameRate);
MosPrintf(MIL_TEXT("The frame rate is # %0.2f fps.\n"), FrameRate);
/* Print a message. */
MosPrintf(MIL_TEXT("\nMULTIPLE BUFFERED PROCESSING.\n"));
MosPrintf(MIL_TEXT("-----------------------------\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to start acquisition.\n\n"));
/* Grab continuously on the display and wait for a key press. */
MdigGrabContinuous(MilDigitizer, MilImageDisp);
MosGetch();
/* Halt continuous grab. */
MdigHalt(MilDigitizer);
/* Allocate the grab buffers and clear them. */
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
for (MilGrabBufferListSize = 0; MilGrabBufferListSize < BUFFERING_SIZE_MAX;
MilGrabBufferListSize++)
{
MbufAlloc2d(MilSystem,
MdigInquire(MilDigitizer, M_SIZE_X, M_NULL),
MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL),
8L + M_UNSIGNED,
M_IMAGE + M_GRAB + M_PROC,
&MilGrabBufferList[MilGrabBufferListSize]);
if (MilGrabBufferList[MilGrabBufferListSize])
MbufClear(MilGrabBufferList[MilGrabBufferListSize], 0xFF);
else
break;
}
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
/* Initialize the user's processing function data structure. */
UserHookData.MilDigitizer = MilDigitizer;
UserHookData.MilImageDisp = MilImageDisp;
UserHookData.ProcessedImageCount = 0;
/* Start the processing. The processing function is called with every frame grabbed. */
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
M_SEQUENCE + M_COUNT(100), M_DEFAULT, ProcessingFunction, &UserHookData);
/* Here the main() is free to perform other tasks while the processing is executing. */
/* --------------------------------------------------------------------------------- */
/* Stop the processing. */
MdigProcess(MilDigitizer, MilGrabBufferList, MilGrabBufferListSize,
M_STOP, M_DEFAULT, ProcessingFunction, &UserHookData);
/* Print statistics. */
MdigInquire(MilDigitizer, M_PROCESS_FRAME_COUNT, &ProcessFrameCount);
MdigInquire(MilDigitizer, M_PROCESS_FRAME_RATE, &ProcessFrameRate);
MdigInquire(MilDigitizer, M_PROCESS_FRAME_MISSED, &ProcessFrameMissed);
MdigInquire(MilDigitizer, M_PROCESS_FRAME_CORRUPTED, &ProcessFrameCorrupted);
MosPrintf(MIL_TEXT("\n\n%d frames grabbed at %.1f frames/sec (%.1f ms/frame).\n"),
(int)ProcessFrameCount, ProcessFrameRate, 1000.0 / ProcessFrameRate);
MosPrintf(MIL_TEXT("%ld frames missed.\n"), ProcessFrameMissed);
MosPrintf(MIL_TEXT("%ld frames corrupted.\n"), ProcessFrameCorrupted);
MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n"));
MosPrintf(MIL_TEXT("BufferListSize = %d\n"), MilGrabBufferListSize);
MosGetch();
/* Free the grab buffers. */
while (MilGrabBufferListSize > 0)
MbufFree(MilGrabBufferList[--MilGrabBufferListSize]);
/* Free display buffer. */
MbufFree(MilImageDisp);
/* Release defaults. */
MdigFree(MilDigitizer);
MdispFree(MilDisplay);
MsysFree(MilSystem);
MappFree(MilApplication);
return 0;
}
/* User's processing function called every time a grab buffer is ready. */
/* -------------------------------------------------------------------- */
/* Local defines. */
#define STRING_LENGTH_MAX 20
#define STRING_POS_X 20
#define STRING_POS_Y 20
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType, MIL_ID HookId, void* HookDataPtr)
{
HookDataStruct* UserHookDataPtr = (HookDataStruct*)HookDataPtr;
MIL_ID ModifiedBufferId;
MIL_TEXT_CHAR Text[STRING_LENGTH_MAX] = { MIL_TEXT('\0'), };
MIL_TEXT_CHAR junkoutput[STRING_LENGTH_MAX] = { MIL_TEXT('\0'), };
/* Retrieve the MIL_ID of the grabbed buffer. */
MdigGetHookInfo(HookId, M_MODIFIED_BUFFER + M_BUFFER_ID, &ModifiedBufferId);
/* Increment the frame counter. */
UserHookDataPtr->ProcessedImageCount++;
/* Print and draw the frame count (remove to reduce CPU usage). */
MosPrintf(MIL_TEXT("Acquiring frame #%d.\r"), (int)UserHookDataPtr->ProcessedImageCount);
MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("%d"),
(int)UserHookDataPtr->ProcessedImageCount);
/* Execute the processing and update the display. */
MbufCopy(ModifiedBufferId, UserHookDataPtr->MilImageDisp); // Remove comment to see the image acquisition. Will slow down the frame rate/ acquisition time
/* Create file name base on the index of the frame that is being processed */
MosSprintf(Text, STRING_LENGTH_MAX, MIL_TEXT("Image%03li.png"), UserHookDataPtr->ProcessedImageCount); // 0-adds zeroes to the naming, 3- three places, l-long integer, i-signed decimal integer
/* Save image to disk */
MbufSave(Text, UserHookDataPtr->MilImageDisp);
return 0;
}
Thanks for all the help I can get!

Why doesn't my serial terminal on stm32cube ide not show anything?

I enabled UART and even used a different serial terminal such as Tera Term and PuTTY. The baud rate is set at 9600 for the st link itself and the serial terminal. I tried changing the baud rate but hasn't been working. I can't even get it to print anything. How do I get my serial terminal to work? Any help is much appreciated.
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f3xx_hal.h"
#include "stm32f3xx_hal_adc.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
UART_HandleTypeDef huart2;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_USART2_UART_Init(void);
int main(void)
{
/* USER CODE BEGIN 1 */
uint16_t raw;
char msg[10];
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
//Reset and clock control - Advanced high-performance bus - Enabling GPIO Port C pin 6 and Port B pin 1
//RCC -> AHBENR |= RCC_AHBENR_GPIOCEN;
RCC -> AHBENR |= RCC_AHBENR_GPIOAEN;
//Setup Control Registers for the LED output
//Mode register as Output
GPIOA -> MODER |= GPIO_MODER_MODER5_0| GPIO_MODER_MODER1_0 | GPIO_MODER_MODER0_0;
GPIOA -> MODER &= ~(GPIO_MODER_MODER5_1)|~(GPIO_MODER_MODER1_1)|~(GPIO_MODER_MODER0_1);
//OtypeR - Push pull
GPIOA -> OTYPER &= ~(GPIO_OTYPER_OT_5)|~(GPIO_OTYPER_OT_1)|~(GPIO_OTYPER_OT_1);
//OspeedR - High
GPIOA -> OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR5)|(GPIO_OSPEEDER_OSPEEDR1)|(GPIO_OSPEEDER_OSPEEDR0);
//PUPDR
GPIOA -> PUPDR &= ~(GPIO_PUPDR_PUPDR5)|~(GPIO_PUPDR_PUPDR1)|~(GPIO_PUPDR_PUPDR0);
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
printf("Starting...");
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
//Get ADC Value
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
raw = HAL_ADC_GetValue(&hadc1);
//Test: Set GPIO Pin Low
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
//Convert to string and print
sprintf(msg, "%hu\r\n", raw);
HAL_UART_Transmit(&huart2, (uint8_t*)msg, strlen(msg), HAL_MAX_DELAY);
//Pretend we have something else to do for a while
HAL_Delay(1);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_ADC12;
PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
PeriphClkInit.Adc12ClockSelection = RCC_ADC12PLLCLK_DIV1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief ADC1 Initialization Function
* #param None
* #retval None
*/
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
/**
* #brief USART2 Initialization Function
* #param None
* #retval None
*/
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 38400;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);
/*Configure GPIO pin : PA10 */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* #brief Period elapsed callback in non blocking mode
* #note This function is called when TIM6 interrupt took place, inside
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
* a global variable "uwTick" used as application time base.
* #param htim : TIM handle
* #retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
/* USER CODE END Callback 0 */
if (htim->Instance == TIM6) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
/* USER CODE END Callback 1 */
}
/**
* #brief This function is executed in case of error occurrence.
* #retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Whats the difference between "id" and "stream_id" in the structure returned with the option "PERF_RECORD_SAMPLE" by the "perf_event_open" syscall?

I am trying to write a piece of code using the perf_event_open syscall. But I don't understand the real difference between id and stream_id fields in the structure returned in my memory map.
This structure is like this one (from the man page of perf_event_open) :
struct {
struct perf_event_header header;
u64 sample_id; /* if PERF_SAMPLE_IDENTIFIER */
u64 ip; /* if PERF_SAMPLE_IP */
u32 pid, tid; /* if PERF_SAMPLE_TID */
u64 time; /* if PERF_SAMPLE_TIME */
u64 addr; /* if PERF_SAMPLE_ADDR */
u64 id; /* if PERF_SAMPLE_ID */
u64 stream_id; /* if PERF_SAMPLE_STREAM_ID */
u32 cpu, res; /* if PERF_SAMPLE_CPU */
u64 period; /* if PERF_SAMPLE_PERIOD */
struct read_format v;
/* if PERF_SAMPLE_READ */
u64 nr; /* if PERF_SAMPLE_CALLCHAIN */
u64 ips[nr]; /* if PERF_SAMPLE_CALLCHAIN */
u32 size; /* if PERF_SAMPLE_RAW */
char data[size]; /* if PERF_SAMPLE_RAW */
u64 bnr; /* if PERF_SAMPLE_BRANCH_STACK */
struct perf_branch_entry lbr[bnr];
/* if PERF_SAMPLE_BRANCH_STACK */
u64 abi; /* if PERF_SAMPLE_REGS_USER */
u64 regs[weight(mask)];
/* if PERF_SAMPLE_REGS_USER */
u64 size; /* if PERF_SAMPLE_STACK_USER */
char data[size]; /* if PERF_SAMPLE_STACK_USER */
u64 dyn_size; /* if PERF_SAMPLE_STACK_USER &&
size != 0 */
u64 weight; /* if PERF_SAMPLE_WEIGHT */
u64 data_src; /* if PERF_SAMPLE_DATA_SRC */
u64 transaction; /* if PERF_SAMPLE_TRANSACTION */
u64 abi; /* if PERF_SAMPLE_REGS_INTR */
u64 regs[weight(mask)];
/* if PERF_SAMPLE_REGS_INTR */
};
The man page give me this explanation :
id If PERF_SAMPLE_ID is enabled, a 64-bit unique ID is included. If the event is a member of an event group, the group leader ID is returned. This ID is the same as the one returned by PERF_FORMAT_ID.
stream_id If PERF_SAMPLE_STREAM_ID is enabled, a 64-bit unique ID is included. Unlike PERF_SAMPLE_ID the actual ID is returned, not the group leader. This ID is the same as the one returned by PERF_FORMAT_ID.
But the problem is here: the documentation seems to be incoherent.
Have I missed something ?
Thanks for your attention.
The main reason for the presence of PERF_SAMPLE_STREAM_ID is to maintain event IDs of inherited counters. While the PERF_SAMPLE_ID will contain the event ID of the parent counters. (if there is any parent-child relationship).
Inherited counters are those counters which are allotted to child tasks, originating from the parent task which is being profiled (unless the flag --no-inherit is being passed to perf command).
This detail is described in this old commit.
Looking at the latest source code here,
if (sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER))
data->id = primary_event_id(event);
if (sample_type & PERF_SAMPLE_STREAM_ID)
data->stream_id = event->id;
....
/*
* If we inherit events we want to return the parent event id
* to userspace.
*/
static u64 primary_event_id(struct perf_event *event)
{
u64 id = event->id;
if (event->parent)
id = event->parent->id;
return id;
}
The above snippet of code clearly distinguishes between the two members of the structure. This is irrespective of whether the event is a group leader or not.
Also, it is important to note that, all the events in a group will also compute/use this primary_event_id function. This can be seen here. So, all the events in a group will contain the id of the group leader.

In C, can't change a struct attribute except using #define val

In Minix 3.1.2a I've a struct "struct proc" where the PCB of any process stored,
but I've a problem when adding new attribute "p_currenthash" in the code below to this struct. I can't change its value except using a constant defined by #define directive; otherwise, the system stops responding. For clarity here is the structure:
struct proc {
struct stackframe_s p_reg; /* process' registers saved in stack frame */
#if (CHIP == INTEL)
reg_t p_ldt_sel; /* selector in gdt with ldt base and limit */
struct segdesc_s p_ldt[2+NR_REMOTE_SEGS]; /* CS, DS and remote segments */
#endif
#if (CHIP == M68000)
/* M68000 specific registers and FPU details go here. */
#endif
proc_nr_t p_nr; /* number of this process (for fast access) */
struct priv *p_priv; /* system privileges structure */
short p_rts_flags; /* process is runnable only if zero */
short p_misc_flags; /* flags that do suspend the process */
char p_priority; /* current scheduling priority */
char p_max_priority; /* maximum scheduling priority */
char p_ticks_left; /* number of scheduling ticks left */
char p_quantum_size; /* quantum size in ticks */
struct mem_map p_memmap[NR_LOCAL_SEGS]; /* memory map (T, D, S) */
clock_t p_user_time; /* user time in ticks */
clock_t p_sys_time; /* sys time in ticks */
struct proc *p_nextready; /* pointer to next ready process */
struct proc *p_caller_q; /* head of list of procs wishing to send */
struct proc *p_q_link; /* link to next proc wishing to send */
message *p_messbuf; /* pointer to passed message buffer */
int p_getfrom_e; /* from whom does process want to receive? */
int p_sendto_e; /* to whom does process want to send? */
sigset_t p_pending; /* bit map for pending kernel signals */
char p_name[P_NAME_LEN]; /* name of the process, including \0 */
int p_endpoint; /* endpoint number, generation-aware */
#if DEBUG_SCHED_CHECK
int p_ready, p_found;
#endif
char p_currenthash; /* hash */
};
Now, suppose I want to set its value. Initially I use the constant defined below.
#define NONE -1
register struct proc *rp;
rp->p_currenthash=NONE;
That works fine, but this: rp->p_currenthash=0 ; will cause the program to stop responding.
Any suggestions will be appreciated
Here's the main initialization in main():
/* Start the ball rolling. */
struct boot_image *ip; /* boot image pointer */
register struct proc *rp; /* process pointer */
register struct priv *sp; /* privilege structure pointer */
register int i, s;
int hdrindex; /* index to array of a.out headers */
phys_clicks text_base;
vir_clicks text_clicks, data_clicks;
reg_t ktsb; /* kernel task stack base */
struct exec e_hdr; /* for a copy of an a.out header */
/* Initialize the interrupt controller. */
intr_init(1);
/* Clear the process table. Anounce each slot as empty and set up mappings
* for proc_addr() and proc_nr() macros. Do the same for the table with
* privilege structures for the system processes.
*/
for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
rp->p_rts_flags = SLOT_FREE; /* initialize free slot */
rp->p_nr = i; /* proc number from ptr */
rp->p_currenthash=NONE;
rp->p_endpoint = _ENDPOINT(0, rp->p_nr); /* generation no. 0 */
(pproc_addr + NR_TASKS)[i] = rp; /* proc ptr from number */
}
for (sp = BEG_PRIV_ADDR, i = 0; sp < END_PRIV_ADDR; ++sp, ++i) {
sp->s_proc_nr = NONE; /* initialize as free */
sp->s_id = i; /* priv structure index */
ppriv_addr[i] = sp; /* priv ptr from number */
}
/* Set up proc table entries for processes in boot image. The stacks of the
* kernel tasks are initialized to an array in data space. The stacks
* of the servers have been added to the data segment by the monitor, so
* the stack pointer is set to the end of the data segment. All the
* processes are in low memory on the 8086. On the 386 only the kernel
* is in low memory, the rest is loaded in extended memory.
*/
/* Task stacks. */
ktsb = (reg_t) t_stack;
for (i=0; i < NR_BOOT_PROCS; ++i) {
ip = &image[i]; /* process' attributes */
rp = proc_addr(ip->proc_nr); /* get process pointer */
ip->endpoint = rp->p_endpoint; /* ipc endpoint */
rp->p_max_priority = ip->priority; /* max scheduling priority */
rp->p_priority = ip->priority; /* current priority */
rp->p_quantum_size = ip->quantum; /* quantum size in ticks */
rp->p_ticks_left = ip->quantum; /* current credit */
strncpy(rp->p_name, ip->proc_name, P_NAME_LEN); /* set process name */
(void) get_priv(rp, (ip->flags & SYS_PROC)); /* assign structure */
priv(rp)->s_flags = ip->flags; /* process flags */
priv(rp)->s_trap_mask = ip->trap_mask; /* allowed traps */
priv(rp)->s_call_mask = ip->call_mask; /* kernel call mask */
priv(rp)->s_ipc_to.chunk[0] = ip->ipc_to; /* restrict targets */
if (iskerneln(proc_nr(rp))) { /* part of the kernel? */
if (ip->stksize > 0) { /* HARDWARE stack size is 0 */
rp->p_priv->s_stack_guard = (reg_t *) ktsb;
*rp->p_priv->s_stack_guard = STACK_GUARD;
}
ktsb += ip->stksize; /* point to high end of stack */
rp->p_reg.sp = ktsb; /* this task's initial stack ptr */
text_base = kinfo.code_base >> CLICK_SHIFT;
/* processes that are in the kernel */
hdrindex = 0; /* all use the first a.out header */
} else {
hdrindex = 1 + i-NR_TASKS; /* servers, drivers, INIT */
}
/* The bootstrap loader created an array of the a.out headers at
* absolute address 'aout'. Get one element to e_hdr.
*/
phys_copy(aout + hdrindex * A_MINHDR, vir2phys(&e_hdr),
(phys_bytes) A_MINHDR);
/* Convert addresses to clicks and build process memory map */
text_base = e_hdr.a_syms >> CLICK_SHIFT;
text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT;
if (!(e_hdr.a_flags & A_SEP)) text_clicks = 0; /* common I&D */
data_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT;
rp->p_memmap[T].mem_phys = text_base;
rp->p_memmap[T].mem_len = text_clicks;
rp->p_memmap[D].mem_phys = text_base + text_clicks;
rp->p_memmap[D].mem_len = data_clicks;
rp->p_memmap[S].mem_phys = text_base + text_clicks + data_clicks;
rp->p_memmap[S].mem_vir = data_clicks; /* empty - stack is in data */
/* Set initial register values. The processor status word for tasks
* is different from that of other processes because tasks can
* access I/O; this is not allowed to less-privileged processes
*/
rp->p_reg.pc = (reg_t) ip->initial_pc;
rp->p_reg.psw = (iskernelp(rp)) ? INIT_TASK_PSW : INIT_PSW;
/* Initialize the server stack pointer. Take it down one word
* to give crtso.s something to use as "argc".
*/
if (isusern(proc_nr(rp))) { /* user-space process? */
rp->p_reg.sp = (rp->p_memmap[S].mem_vir +
rp->p_memmap[S].mem_len) << CLICK_SHIFT;
rp->p_reg.sp -= sizeof(reg_t);
}
/* Set ready. The HARDWARE task is never ready. */
if (rp->p_nr != HARDWARE) {
rp->p_rts_flags = 0; /* runnable if no flags */
lock_enqueue(rp); /* add to scheduling queues */
} else {
rp->p_rts_flags = NO_MAP; /* prevent from running */
}
/* Code and data segments must be allocated in protected mode. */
alloc_segments(rp);
}
register struct proc *rp;
rp->p_currenthash=NONE;
rp is an uninitialized pointer; it isn't pointing to a valid struct proc object, and so dereferencing it leads to undefined behavior. The fact that this didn't crash when assigning -1 was pure luck. (bad luck, because it misled you to believe you were doing something meaningful)
acutually the problem not solved ,first the "p_currenthash" initialized in the main as shown above ,later in a function called pic_proc ,i've this code :
register struct proc **xpp; /* iterate over queue */
register struct proc *rp; /* process to run */
int q;
for (q=0; q < NR_SCHED_QUEUES; q++)
{
if ( (rp = rdy_head[q]) != NIL_PROC)
{
for (xpp = &rdy_head[q]; *xpp != NIL_PROC; xpp = &(*xpp)->p_nextready)
{
if ((*xpp)->p_currenthash==NONE)
{
pick_val++;
}
}
}
}
that code works fine ,no inside the if if i changed the attribute "p_currenthash" the problem ocuured as bellow:
register struct proc **xpp; /* iterate over queue */
register struct proc *rp; /* process to run */
int q;
for (q=0; q < NR_SCHED_QUEUES; q++)
{
if ( (rp = rdy_head[q]) != NIL_PROC)
{
for (xpp = &rdy_head[q]; *xpp != NIL_PROC; xpp = &(*xpp)->p_nextready)
{
if ((*xpp)->p_currenthash==NONE)
{
pick_val++;
(*xpp)->p_currenthash=1;
}
}
}
}
i really can't realize the problem.